ここで使用するソフトウェアをバックアップするための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
どんなガイダンスもありがとう!!
Add-Type
キャッチして、LoaderExceptionsプロパティを出力します。より詳細なエラーメッセージで例外が発生する場合があります。
try
{
Add-Type -Path "C:\rnd\CloudBerry.Backup.API.dll"
}
catch
{
$_.Exception.LoaderExceptions | %
{
Write-Error $_.Message
}
}
私はこのリンクを見つけました: 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)"
}
LoaderExceptions
はエラーレコード内に隠されています。追加タイプのエラーがエラーリストの最後のエラーである場合は、$Error[0].InnerException.LoaderExceptions
を使用してエラーを表示します。ほとんどの場合、ライブラリはロードされていない別のライブラリに依存しています。それぞれをAdd-Type
するか、リストを作成して-ReferencedAssemblies
引数をAdd-Type
に使用することができます。
PowerShellでカスタムcsharpコントロールを読み込むには、次の設定を使用しました。これにより、Powershell内からコントロールをカスタマイズして利用できます。
ここにブログリンクがあります
そしてこれがソースとのcodeprojectリンクです
http://www.codeproject.com/Articles/311705/Custom-CSharp-Control-for-Powershell