La plupart des gens savent maintenant que System.Reflection.Assembly.LoadWithPartialName
c'est obsolète, mais il s'avère que Add-Type -AssemblyName Microsoft.VisualBasic
cela ne se comporte pas beaucoup mieux queLoadWithPartialName
:
Plutôt que de tenter d'analyser votre requête dans le contexte de votre système, [Add-Type] examine une table interne statique pour traduire le «nom partiel» en «nom complet».
Si votre "nom partiel" n'apparaît pas dans leur tableau, votre script échouera.
Si plusieurs versions de l'assemblage sont installées sur votre ordinateur, il n'y a pas d'algorithme intelligent pour choisir entre elles. Vous obtiendrez celui qui apparaît dans leur tableau, probablement le plus ancien et obsolète.
Si les versions que vous avez installées sont toutes plus récentes que la version obsolète du tableau, votre script échouera.
Add-Type n'a pas d'analyseur intelligent de "noms partiels" comme
.LoadWithPartialNames
.
Qu'est - ce que Microsoft dit que vous êtes réellement censé faire quelque chose comme ceci:
Add-Type -AssemblyName 'Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
Ou, si vous connaissez le chemin, quelque chose comme ceci:
Add-Type -Path 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.VisualBasic\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualBasic.dll'
Ce nom long donné pour l'assembly est connu sous le nom de nom fort , qui est à la fois unique à la version et à l'assembly, et est également parfois appelé nom complet.
Mais cela laisse quelques questions sans réponse:
Comment déterminer le nom fort de ce qui est réellement chargé sur mon système avec un nom partiel donné?
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).Location;
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).FullName;
Ceux-ci devraient également fonctionner:
Add-Type -AssemblyName $TypeName -PassThru | Select-Object -ExpandProperty Assembly | Select-Object -ExpandProperty FullName -Unique
Si je veux que mon script utilise toujours une version spécifique d'un .dll mais que je ne peux pas être certain de l'endroit où il est installé, comment déterminer quel est le nom fort du .dll?
[System.Reflection.AssemblyName]::GetAssemblyName($Path).FullName;
Ou:
Add-Type $Path -PassThru | Select-Object -ExpandProperty Assembly | Select-Object -ExpandProperty FullName -Unique
Si je connais le nom fort, comment puis-je déterminer le chemin .dll?
[Reflection.Assembly]::Load('Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a').Location;
Et, dans le même ordre d'idées, si je connais le nom de type de ce que j'utilise, comment savoir de quel assemblage il provient?
[Reflection.Assembly]::GetAssembly([Type]).Location
[Reflection.Assembly]::GetAssembly([Type]).FullName
Comment voir quels assemblages sont disponibles?
Je suggère le module GAC PowerShell . Get-GacAssembly -Name 'Microsoft.SqlServer.Smo*' | Select Name, Version, FullName
fonctionne plutôt bien.
- Comment puis-je voir la liste qui
Add-Type
utilise?
C'est un peu plus complexe. Je peux décrire comment y accéder pour n'importe quelle version de PowerShell avec un réflecteur .Net (voir la mise à jour ci-dessous pour PowerShell Core 6.0).
Tout d'abord, déterminez de quelle bibliothèque Add-Type
provient:
Get-Command -Name Add-Type | Select-Object -Property DLL
Ouvrez la DLL résultante avec votre réflecteur. J'ai utilisé ILSpy pour cela parce que c'est FLOSS, mais n'importe quel réflecteur C # devrait fonctionner. Ouvrez cette bibliothèque et regardez dedans Microsoft.Powershell.Commands.Utility
. En dessous Microsoft.Powershell.Commands
, il devrait y en avoir AddTypeCommand
.
Dans le code inscripteur pour cela, il y a une classe privée, InitializeStrongNameDictionary()
. Cela répertorie le dictionnaire qui mappe les noms courts aux noms forts. J'ai regardé près de 750 entrées dans la bibliothèque.
Mise à jour: maintenant que PowerShell Core 6.0 est open source. Pour cette version, vous pouvez ignorer les étapes ci-dessus et voir le code directement en ligne dans leur référentiel GitHub . Cependant, je ne peux pas garantir que ce code correspond à une autre version de PowerShell.