用語集:
- ホスト: 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.
疑わしい解決策:
モジュールをネストされたサブモジュールに分割します。1 つは「Common」用、もう 1 つはサポートされている各ホスト用です。それぞれにサブフォルダーを使用し、それぞれに psd1 を複製します。特にネストされた依存関係に関しては、保守性の悪夢になるようです。
UberModule
/ModuleCommon
/ModuleCommon.(psd1|psm1)
/ConsoleHostSpecific
/ConsoleHostSpecific.(psd1|psm1)
/IseHostSpecific
/IseHostSpecific.(psd1|psm1)
/etc...
これを行うためのより良い方法はありますか、それとも uber-module 分割が唯一の方法ですか?