C#将所需的DLL放在输出根目录以外的地方[重复]

Posted

技术标签:

【中文标题】C#将所需的DLL放在输出根目录以外的地方[重复]【英文标题】:C# Putting the required DLLs somewhere other than the root of the output [duplicate] 【发布时间】:2011-01-27 13:59:03 【问题描述】:

我在一个项目中使用 EmguCV,当我们的程序运行时,它需要一些 dll,例如“cxcore.dll”等(或者它会引发运行时异常)。目前,我将文件放在输出文件夹的根目录中(在 Visual Studio 的文件属性中选择“始终复制”)。

但是看起来有点乱,那里有大约 10 个不同的 dll。有没有办法可以将它移动到输出文件夹中的子文件夹,它仍然会找到它。

【问题讨论】:

您是想从其他位置引用它们(即包含在所有其他依赖库中),还是将它们放在您的 bin 目录下的子文件夹中?这些也是包含在项目中,还是由您的应用加载(Assembly.Load,或P/Invoked)? @Gray:我想把它们放在我的 bin 目录下的一个子文件夹中。我不直接使用这些 dll,但它们被 EmguCV 项目使用(我相信它们是 P/Invoked)。另外,我认为 dll 本身是用 C 编写的。如果没有 dll,我仍然可以构建,但我会遇到运行时异常。 【参考方案1】:

到目前为止,答案令人惊叹。不对;)好吧,

是的,您可以将程序集放在不同的位置。

在相应的应用程序配置(app.config 复制到 your.exe.config)中添加:

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <probing privatePath="lib" />
    </assemblyBinding>
</runtime>

根据:

http://msdn.microsoft.com/en-us/library/823z9h8w.aspx

这将使程序查找程序集的私有路径(它自己的文件夹下的文件夹) - 就像 Web 应用程序查找 /bin。

您也可以将它们放入 GAC,但除非有其他原因,否则应避免这样做。

话虽如此,你真的不需要。如果您在开始菜单中正确安装应用程序,用户不会感到困惑;)我从来没有遇到过这个问题,包括具有 50 多个程序集的项目。用户根本看不到他们。

【讨论】:

@TomTom Svish 的回答是对的 至于你的回答。您确定它可以与非托管库一起使用吗? @TomTom:以上内容会在我的.csproj 文件中吗?我的项目是 C# winforms 应用程序 - 我找不到 .config 文件。 我的回答也是在我之后完成的。该条目将进入应用程序配置文件。阅读 .config 文件 - 真的。这是 .NET 基础知识。添加它,它会说应用程序配置。结果是一个名为“app.config”的 XML 文件,它被复制到“your.exe.config”中。这是您可以进行运行时配置的地方 - 类似于(实际上是相同的文件)Web 应用程序中的 web.config。阅读它们。 我试过了,但我不能让它正常工作......所以我找到了一个解决方案并在这里发布:***.com/a/51211161/5734097【参考方案2】:

要在子目录中获取程序集,您可以手动将它们复制到那里,使用构建前或构建后事件或完全不同的东西。

要加载它们,您可以使用AppDomain.AssemblyResolve Event,或(如TomTom 所述)&lt;probing&gt; Element。来自 MSDN:

以下示例显示如何指定运行时应搜索程序集的应用程序基子目录。

<configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <probing privatePath="bin;bin2\subbin;bin3"/>
        </assemblyBinding>
    </runtime>
</configuration>

GAC 当然是另一个转储程序集的地方,但这并不能真正算作子目录...除非您将应用程序安装在不应该安装的地方:P

【讨论】:

@Svish:以上内容会在我的 .csproj 文件中吗?我的项目是 C# winforms 应用程序 - 我找不到 .config 文件。 @aip.cd.aish:msdn.microsoft.com/en-us/library/4191fzwb(v=VS.90).aspx 有一个更完整的示例。如果没有配置文件,你可以创建一个。根据msdn.microsoft.com/en-us/library/ms229689(v=VS.90).aspx,它应该与您的应用程序命名相同,扩展名为 .config。 该文件也可能仅命名为 app.config... 但我不确定。阅读 MSDN 上的配置文件,你应该明白了 :)【参考方案3】:

您可以使用构建前/构建后事件以及告诉您输出文件夹在哪里的宏将 dll 复制到您想要的位置。

但是,如果 dll 与可执行文件不在同一目录中,则不会加载它们。 如果它们是托管的,您可以使用 Assembly.Load 方法手动加载它们。 如果它们不受管理,我不知道你该怎么做。

【讨论】:

当心构建前/构建后事件,尤其是在您使用多个开发人员和/或自动构建的环境中。它们可能是个大问题。【参考方案4】:

您可以将其保存在其他地方并仍然链接它。在参考属性中,将“复制本地”设置为 false 并相应地设置路径。这将起作用。如果外部 DLLS 需要更改版本,您可以将“特定版本”设置为 false,以便能够链接到任何版本。

【讨论】:

以上是关于C#将所需的DLL放在输出根目录以外的地方[重复]的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中从 dll 加载特定类

UCanAccess、IKVM 和 C#

Qt 在 Windows 中部署应用程序所需的 dll

QT程序自动拷贝所需动态库批处理

QT程序自动拷贝所需动态库批处理

Javascript二维数组[重复]