ほとんどの人はこれSystem.Reflection.Assembly.LoadWithPartialName
が非推奨であることを今では知っAdd-Type -AssemblyName Microsoft.VisualBasic
ていますが、それよりも動作がよくないLoadWithPartialName
ことがわかります:
[Add-Type]は、システムのコンテキストで要求を解析しようとするのではなく、静的な内部テーブルを調べて、「部分的な名前」を「完全な名前」に変換します。
「部分的な名前」がテーブルに表示されない場合、スクリプトは失敗します。
コンピューターにインストールされているアセンブリの複数のバージョンがある場合、それらの間で選択するインテリジェントなアルゴリズムはありません。あなたは彼らのテーブルに現れるもののどれでも、おそらく古い、古いものを手に入れるでしょう。
インストールしたバージョンがすべて、表にある古いバージョンよりも新しい場合、スクリプトは失敗します。
Add-Typeには、次のような「部分名」のインテリジェントなパーサーがありません。
.LoadWithPartialNames
。
Microsoftが実際に行うべきだと言っているのは、次のようなものです。
Add-Type -AssemblyName 'Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
または、パスがわかっている場合は、次のようになります。
Add-Type -Path 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.VisualBasic\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualBasic.dll'
アセンブリに付けられた長い名前は、 な名前ますは、バージョンとアセンブリの両方に固有であり、フルネームとも呼ばれます。
しかし、これは未解決のいくつかの質問を残します:
与えられた部分的な名前でシステムに実際にロードされているものの厳密な名前を判断するにはどうすればよいですか?
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).Location;
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).FullName;
これらも機能するはずです:
Add-Type -AssemblyName $TypeName -PassThru | Select-Object -ExpandProperty Assembly | Select-Object -ExpandProperty FullName -Unique
スクリプトで特定のバージョンの.dllを常に使用したいが、それがインストールされている場所がわからない場合は、.dllから厳密な名前を判別するにはどうすればよいですか?
[System.Reflection.AssemblyName]::GetAssemblyName($Path).FullName;
または:
Add-Type $Path -PassThru | Select-Object -ExpandProperty Assembly | Select-Object -ExpandProperty FullName -Unique
厳密な名前がわかっている場合、.dllパスを確認するにはどうすればよいですか?
[Reflection.Assembly]::Load('Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a').Location;
同様に、使用しているもののタイプ名がわかっている場合、それがどのアセンブリからのものであるかをどのようにして知ることができますか?
[Reflection.Assembly]::GetAssembly([Type]).Location
[Reflection.Assembly]::GetAssembly([Type]).FullName
使用可能なアセンブリを確認するにはどうすればよいですか?
GAC PowerShellモジュールをお勧めします。 Get-GacAssembly -Name 'Microsoft.SqlServer.Smo*' | Select Name, Version, FullName
かなりうまくいきます。
- を
Add-Type
使用するリストをどのように表示できますか?
これはもう少し複雑です。.Netリフレクターを備えたPowerShellの任意のバージョンでそれにアクセスする方法を説明できます(PowerShell Core 6.0の下記の更新を参照)。
まず、どのライブラリAdd-Type
からのものかを調べます。
Get-Command -Name Add-Type | Select-Object -Property DLL
結果のDLLをリフレクターで開きます。ILSpyはFLOSS なのでこれに使用しましたが、C#リフレクターはすべて機能するはずです。そのライブラリを開き、を調べますMicrosoft.Powershell.Commands.Utility
。下Microsoft.Powershell.Commands
にあるはずですAddTypeCommand
。
そのコードリストには、プライベートクラスがありInitializeStrongNameDictionary()
ます。これは、短い名前を厳密な名前にマップする辞書をリストします。私が見たライブラリには、ほぼ750のエントリがあります。
更新: PowerShell Core 6.0がオープンソースになりました。そのバージョンの場合、上記の手順をスキップして、GitHubリポジトリでオンラインで直接コードを確認できます。ただし、そのコードがPowerShellの他のバージョンと一致することは保証できません。