【问题标题】:Powershell module abort loading on unsupported hostsPowershell 模块在不受支持的主机上中止加载
【发布时间】:2014-12-04 18:56:55
【问题描述】:

词汇表:

  • 主机:PowershellHost 会话
  • 互动:[Environment]::UserInteractive -eq $True

场景:

创建一个 powershell 模块,它只会在失败的情况下正确中止并且不会出错。在这种情况下,某些命令/模块只能在 ISE 和控制台等完全交互式主机中正常工作,而在 NuGet 包管理器控制台等假交互式主机中则无法正常工作

失败的解决方案:

# Add value to Powershell manifest(psd1) 
# Issue: Only supports a string for the `PowerShellHostName` property. How to specify both `ConsoleHost` and `Windows PowerShell ISE Host`? Unknown if this property supports regex, and even if it does, will the behavior change since it's not documented?
@{
    ....
    # Name of the Windows PowerShell host required by this module
    # PowerShellHostName = ''
    ....
}

失败的解决方案:

# Check for interactive shell
# Issue: UserInteractive is still set in embedded shells like NuGet package manager
# console. Commands that expect user input directly often hang.
if([Environment]::UserInteractive) {
    # Do stuff, dotsource, etc
}

失败的解决方案:

# Issue: returning still leaves module loaded, and it appears in Get-Module list
# Even if value is supplied for return, powershell's return statement is 'special'
# and the value is ignored
if($Host.Name -inotmatch '(ConsoleHost|Windows PowerShell ISE Host)') {
    Write-Warning "Host [$($Host.Name)] not supported, aborting"
    return 
}

失败的解决方案:

# Issue: Module isn't loaded, so it can't be unloaded
if( $Host.Name -inotmatch '(ConsoleHost|Windows PowerShell ISE Host)' ) {
    Remove-Module ThisModuleName
}

失败的解决方案:

# Issue: Powershell module error output is just passthrough, import-module 
# still reports success, even though $Error is has more stuff than before
if( $Host.Name -inotmatch '(ConsoleHost|Windows PowerShell ISE Host)' ) {
    Write-Error "Unsupported Host:" $Host.Name
}

烦人的解决方案:

# Issue: Leaves two errors on the stack, one for the throw, one for the module not 
# loading successfully
if($Host.Name -inotmatch '(ConsoleHost|Windows PowerShell ISE Host)') {
    throw "Host [$($Host.Name)] not supported, aborting"
}

不是解决方案:

Force user to wrap the import every time.

有问题的解决方案:

将模块拆分为嵌套子模块,一个用于“通用”,一个用于每个受支持的主机。为每个使用子文件夹,并为每个复制 psd1。看起来它最终将成为可维护性的噩梦,尤其是在嵌套依赖项方面。

UberModule
    /ModuleCommon
        /ModuleCommon.(psd1|psm1)
    /ConsoleHostSpecific
        /ConsoleHostSpecific.(psd1|psm1)
    /IseHostSpecific
        /IseHostSpecific.(psd1|psm1)
    /etc...

有没有更好的方法来做到这一点,或者超级模块拆分是唯一的方法?

【问题讨论】:

    标签: powershell powershell-module


    【解决方案1】:

    看看#requires 关键字,它可能会提供一些您尚未尝试过的选项。我不知道 NuGet 包管理器控制台是否有唯一的 ShellId。

    #Requires –ShellId Microsoft.PowerShell
    

    http://technet.microsoft.com/en-us/library/hh847765.aspx

    【讨论】:

      猜你喜欢
      • 2014-06-24
      • 1970-01-01
      • 2022-08-02
      • 1970-01-01
      • 1970-01-01
      • 2015-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多