Die meisten Menschen wissen inzwischen, dass dies System.Reflection.Assembly.LoadWithPartialName
veraltet ist, aber es stellt sich heraus, dass Add-Type -AssemblyName Microsoft.VisualBasic
es sich nicht viel besser verhält alsLoadWithPartialName
:
Anstatt zu versuchen, Ihre Anfrage im Kontext Ihres Systems zu analysieren, betrachtet [Add-Type] eine statische interne Tabelle, um den "Teilnamen" in einen "vollständigen Namen" zu übersetzen.
Wenn Ihr "Teilname" nicht in der Tabelle angezeigt wird, schlägt Ihr Skript fehl.
Wenn auf Ihrem Computer mehrere Versionen der Baugruppe installiert sind, können Sie keinen intelligenten Algorithmus auswählen. Sie werden das bekommen, was in ihrer Tabelle erscheint, wahrscheinlich das ältere, veraltete.
Wenn die von Ihnen installierten Versionen alle neuer als die veraltete in der Tabelle sind, schlägt Ihr Skript fehl.
Add-Type hat keinen intelligenten Parser von "Teilnamen" wie
.LoadWithPartialNames
.
Was Microsoft sagt, dass Sie eigentlich tun sollen, ist ungefähr so:
Add-Type -AssemblyName 'Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
Oder, wenn Sie den Weg kennen, so etwas:
Add-Type -Path 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.VisualBasic\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualBasic.dll'
Dieser lange Name für die Versammlung ist bekannt als starker Name bezeichnet , der sowohl für die Version als auch für die Assembly eindeutig ist und manchmal auch als vollständiger Name bezeichnet wird.
Dies lässt jedoch einige Fragen offen:
Wie bestimme ich den starken Namen dessen, was tatsächlich mit einem bestimmten Teilnamen auf mein System geladen wird?
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).Location;
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).FullName;
Diese sollten auch funktionieren:
Add-Type -AssemblyName $TypeName -PassThru | Select-Object -ExpandProperty Assembly | Select-Object -ExpandProperty FullName -Unique
Wenn ich möchte, dass mein Skript immer eine bestimmte Version einer DLL verwendet, ich aber nicht sicher bin, wo sie installiert ist, wie kann ich den starken Namen der DLL ermitteln?
[System.Reflection.AssemblyName]::GetAssemblyName($Path).FullName;
Oder:
Add-Type $Path -PassThru | Select-Object -ExpandProperty Assembly | Select-Object -ExpandProperty FullName -Unique
Wie bestimme ich den DLL-Pfad, wenn ich den starken Namen kenne?
[Reflection.Assembly]::Load('Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a').Location;
Und in ähnlicher Weise, wenn ich den Typnamen meiner Verwendung kenne, woher weiß ich, von welcher Baugruppe sie stammt?
[Reflection.Assembly]::GetAssembly([Type]).Location
[Reflection.Assembly]::GetAssembly([Type]).FullName
Wie sehe ich, welche Baugruppen verfügbar sind?
Ich schlage das GAC PowerShell-Modul vor . Get-GacAssembly -Name 'Microsoft.SqlServer.Smo*' | Select Name, Version, FullName
funktioniert ziemlich gut.
- Wie kann ich die verwendete Liste
Add-Type
anzeigen?
Das ist etwas komplexer. Ich kann beschreiben, wie für jede Version von PowerShell mit einem .Net-Reflektor darauf zugegriffen werden kann (siehe das Update unten für PowerShell Core 6.0).
Stellen Sie zunächst fest, aus welcher Bibliothek Sie Add-Type
stammen:
Get-Command -Name Add-Type | Select-Object -Property DLL
Öffnen Sie die resultierende DLL mit Ihrem Reflektor. Ich habe ILSpy dafür verwendet, weil es FLOSS ist, aber jeder C # -Reflektor sollte funktionieren. Öffnen Sie diese Bibliothek und schauen Sie hinein Microsoft.Powershell.Commands.Utility
. Unter Microsoft.Powershell.Commands
sollte es seinAddTypeCommand
.
In der Codeliste dafür gibt es eine private Klasse InitializeStrongNameDictionary()
. Das listet das Wörterbuch auf, das die Kurznamen den starken Namen zuordnet. Es gibt fast 750 Einträge in der Bibliothek, die ich mir angesehen habe.
Update: Jetzt, da PowerShell Core 6.0 Open Source ist. Für diese Version können Sie die obigen Schritte überspringen und den Code direkt online in ihrem GitHub-Repository anzeigen . Ich kann jedoch nicht garantieren, dass dieser Code mit einer anderen Version von PowerShell übereinstimmt.