J'ai un assemblage .NET (une dll) qui est une API pour sauvegarder le logiciel que nous utilisons ici. Il contient certaines propriétés et méthodes dont j'aimerais tirer parti dans mes scripts Powershell. Cependant, je rencontre beaucoup de problèmes avec le premier chargement de l'assemblage, puis l'utilisation de l'un des types une fois l'assemblage chargé.
Le chemin d'accès complet au fichier est:
C:\rnd\CloudBerry.Backup.API.dll
Dans Powershell, j'utilise:
$dllpath = "C:\rnd\CloudBerry.Backup.API.dll"
Add-Type -Path $dllpath
J'obtiens l'erreur ci-dessous:
Add-Type : Unable to load one or more of the requested types. Retrieve the
LoaderExceptions property for more information.
At line:1 char:9
+ Add-Type <<<< -Path $dllpath
+ CategoryInfo : NotSpecified: (:) [Add-Type], ReflectionTypeLoadException
+ FullyQualifiedErrorId : System.Reflection.ReflectionTypeLoadException,Microsoft.PowerShell.Commands.AddTypeComma
ndAdd-Type : Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
L'utilisation de la même applet de commande sur un autre assembly .NET, DotNetZip , qui contient des exemples d'utilisation des mêmes fonctionnalités sur le site, ne fonctionne pas non plus pour moi.
Je trouve finalement que je suis apparemment capable de charger l'assemblage en utilisant la réflexion:
[System.Reflection.Assembly]::LoadFrom($dllpath)
Bien que je ne comprenne pas la différence entre les méthodes Load, LoadFrom ou LoadFile, cette dernière méthode semble fonctionner.
Cependant, il me semble toujours impossible de créer des instances ou d'utiliser des objets. Chaque fois que j'essaye, j'obtiens des erreurs qui décrivent que Powershell est incapable de trouver l'un des types publics.
Je sais que les cours sont là:
$asm = [System.Reflection.Assembly]::LoadFrom($dllpath)
$cbbtypes = $asm.GetExportedTypes()
$cbbtypes | Get-Member -Static
---- début de l'extrait ----
TypeName: CloudBerryLab.Backup.API.BackupProvider
Name MemberType Definition
---- ---------- ----------
PlanChanged Event System.EventHandler`1[CloudBerryLab.Backup.API.Utils.ChangedEventArgs] PlanChanged(Sy...
PlanRemoved Event System.EventHandler`1[CloudBerryLab.Backup.API.Utils.PlanRemoveEventArgs] PlanRemoved...
CalculateFolderSize Method static long CalculateFolderSize()
Equals Method static bool Equals(System.Object objA, System.Object objB)
GetAccounts Method static CloudBerryLab.Backup.API.Account[], CloudBerry.Backup.API, Version=1.0.0.1, Cu...
GetBackupPlans Method static CloudBerryLab.Backup.API.BackupPlan[], CloudBerry.Backup.API, Version=1.0.0.1,...
ReferenceEquals Method static bool ReferenceEquals(System.Object objA, System.Object objB)
SetProfilePath Method static System.Void SetProfilePath(string profilePath)
---- fin de l'extrait ----
Essayer d'utiliser des méthodes statiques échoue, je ne sais pas pourquoi !!!
[CloudBerryLab.Backup.API.BackupProvider]::GetAccounts()
Unable to find type [CloudBerryLab.Backup.API.BackupProvider]: make sure that the assembly containing this type is load
ed.
At line:1 char:42
+ [CloudBerryLab.Backup.API.BackupProvider] <<<< ::GetAccounts()
+ CategoryInfo : InvalidOperation: (CloudBerryLab.Backup.API.BackupProvider:String) [], RuntimeException
+ FullyQualifiedErrorId : TypeNotFound
Toute orientation appréciée !!
la source
J'ai trouvé ce lien: http://www.madwithpowershell.com/2013/10/add-type-vs-reflectionassembly-in.html
Il dit que ".LoadWithPartialName" est obsolète. Par conséquent, au lieu de continuer à implémenter Add-Type avec cette méthode, il utilise une table interne statique pour traduire le "nom partiel" en "nom complet". Dans l'exemple donné dans la question,
CloudBerry.Backup.API.dll
n'a pas d'entrée dans la table interne de PowerShell, c'est pourquoi cela[System.Reflection.Assembly]::LoadFrom($dllpath)
fonctionne. Il n'utilise pas la table pour rechercher un nom partiel.la source
Certaines des méthodes ci-dessus n'ont pas fonctionné pour moi ou n'étaient pas claires.
Voici ce que j'utilise pour encapsuler les appels -AddPath et intercepter les LoaderExceptions:
Référence
https://social.technet.microsoft.com/Forums/sharepoint/en-US/dff8487f-69af-4b64-ab83-13d58a55c523/addtype-inheritance-loaderexceptions
la source
J'ai utilisé la configuration suivante pour charger un contrôle csharp personnalisé dans PowerShell. Il permet au contrôle d'être personnalisé et utilisé à partir de PowerShell.
voici le lien du blog
http://justcode.ca/wp/?p=435
et voici le lien codeproject avec la source
http://www.codeproject.com/Articles/311705/Custom-CSharp-Control-for-Powershell
la source
Ils
LoaderExceptions
sont cachés dans l'enregistrement d'erreur. Si l'erreur de type ajout était la dernière de la liste d'erreurs, utilisez$Error[0].InnerException.LoaderExceptions
pour afficher les erreurs. Très probablement, votre bibliothèque dépend d'une autre qui n'a pas été chargée. Vous pouvez soitAdd-Type
chacun, soit créer une liste et utiliser l'-ReferencedAssemblies
argument pourAdd-Type
.la source
Je suppose que maintenant vous POURRIEZ avez trouvé une réponse à ce phénomène. J'ai couru sur ce message après avoir rencontré le même problème ... J'ai pu charger l'assembly et afficher les types contenus dans l'assembly, mais je n'ai pas pu instancier une instance de celui-ci à partir d'une classe statique. Était-ce EFTIDY. Tidy, EFTidyNet.TidyNet.Options ou quoi? Ooooo Weeee ... Des problèmes ... des problèmes ... ça pourrait être n'importe quoi. Et regarder à travers les méthodes statiques et les types de DLL n'a rien révélé de prometteur. Maintenant, je déprimais. Je l'avais fait fonctionner dans un programme C # compilé, mais pour mon usage, je voulais le faire fonctionner dans un langage interpété ... powershell.
J'ai trouvé ma solution, et elle est toujours en cours de preuve, mais je suis ravie et je voulais la partager. Construisez une petite application console.exe exerçant la fonction qui m'intéressait, puis visualisez-la dans quelque chose qui la décompilerait ou afficherait le code IL. J'ai utilisé le réflecteur de Red-Gate et le complément du générateur de langage PowerShell et Wallah! il a montré quelle était la chaîne de construction appropriée! :-) Essayez-le. et j'espère que cela fonctionne pour quiconque est confronté à ce problème.
la source