无法调用反射dll中的方法.我怎样才能得到一个更好的错误信息

本文关键字:信息 错误 更好 一个 dll 反射 调用 方法 | 更新日期: 2023-09-27 18:09:57

我正在尝试编写一个PowerShell脚本,该脚本将通过反射在某个DLL (MyNamespace.MyLibrary.dll)中包含的静态类(MyClass)中调用一系列静态方法。然而,即使调用库中最简单的方法(MyNamespace.MyLibrary.MyClass.CallMe())也会失败,并出现以下错误消息:

Exception calling "CallMe" with "0" argument(s): "The type initializer for 'MyNamespace.MyLibrary.MyClass' threw an exception."
At C:'temp'powershellTest.ps1:41 char:1
+ $output = [MyNamespace.MyLibrary.MyClass...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : TypeInitializationException
第一个奇怪的事情是,当我试图在static类中调用static方法时,我得到了类型初始化(构造函数?)错误。

进行调用的PowerShell代码:

[reflection.assembly]::LoadFile($dllLocation + 'MyNamespace.MyLibrary.dll')
$output = [MyNamespace.MyLibrary.MyClass]::CallMe()
Write-Host $output
相关的c#代码:
namespace MyNamespace.MyLibrary
{
    public static class MyClass
    {
        public static string CallMe() // the CallMe() method was added just to try to debug this
        {
            return "I was called";
        }
    }
}

现在,这个特定的库要大得多,并且有许多依赖项,所有这些都在MyClass的其他方法中使用。我制作了另一个DLL,它实际上尽可能简单(没有外部依赖)来测试我的powershell反射,并且它成功地调用了静态类的方法(显然也是静态的)。这告诉我,我的powershell是正确的,所以我查找了为什么我可能会得到这个问题。这个注释说它可能不会自动加载MyNamespace.MyLibrary的所有引用。

我尝试了两种方法来补救:

  1. 我将MyLibrary引用的所有非gced dll复制到同一文件夹中,以便它们与MyLibrary.dll并列

  2. 当这不起作用时,我还在MyNamespace.MyLibrary.dll之后添加了显式的[reflection.assembly]::LoadFile(path'otherAssembly.dll)行,以确保powershell可以加载它们。

这是我的主要问题:我怎么能得到一个更具体的错误信息,关于哪个依赖没有被发现,可能在哪里找?当我发现"尝试修复#1"还不够时,我很震惊,我不确定我还能做什么。

我希望这是有意义的;请随意提出任何必要的澄清问题。谢谢!

无法调用反射dll中的方法.我怎样才能得到一个更好的错误信息

根据这个答案,从复制dll的位置运行脚本,并尝试以下代码:

$currentScriptDirectory = Get-Location
[System.IO.Directory]::SetCurrentDirectory($currentScriptDirectory.Path)

这会给你异常的详细信息:

try
{
  [reflection.assembly]::LoadFile($dllLocation + 'MyNamespace.MyLibrary.dll')
  $output = [MyNamespace.MyLibrary.MyClass]::CallMe()
  Write-Host $output
}
catch [Exception]
{
  echo $_.Exception.GetType().FullName, $_.Exception.Message
}