web-dev-qa-db-ja.com

.NETアセンブリをPowershellセッションに適切に追加するにはどうすればよいですか?

ここで使用するソフトウェアをバックアップするための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

どんなガイダンスもありがとう!!

27
amandion

Add-Typeキャッチして、LoaderExceptionsプロパティを出力します。より詳細なエラーメッセージで例外が発生する場合があります。

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

私はこのリンクを見つけました: 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)が機能します。名前の一部を検索するためにテーブルを使用していません。

上記の方法のいくつかは、私にとってうまくいかなかったか、不明確でした。

-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

2
Ralph Willgoss

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

0
Eris

PowerShellでカスタムcsharpコントロールを読み込むには、次の設定を使用しました。これにより、Powershell内からコントロールをカスタマイズして利用できます。

ここにブログリンクがあります

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

そしてこれがソースとのcodeprojectリンクです

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

0
justcode_ca