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

为什么我的PowerShell模块不能正确导出成员,为什么不能导出嵌套模块?

如何解决为什么我的PowerShell模块不能正确导出成员,为什么不能导出嵌套模块?

我正在使用“快速模块CLI”构建器。想法是您有我的模块,其中包含Add-QuickFunction,Add-QuickAlias,New-QuickModule,Remove-QuickCommand等命令。

构建功能时,模块将继续构建。计划是创建一个Export-QuickModule和Export-QuickModule命令,以便在准备导出模块时可以将其发布到组织,公共画廊。

所以这个问题有两个方面。

  1. 导出的成员与模块中的命令不匹配
PS C:\WINDOWS\system32> Get-Module -Name QuickModuleCLI

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Script     0.1.3      QuickModuleCLI                      {New-QuickModule,Update-QuickModule}

注意它仅包含2个导出命令。这是在我将Export-ModuleMember手动添加到本地系统之后。没有Export-ModuleMember,只有New-QuickModule显示为已导出。

但是将其与命令的实际列表进行比较:

PS C:\WINDOWS\system32> Get-Command -Module QuickModuleCLI

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Add-QuickAlias                                     0.1.3      QuickModuleCLI
Function        Add-QuickFunction                                  0.1.3      QuickModuleCLI
Function        ConvertTo-PowershellEncodedString                  0.1.3      QuickModuleCLI
Function        Edit-QuickCommand                                  0.1.3      QuickModuleCLI
Function        New-QuickModule                                    0.1.3      QuickModuleCLI
Function        Remove-QuickCommand                                0.1.3      QuickModuleCLI
Function        Rename-QuickCommand                                0.1.3      QuickModuleCLI
Function        Reset-QuickCommand                                 0.1.3      QuickModuleCLI
Function        Set-Env                                            0.1.3      QuickModuleCLI
Function        Update-QuickModule                                 0.1.3      QuickModuleCLI
  1. 在导入模块之前,嵌套模块不会导入到PowerShell会话中。我可以通过在我的$ Profile中添加Import-Module来处理它,但我只是想确保自己没有做错任何事情。

这是什么意思,在打开新会话后,我看到以下内容

PS C:\WINDOWS\system32> Write-Test
Write-Test : The term 'Write-Test' 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.
At line:1 char:1
+ Write-Test
+ ~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Write-Test:String) [],CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

PS C:\WINDOWS\system32> Import-Module QuickModuleCLI
PS C:\WINDOWS\system32> Write-Test
Hello

我使用动态的自滚动PowerShell生成器来更新psd1文件添加到FunctionsToExport中。您可以验证当我导入模块时,它调用nestedModules并正确导入了它。但是,在我用来开发此模块的计算机上,不需要导入模块就可以使Write-Test出现在我的PowerShell选项中。这是我必须“应对”的环境问题还是可以解决的问题?

代码可在此处找到:https://github.com/EdLichtman/QuickModuleCLI 您可以使用Import-Module QuickModuleCLI自己尝试一下

解决方法

第1部分-ExportedCommands

对于您的问题,ExportedCommands列表与Get-Command的结果不匹配,这里的修复很少。我通过逐步从https://github.com/EdLichtman/QuickModuleCLI的仓库中删除代码块,直到没有可删除的东西,将其精简为这一点:

MyModule.psd1

@{

RootModule = "MyModule.psm1"

ModuleVersion = "0.1.4"

FunctionsToExport = @(
    "Add-MyAlias","New-MyModule"
)

}

MyModule.psm1

function global:Add-MyAlias {
    write-host "global:Add-MyAlias"
}

function New-MyModule {
    write-host "New-MyModule"
}

交互式

PS> Import-Module .\MyModule\MyModule.psd1 -Force

PS> Get-Module MyModule

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Script     0.1.4      MyModule                            New-MyModule

PS> Get-Command -Module MyModule

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Add-MyAlias                                        0.1.4      MyModule
Function        New-MyModule                                       0.1.4      MyModule

我不知道在导出的函数上使用global:时的确切含义是什么(我假设该函数被导入到global范围而不是模块范围中),但是如果您删除global:,该功能将突然再次出现在ExportedCommands列表中:

第2部分-导入模块

PowerShell具有一项功能,可使它在一组预定义的文件夹位置中搜索未知命令。这称为“模块自动加载”,您可以根据About Preference Variables使用$PSModuleAutoLoadingPreference变量来启用或禁用该功能(提示:默认情况下已启用)。

它搜索的位置在环境变量PSModulePath中定义-请参见About PSModulePath

如果希望模块中的命令可被发现并在首次调用时自动加载,请在已经添加到PSModulePath环境变量的路径之一中安装模块,或将模块的位置添加到路径。

,

因此,要继续进行第2部分的介绍,就会发现与之相关的原因,实际上,它与该答案中描述的行为完全相同:

Invoking functions from nested modules in a script module do not always trigger a module to autoload

我的解决方法是将NestedModules中的函数添加到FunctionsToExport列表中。最初,我不认为我可以导出不直接属于父模块的功能。

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