我有一个 .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.
在另一个 .NET 程序集上使用相同的 cmdlet,点网压缩,其中有使用网站上相同功能的示例,但对我来说不起作用。
我最终发现我似乎能够使用反射来加载程序集:
[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
任何指导意见都感激不尽!!
答案1
您能否用 try catch 包围Add-Type
并打印 LoaderExceptions 属性,正如错误所述。它可能会提供带有更详细错误消息的异常。
try
{
Add-Type -Path "C:\rnd\CloudBerry.Backup.API.dll"
}
catch
{
$_.Exception.LoaderExceptions | %
{
Write-Error $_.Message
}
}
答案2
上述某些方法对我来说不起作用或不太清楚。
以下是我用来包装 -AddPath 调用和捕获 LoaderException 的方法:
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)"
}
答案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)
有效的原因。它没有使用该表来查找部分名称。
答案4
我使用以下设置在 powershell 中加载自定义 csharp 控件。它允许在 powershell 中自定义和使用该控件。
这是博客链接
这是带有源代码的 codeproject 链接
http://www.codeproject.com/Articles/311705/Custom-CSharp-Control-for-Powershell