参考非托管程序集

11
我试图在我的.NET项目中引用一个托管的DLL,而不将它复制到我的输出目录中。因此,当我的程序运行时,它从安装位置运行DLL - 无论它在哪里。问题在于这个托管的DLL调用了非托管的DLL。当我尝试引用这个托管的DLL时,它会抛出一个“FileNotFound Exception - Could not load file or assembly 'CharacterGen' or one of its dependencies. The system cannot find file specified”异常。当我将输出设置为与我正在引用的DLL相同的目录时,一切都正常工作。通常的解决方案是还要引用从其他程序集中调用的DLL。然而,我无法从我的托管程序中引用非托管的程序集。
有没有办法引用一个调用非托管DLL的托管DLL?

你熟悉GAC吗?如果你不想将文件复制到bin文件夹中,那么可以创建一个单独的文件夹,但你仍然需要将.dll文件复制到该文件夹中,并引用它们等等。如果不这样做,你就必须使用搜索路径来编写一些LoadFromAssebly代码。为什么不直接将.dll文件复制到可以正确引用的位置呢?此外,你是否考虑过创建MSI安装程序?这样,如果用户想要在不同的目录结构中运行/设置你的应用程序,至少他们可以这样做,并且相关的引用依赖关系将被处理。 - MethodMan
我对GAC不是很熟悉,但据我所知,程序集必须被签名。我无法控制我正在引用的DLL文件,因此无法验证它们是否已签名。我考虑过使用安装程序,但我不想安装到用户现有的目录中,因为那不是我的程序目录,而是存在于客户机器上的目录。如果没有其他办法,那将成为我的备选方案。 - XSL
1
GAC 对于引用非托管 DLL 没有用处。 - BrainSlugs83
2个回答

22

如果您想知道如何让Visual Studio将非托管DLL复制到输出目录,可以按照以下步骤操作:

  1. 将非托管dll作为文件或链接文件添加到您的项目中。(右键单击项目->添加->现有文件,然后选择“添加”或“添加为链接”)。
  2. 在解决方案资源管理器中选择该文件。在属性窗口中将构建操作设置为始终复制。

3
不要忘记未经管理的 DLL 可能需要其他未经管理的 DLL。如果您忘记添加这些 DLL,您可能会遇到完全相同的错误。如果您不确定依赖关系是什么,可以使用依赖项查看器来帮助您。 - insipid
1
谢谢!只是为了纠正一下,"始终复制"不在 "生成操作" 下面,它在 "复制到输出目录" 下面。 - oli.G

2
如果您的解决方案包含许多未经管理的C++ dll,并且其中有一两个托管的C#程序集,并且它们都需要位于同一个文件夹中,那么我发现将所有项目设置为使用相同的输出目录是最容易管理的解决方案。这样,如果稍后重命名项目等,它们仍然会出现在正确的位置;如果稍后添加新项目,您不必弄清楚需要添加哪些dll,只需将OutputPath设置为与其他项目完全相同的内容。
为此,我将OutputPath属性(对于每个项目的所有配置和平台)设置为$(SolutionDir)\bin\$(Configuration)
通常,我不在路径中包含$(Platform),因为对于未管理的项目,它被命名为Win32,而对于托管项目,它被命名为x86。但是,如果您确实需要平台隔离,则可以在.csproj文件中进行某些条件逻辑以创建具有所需值的新属性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接