如何解决为什么模块清单在二进制模块中以这种方式工作 项目设置
为长篇文章道歉,但我想制作一个 MRE,这不是最短的事情。首先我的两个问题:
项目设置
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 举报,一经查实,本站将立刻删除。