如何正确地将.NET 程序集添加到 Powershell 会话?

如何正确地将.NET 程序集添加到 Powershell 会话?

我有一个 .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)"
}

参考
https://social.technet.microsoft.com/Forums/sharepoint/en-US/dff8487f-69af-4b64-ab83-13d58a55c523/addtype-in​​heritance-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 中自定义和使用该控件。

这是博客链接

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

这是带有源代码的 codeproject 链接

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

相关内容