.NETアセンブリをPowershellセッションに適切に追加する方法は?


24

ここで使用するソフトウェアをバックアップするためのAPIである.NETアセンブリ(dll)があります。これには、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.

別の.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
Brett

相対パスを使用する方法はありませんか?
アミット

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-in​​heritance-loaderexceptions


0

次のセットアップを使用して、powershellでカスタムcsharpコントロールをロードしました。PowerShell内からコントロールをカスタマイズして利用できます。

こちらがブログのリンクです

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

ここにソースとのcodeprojectリンクがあります

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


3
サーバー障害へようこそ!回答には、コンテンツへのポインタではなくコンテンツが含まれることが本当に望ましいです。これは理論的には質問に回答するかもしれませんが、回答の重要な部分をここに含め、参照用のリンクを提供することが望ましいでしょう
jscott

0

LoaderExceptionsエラーレコードの内側に隠されています。add-typeエラーがエラーリストの最後のエラーである場合は、を使用$Error[0].InnerException.LoaderExceptionsしてエラーを表示します。ほとんどの場合、ライブラリはロードされていない別のライブラリに依存しています。Add-Typeそれぞれ、またはリストを作成しての-ReferencedAssemblies引数を使用することができますAdd-Type


$ Error [0] .Exception.LoaderExceptionsを試して、Erisのアドバイスに従ってください。
タヒルハッサン14

-1

私は、あなたが今では推測MIGHTこの現象への答えを発見しました。同じ問題に遭遇した後、この投稿を実行しました...アセンブリを読み込み、アセンブリに含まれる型を表示できましたが、静的クラスからインスタンスをインスタンス化できませんでした。EFTIDYでしたか。Tidy、EFTidyNet.TidyNet.Optionsまたは何?Ooooo Weeee ...問題...問題...それは何でもかまいません。また、DLLの静的メソッドと型を調べても、有望なものは何も見つかりませんでした。今、私は落ち込んでいた。コンパイル済みのC#プログラムで動作させていましたが、使用するために、インタプリタ言語で実行することを望んでいました。

私が見つけた解決策はまだ証明されていますが、私は喜んでこれを共有したいと考えました。興味のあるfuncを実行する小さなconsole.exeアプリをビルドし、それを逆コンパイルまたはILコードを表示するもので表示します。Red-Gateのリフレクターとpowershell言語ジェネレーターアドインとWallahを使用しました!適切なコンストラクタ文字列が何であるかを示しました!:-) それを試してみてください。そして、この問題に直面している人のために機能することを願っています。


2
そして...適切なコンストラクタ文字列は何でしたか?これは、質問が書かれている方法で実際には答えません。また、ServerFaultへようこそ!
オースティン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.