【问题标题】:How to set C# library path for an application?如何为应用程序设置 C# 库路径?
【发布时间】:2023-03-14 22:08:01
【问题描述】:

我有使用 dll 的 C# 应用程序。当我尝试运行应用程序时,它找不到 dll,除非它位于同一目录或 GAC 中。我不想将它放在同一个目录中,也不想将它安装到 GAC。 有什么方法可以告诉应用程序在哪里寻找库? (例如,如果我想将应用程序分发给客户并且他们想使用自己的应用程序来使用 dll。)

添加:

我想要这个文件结构:

MainFolder:库、应用程序

库:lib.dll

应用程序:app1.exe

我不想将它复制到 GAC 或将 lib.dll 放在文件夹 Applications 中。有可能吗?

【问题讨论】:

标签: c# .net gac distribution


【解决方案1】:

我建议您客户的应用程序复制他们在自己目录中使用的 dll。

VB6 用于在应用程序之间共享 dll,我们有一个术语:DLL Hell

【讨论】:

  • 请使用更现代的术语来表示“DLL Hell”---> 全局程序集缓存。 =) 我认为 MS 在他们创建 GAC 时的本意是好的(“通往地狱的道路是......”),但感觉就像是同样的痛苦......应用程序的怪异、缺少功能、额外的部署步骤等。跨度>
【解决方案2】:

【讨论】:

  • 这和复制到GAC基本一样吗?
  • 不,它们在概念上是不同的。您甚至可以通过此方法将安装在 GAC 中的程序集重新路由到另一个版本。您必须编辑机器配置或将 DLL 放在子目录中。我怀疑它们中的任何一个都是你想要的,但正如 GvS 和 Jon 指出的那样,这通常不是一件好事
【解决方案3】:

在您的主目录中:

 AppDomain.CurrentDomain.AssemblyResolve += (s,e)=>{
    var filename = new AssemblyName(e.Name).Name;
    var path = string.format(@"C:\path\to\assembly\{0}.dll",  filename);
    return Assembly.LoadFrom(path);
 };

为此添加一些异常处理

【讨论】:

  • 谢谢;就我而言,我们的用户都安装了特定的产品 SDK,我们大致知道该库在哪里。 AssemblyResolve 事件处理程序正是我所需要的。
【解决方案4】:

正如您之前问题的答案所说,DLL 必须位于 GAC 或应用程序的目录或子目录中。

如果您的客户想要使用 DLL 编写自己的应用程序,您应该将其安装在 GAC 中或让他​​们也复制 DLL。拥有该库的多个副本听起来不是一件好事,但它确实是:这意味着您可以将一个副本升级到不同的版本而不会破坏其他所有内容。

【讨论】:

    【解决方案5】:

    没有 GAC 也可以,但程序集必须是强命名的,并且您必须在版本或 publickeytoken 更改时更改 app.config。这就是我所拥有的 \ 中的主程序,\Shared 中的共享库。和一个我想在 \SDK 中分离的子程序,它使用 ..\Shared 作为程序集。

    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
          <probing privatePath="shared" />
          <dependentAssembly>
             <assemblyIdentity name="protobuf-net" publicKeyToken="257b51d87d2e4d67" />
             <codeBase version="1.0.0.282" href="../protobuf-net.dll"/>
           </dependentAssembly>
           <dependentAssembly>
             <assemblyIdentity name="SevenUpdate.Base" publicKeyToken="5d1aea1de74f122c" />
             <codeBase version="11.5.4.0" href="../SevenUpdate.Base.dll"/>
           </dependentAssembly>
           <dependentAssembly>
             <assemblyIdentity name="SharpBits.Base" publicKeyToken="5d1aea1de74f122c" />
             <codeBase version="11.5.5.0" href="../SharpBits.Base.dll"/>
           </dependentAssembly>
           <dependentAssembly>
             <assemblyIdentity name="System.Windows" publicKeyToken="5d1aea1de74f122c" />
             <codeBase version="11.5.5.0" href="../System.Windows.dll"/>
           </dependentAssembly>
           <dependentAssembly>
             <assemblyIdentity name="WPFLocalizeExtension" publicKeyToken="5d1aea1de74f122c" />
             <codeBase version="11.5.5.0" href="../WPFLocalizeExtension.dll"/>
           </dependentAssembly>
        </assemblyBinding>
      </runtime>
    

    【讨论】:

      【解决方案6】:

      就像我在回答您上一个问题时所说的那样:

      在您的 app.config 或 machine.config 中使用 Assembly Redirection 指令。

      【讨论】:

        【解决方案7】:

        您可以记录,然后查看框架在尝试加载程序集时所采取的操作。这使得诊断程序集加载错误变得非常容易。

        执行这两个操作的工具是“FUSLOGVW.exe”(Fusion Log Viewer,Fusion 是加载程序的名称)并包含在 SDK 中。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-01-30
          • 2012-07-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多