Mam zestaw .NET (dll), który jest interfejsem API do tworzenia kopii zapasowych oprogramowania, którego tutaj używamy. Zawiera niektóre właściwości i metody, z których chciałbym skorzystać w moich skryptach Powershell. Mam jednak wiele problemów z pierwszym załadowaniem zestawu, a następnie użyciem dowolnego z typów po załadowaniu zestawu.
Pełna ścieżka do pliku to:
C:\rnd\CloudBerry.Backup.API.dll
W PowerShell używam:
$dllpath = "C:\rnd\CloudBerry.Backup.API.dll"
Add-Type -Path $dllpath
Otrzymuję błąd poniżej:
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.
Używanie tego samego polecenia cmdlet w innym zestawie .NET, DotNetZip , który ma przykłady użycia tej samej funkcjonalności na stronie, również dla mnie nie działa.
W końcu okazało się, że pozornie jestem w stanie załadować zestaw za pomocą odbicia:
[System.Reflection.Assembly]::LoadFrom($dllpath)
Chociaż nie rozumiem różnicy między metodami Load, LoadFrom lub LoadFile, ta ostatnia metoda wydaje się działać.
Jednak nadal nie mogę tworzyć instancji ani używać obiektów. Za każdym razem, gdy próbuję, pojawiają się błędy opisujące, że Powershell nie może znaleźć żadnego z typów publicznych.
Wiem, że są tam zajęcia:
$asm = [System.Reflection.Assembly]::LoadFrom($dllpath)
$cbbtypes = $asm.GetExportedTypes()
$cbbtypes | Get-Member -Static
---- początek fragmentu ----
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)
---- koniec fragmentu ----
Próba użycia metod statycznych kończy się niepowodzeniem, nie wiem dlaczego !!!
[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
Wszelkie wskazówki są mile widziane !!
źródło
Znalazłem ten link: http://www.madwithpowershell.com/2013/10/add-type-vs-reflectionassembly-in.html
Mówi: „.LoadWithPartialName” jest przestarzałe. Dlatego zamiast kontynuować wdrażanie metody Add-Type za pomocą tej metody, używa ona statycznej wewnętrznej tabeli do przetłumaczenia „częściowej nazwy” na „pełną nazwę”. W przykładzie podanym w pytaniu
CloudBerry.Backup.API.dll
nie ma wpisu w wewnętrznej tabeli PowerShell, dlatego[System.Reflection.Assembly]::LoadFrom($dllpath)
działa. Nie używa tabeli do wyszukiwania częściowej nazwy.źródło
Niektóre z powyższych metod albo nie działały dla mnie, albo były niejasne.
Oto, czego używam do zawijania wywołań -AddPath i przechwytywania wyjątków LoaderException:
Odwołanie
https://social.technet.microsoft.com/Forums/sharepoint/en-US/dff8487f-69af-4b64-ab83-13d58a55c523/addtype-inheritance-loaderexceptions
źródło
Użyłem następującej konfiguracji, aby załadować niestandardową kontrolę csharp w PowerShell. Pozwala na dostosowanie i wykorzystanie kontroli z poziomu PowerShell.
tutaj jest link do bloga
http://justcode.ca/wp/?p=435
a tutaj jest link do kodu projektu ze źródłem
http://www.codeproject.com/Articles/311705/Custom-CSharp-Control-for-Powershell
źródło
LoaderExceptions
Są ukryte wewnątrz rekordu błędu. Jeśli błąd typu dodawania był ostatnim na liście błędów, użyj przycisku,$Error[0].InnerException.LoaderExceptions
aby wyświetlić błędy. Najprawdopodobniej twoja biblioteka jest zależna od innej, która nie została załadowana. Możesz alboAdd-Type
każdy z nich, albo po prostu stworzyć listę i użyć-ReferencedAssemblies
argumentu doAdd-Type
.źródło
Myślę, że do tej pory MUSISZ znaleźć odpowiedź na to zjawisko. Natknąłem się na ten post po napotkaniu tego samego problemu ... Mogłem załadować zestaw i wyświetlić typy zawarte w zestawie, ale nie byłem w stanie zaimplementować jego wystąpienia z klasy statycznej. Czy to było EFTIDY. Tidy, EFTidyNet.TidyNet.Options czy co? Ooooo Weeee ... Problemy ... problemy ... to może być cokolwiek. A przeglądanie statycznych metod i typów bibliotek DLL nie ujawnił niczego obiecującego. Teraz miałam depresję. Miałem go do pracy w skompilowanym programie C #, ale dla własnego użytku chciałem, aby działał w interpolowanym języku ... PowerShell.
Moje rozwiązanie znalazłem i wciąż jest sprawdzane, ale jestem podekscytowany i chciałem się tym podzielić. Zbuduj małą aplikację console.exe, wykonując func, który mnie interesował, a następnie wyświetl go w coś, co go zdekompiluje lub pokaże kod IL. Użyłem reflektora Red-Gate i dodatku do generatora języka PowerShell oraz Wallah! pokazał, jaki był prawidłowy ciąg konstruktora! :-) Spróbuj. i mam nadzieję, że zadziała dla każdego, kto ma do czynienia z tym problemem.
źródło