Як правильно додати .NET збірки до сесії Powershell?


24

У мене є .NET збірка (dll), яка є API для резервного копіювання програмного забезпечення, яке ми використовуємо тут. Він містить деякі властивості та методи, якими я хотів би скористатися в моїх сценаріях Powershell. Однак у мене виникає безліч проблем із початком завантаження збірки, а потім використання будь-якого типу після завантаження збірки.

Повний шлях до файлу:

C:\rnd\CloudBerry.Backup.API.dll

У Powershell я використовую:

$dllpath = "C:\rnd\CloudBerry.Backup.API.dll"
Add-Type -Path $dllpath

Я отримую помилку нижче:

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.

Використання того ж cmdlet на іншій збірці .NET, DotNetZip , який має приклади використання однакових функціональних можливостей на сайті, також не працює для мене.

Зрештою я виявляю, що я, здається, зможу завантажити збірку за допомогою відображення:

[System.Reflection.Assembly]::LoadFrom($dllpath)

Хоча я не розумію різниці між методами Load, LoadFrom або LoadFile, але останній метод, здається, працює.

Однак я все ще не можу створювати екземпляри або використовувати об’єкти. Кожен раз, коли я намагаюся, я отримую помилки, які описують, що Powershell не в змозі знайти жоден із загальнодоступних типів.

Я знаю, що заняття є:

$asm = [System.Reflection.Assembly]::LoadFrom($dllpath)
$cbbtypes = $asm.GetExportedTypes()
$cbbtypes | Get-Member -Static

---- початок витягу ----

   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)

---- кінець витягу ----

Спроба використовувати статичні методи не вдалася, я не знаю чому !!!

[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

Будь-яке керівництво оцінено !!

Відповіді:


15

Не могли б ви оточити Add-Typeспробу вловлювання та надрукувати властивість LoaderExceptions, як це робиться помилка. Він може надати виняток із більш детальним повідомленням про помилку.

try
{
    Add-Type -Path "C:\rnd\CloudBerry.Backup.API.dll"
}
catch
{
    $_.Exception.LoaderExceptions | %
    {
        Write-Error $_.Message
    }
}

9
Це не спрацювало для мене, але воно потрапило в бальний парк. Всередині улову тут знаходиться об’єкт LoaderExceptions: $ _. Exception.LoaderExceptions
Бретт

чи не існує способу використання відносного шляху?
Аміт

3

Я знайшов це посилання: http://www.madwithpowershell.com/2013/10/add-type-vs-reflectionassembly-in.html

За його словами, ".LoadWithPartialName" був застарілим. Тому, замість того, щоб продовжувати реалізовувати Add-Type за допомогою цього методу, він використовує статичну внутрішню таблицю для перекладу "часткового імені" в "повне ім'я". У прикладі, наведеному у питанні, CloudBerry.Backup.API.dllнемає запису у внутрішній таблиці PowerShell, через що [System.Reflection.Assembly]::LoadFrom($dllpath)працює. Це не за допомогою таблиці для пошуку часткової назви.


2

Деякі з вищевказаних методів для мене або не спрацювали, або були незрозумілими.

Ось що я використовую для завершення викликів -AddPath та лову LoaderExceptions:

try
{
   Add-Type -Path "C:\path\to.dll"
}
catch [System.Reflection.ReflectionTypeLoadException]
{
   Write-Host "Message: $($_.Exception.Message)"
   Write-Host "StackTrace: $($_.Exception.StackTrace)"
   Write-Host "LoaderExceptions: $($_.Exception.LoaderExceptions)"
}

Довідка
https://social.technet.microsoft.com/Forums/sharepoint/en-US/dff8487f-69af-4b64-ab83-13d58a55c523/addtype-inheritance-loaderexceptions


0

Я використовував наступні настройки для завантаження користувальницького керування csharp в powershell. Це дозволяє налаштувати управління та використовувати його зсередини.

ось посилання на блог

http://justcode.ca/wp/?p=435

і ось посилання кодупроекту з джерелом

http://www.codeproject.com/Articles/311705/Custom-CSharp-Control-for-Powershell


3
Ласкаво просимо до помилки сервера! Ми дійсно вважаємо за краще, щоб відповіді містили вміст, а не вказівки на зміст. Хоча це теоретично може відповісти на питання, бажано було б сюди включити істотні частини відповіді та надати посилання для довідки.
jscott

0

Вони LoaderExceptionsприховані всередині запису про помилки. Якщо помилка типу додавання була останньою у списку помилок, використовуйте $Error[0].InnerException.LoaderExceptionsдля відображення помилок. Швидше за все, ваша бібліотека залежить від іншої, яка не була завантажена. Ви можете або Add-Typeкожен, або просто скласти список та використати -ReferencedAssembliesаргумент Add-Type.


Спробуйте $ Error [0]. Exception.LoaderExceptions та дотримуйтесь порад Еріса.
Тахір Хассан

-1

Я думаю, що тепер ви МОГЛИ знайшли відповідь на ці явища. Я наткнувся на цю посаду після того, як зіткнувся з тією ж проблемою ... Я міг завантажити збірку та переглянути типи, що містяться в збірці, але не зміг застосувати екземпляр її зі статичного класу. Це було ПОВЕРНЕНО. Tidy, EFTidyNet.TidyNet.Options чи що? Ooooo Weeee ... Проблеми ... проблеми ... це може бути все, що завгодно. А перегляд статичних методів та типів DLL не виявив нічого перспективного. Зараз у мене депресія. У мене це було в компільованій програмі C #, але для мого використання я хотів, щоб вона працювала мовою, що інтерпретується ...

Моє рішення я знайшов, і воно ще доводиться, але я в захваті від цього і хотів поділитися цим. Створіть невеликий додаток console.exe, що виконує функцію, яка мене зацікавила, а потім перегляньте її в чомусь, що може декомпілювати її або показати код IL. Я використав рефлектор Red-Gate та доповнення генератора мови powerhell та Wallah! це показало, що таке правильний рядок конструктора! :-) Спробуй це. і я сподіваюся, що це працює для тих, хто стикається з цією проблемою.


2
І ... який був правильний рядок конструктора? Це насправді не відповідає на питання так, як це написано. Також ласкаво просимо до ServerFault!
австрійський
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.