微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么模块清单在二进制模块中以这种方式工作 项目设置

如何解决为什么模块清单在二进制模块中以这种方式工作 项目设置

为长篇文章道歉,但我想制作一个 MRE,这不是最短的事情。首先我的两个问题:

  1. 如果 psm1 文件是清单中的 RootModule,则二进制 cmdlet 不会导出。这是一个错误吗?也许我做错了什么。

  2. 当所有 cmdlet 都导出时,我看到 psm1 文件函数的重复导入。为什么是这样?要遵循的证据。

项目设置

mkdir sample
cd sample
mkdir src
dotnet new classlib -o src\PSSample -n src\PSSample
cd src\PSSample
dotnet add package PowerShellStandard.Library --version 5.1.0
dotnet restore

所有文件

|- PSSample
    |- lib
        |- Newtonsoft.Json.dll
|- src
    |- PSSample
        |- PSSample.csproj
        |- SetFunction.cs
    |-Public
        |- Get-Function.ps1
        |- New-Function.ps1
    |- PSSample.psd1
    |- PSSample.psm1
|- build.ps1

函数内容在这里无关紧要,只要它们包含要导出的最小可行代码,所以我不会添加它们,但如果您想快速重现,这里是我的最小二进制cmdlet。

SetFunction.cs

using System.Management.Automation;

namespace PSSample
{
    [Cmdlet(VerbsCommon.Set,"Function")]
    public class SetFunction : PSCmdlet
    {
        [Parameter(Position = 0,Mandatory = true)]
        public object InputObject { get; set; }

        protected override void ProcessRecord()
        {
            WriteObject(InputObject);
        }
    }
}

build.ps1

# Pertinent part of script
$ModuleName = "PSSample"
[void](& dotnet publish .\src\PSSample\PSSample.csproj --configuration Release --output .\$ModuleName\lib)
copy-Item -Path .\src\$ModuleName.* -Destination .\$ModuleName -Force
copy-Item -Path .\src\Public -Destination .\$ModuleName\Public -Container -Recurse
$PublicFunctions = (Get-ChildItem -Path .\src\Public -Recurse -File).BaseName
$ManifestParams = @{
    Path                 = ".\PSSample\$ModuleName.psd1"
    FunctionsToExport    = $PublicFunctions
    CmdletsToExport      = "Set-Function"
    # I have a genuine import for another assembly,I am just using Newtonsoft as an example.
    requiredAssemblies   = @(".\lib\Newtonsoft.Json.dll")
    nestedModules        = @(".\lib\PSSample.dll",".\PSSample.psm1")
    CompatiblePSEditions = "Desktop","Core"
}
Update-ModuleManifest @ManifestParams

PSSample.psm1

$Public = Get-ChildItem (Join-Path $PSScriptRoot Public) -Recurse -Filter *.ps1 -ErrorAction SilentlyContinue
# I hope it is not relevant here,but this approach is used instead of
# dot sourcing individually,because of the number of functions in the real module.
$Functions = $Public.Foreach({
    [System.IO.File]::ReadAllText($_.FullName,[System.Text.Encoding]::UTF8) + [System.Environment]::NewLine
})
. ([System.Management.Automation.ScriptBlock]::Create($Functions))
Export-ModuleMember -Function $Public.BaseName

PSSample.psd1

在这里复制了一个相当空白的清单,其中包含模块的 GUID,并且构建脚本更新了其他信息,如上所述。以下是已完成清单的一些设置。

requiredAssemblies = '.\lib\Newtonsoft.Json.dll'
FunctionsToExport = 'Get-Function','New-Function'
CmdletsToExport = 'Set-Function'

如前面问题 1 中所述,如果我将 RootModule 设置为 PSSample.psm1,则不会加载二进制 cmdlet,尽管路径正确。

模块导入

VERBOSE: Loading module from path 'C:\powershell\sample\PSSample\PSSample.psd1'.
VERBOSE: Loading 'Assembly' from path 'C:\powershell\sample\PSSample\lib\Newtonsoft.Json.dll'.
VERBOSE: Loading 'Assembly' from path 'C:\powershell\sample\PSSample\lib\Newtonsoft.Json.dll'.
VERBOSE: Loading module from path 'C:\powershell\sample\PSSample\lib\PSSample.dll'.
VERBOSE: Importing cmdlet 'Set-Function'.
VERBOSE: Loading module from path 'C:\powershell\sample\PSSample\PSSample.psm1'.
VERBOSE: Importing function 'Get-Function'.
VERBOSE: Importing function 'New-Function'.
PS powershell\sample>
PS powershell\sample> Get-Command -Module PSSample

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Get-Function                                       0.0.0      PSSample
Function        New-Function                                       0.0.0      PSSample

所以我可以看到模块的导入,但是 cmdlet 没有出现在可用命令列表中。嵌套模块在那里并包含导出的命令,但它在 PowerShell 中不可用。

PS powershell\sample> (Get-Module -Name PSSample).nestedModules

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Binary     1.0.0.0    PSSample                            Set-Function


PS powershell\sample> Set-Function
Set-Function : The term 'Set-Function' is not recognized as the name of a cmdlet,function,script file,or operable program. Check the spelling of the name,or if a path was included,verify that the path is correct and try again.

只要 PSSample.psm1 不是 RootModule,如问题 2所述,所有函数和 cmdlet 的导入都可以在任何其他组合中工作>.

  • 两个文件都是嵌套模块,顺序不限。
  • 二进制模块作为 RootModule

但是,在这种情况下,您会看到所有函数的多次导入的详细输出。我不认为这会影响任何事情,但与 PSSample.psm1 文件RootModule

时的行为相比,这似乎很奇怪

模块导入

VERBOSE: Loading module from path 'C:\powershell\sample\PSSample\PSSample.psd1'.
VERBOSE: Loading 'Assembly' from path 'C:\powershell\sample\PSSample\lib\Newtonsoft.Json.dll'.
VERBOSE: Loading 'Assembly' from path 'C:\powershell\sample\PSSample\lib\Newtonsoft.Json.dll'.
VERBOSE: Loading module from path 'C:\powershell\sample\PSSample\.\lib\PSSample.dll'.
VERBOSE: Importing cmdlet 'Set-Function'.
VERBOSE: Loading module from path 'C:\powershell\sample\PSSample\.\PSSample.psm1'.
VERBOSE: Importing function 'Get-Function'.
VERBOSE: Importing function 'New-Function'.
VERBOSE: Exporting function 'Get-Function'.
VERBOSE: Exporting function 'New-Function'.
VERBOSE: Exporting cmdlet 'Set-Function'.
VERBOSE: Importing cmdlet 'Set-Function'.
VERBOSE: Importing function 'Get-Function'.
VERBOSE: Importing function 'New-Function'.

PS > Get-Command -Module PSSample

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Get-Function                                       0.0.0      PSSample
Function        New-Function                                       0.0.0      PSSample
Cmdlet          Set-Function                                       0.0.0      PSSample

所以,如您所见,我知道如何同时导入函数和 cmdlet,但是在处理某些人称为混合模块内容时,这是正确的方法吗?哎呀,第三个问题... Kevin Marquette offers this advice in his blog about the Standard Library Binary Module,然而,他似乎使用了一个空的 psm1 文件,这可能是二进制模块加载正常的原因。

预先感谢您深思熟虑的想法。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?