【问题标题】:How to reference a libraby that's located in another folder如何引用位于另一个文件夹中的库
【发布时间】:2016-01-14 13:53:41
【问题描述】:

我有一个名为 app1.exe 的应用程序,它从名为 CodeToCall.dll 的 dll 库中调用一个函数。在生产环境中,我的库位于属于另一个程序的另一个文件夹中。当我运行我的应用程序时,它会引发以下异常:

未处理的异常:System.IO.FileNotFoundException:无法加载文件或程序集“dllToCall,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null”或其依赖项之一。系统找不到指定的文件。
在主(字符串 [] 参数)
在 mainCRTStartupStrArray(String[] arguments)

我引用的 Dll 可能正在使用一些库,并且它们无法加载。

我尝试在 Windows PATH 中包含 dll 文件夹,但没有成功,这是引用 dll 的正确方法

我的CodeToCall.dll 代码:

public class Class1
{
    public void Some()
    {
        Console.WriteLine("HI");
    }
}

我的app1.exe,当我添加codeToCall.dll作为参考时:

int main(array<System::String ^> ^args)
{
    //PCWSTR wcstr = L"C:\Program Files(x86)\Sigma"
    Console::WriteLine(L"Hello World");
    dllToCall::Class1^ obj = gcnew class dllToCall:Class1;
    obj->Some();
    Console::ReadKey();
    return 0;
}

【问题讨论】:

  • 这完全取决于你如何加载dll
  • 这不是C#,如果没有适当的语言标签,您很难获得答案。另外,避免将代码作为图像发布,将其复制到答案中是..复杂的。
  • @Sinatr 你说得对,它是 C++/cli,但 dll 加载机制是一样的
  • 这是一个简单的“找不到文件”错误,我们不太可能为您找到它。只需确保 C# 项目构建到与 C++ 项目相同的目录即可。使用 Fuslogvw.exe 进行故障排除。

标签: c# .net dll c++-cli


【解决方案1】:

您可以通过订阅AppDomain::AssemblyResolve 事件从任意文件夹加载程序集。 here 是汇编分辨率的一个很好的概述。

简而言之:

  • AppDomain::AssemblyResolve 事件将在运行时在任何常见位置找不到您引用的程序集时触发。
  • 在事件处理程序中,检查事件参数 (ResolveEventArgs::Name) 以确保 .NET 实际上正在请求您要加载的程序集。
  • 在事件处理程序中,现在由您来加载程序集,通常使用对 Assembly::LoadFrom 的调用,它允许您提供 CodeToCall.dll 的完整路径。
  • 如果Assembly::LoadFrom 成功,它将返回新加载程序集的句柄。您必须从您的 AssemblyResolve 事件处理程序中返回该句柄。

(您可能想在您的应用首次启动时直接调用 Assembly::LoadFrom,但仅此一项是行不通的 - 您必须AppDomain::AssemblyResolve 返回程序集的句柄处理程序。)

例子:

using namespace System;
using namespace System::Reflection;

Assembly^ MyResolveEventHandler(Object^ sender, ResolveEventArgs^ args)
{
    if (args->Name == "CodeToCall, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
        return Assembly::LoadFrom("C:\\Program Files (x86)\\Sigma\\CodeToCall.dll");
    else
        return nullptr;
}

void UseClass1()
{
    auto obj = gcnew CodeToCall::Class1;
    obj->Some();
}

int main(array<System::String ^> ^args)
{
    AppDomain::CurrentDomain->AssemblyResolve += gcnew ResolveEventHandler(MyResolveEventHandler);

    // You can't directly use Class1 in the same method/function
    // that you use to subscribe to AssemblyResolve.
    UseClass1();

    Console::ReadKey();
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多