7

我有一个引用 DLL 的 EXE——在本例中,我将其命名为TestDLL.dll
EXE 用 C# 编写,DLL 用 VB .Net 编写。

我创建了 DLL 的演示程序集版本 - 例如 - TestDLL.dll 版本 1.0.0.0。
我想参考演示版 DLL (1.0.0.0) 来编译 EXE。之后 - 我希望 EXE 使用相同的 DLL,但我将放入 GAC 中的任何版本。
为此,我将DLL 引用的“复制本地”属性设置为FALSE

例如,我的目标是 - 编译后,我将使用程序集版本 2.1.6.0 放入 GAC TestDLL.dll,EXE 将使用程序集重定向绑定找到它。为此,我使用了一个配置文件。我使用此链接创建它: http:
//msdn.microsoft.com/en-us/library/7wd6ex19 (v=vs.71).aspx

所以我的配置文件看起来像这样:

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
       <dependentAssembly>
         <assemblyIdentity name="myAssembly"
                           publicKeyToken="32ab4ba45e0a69a1"
                           culture="en-us" />
         <!-- Assembly versions can be redirected in application, publisher policy, or machine configuration files. -->
         <bindingRedirect oldVersion="1.0.0.0"
                          newVersion="2.1.6.0"/>
       </dependentAssembly>
      </assemblyBinding>
   </runtime>
</configuration>

问题是,在完成所有这些之后,我运行了 EXE,当访问 dll 时,我得到了著名的错误: System.IO.FileNotFoundException: 无法加载文件或程序集 'TestDLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9d8162944bd6fdc7' 或其依赖项之一。该系统找不到指定的文件。文件名:'TestDLL,版本=1.0.0.0,文化=中性,PublicKeyToken=9d8162944bd6fdc7'

意思是,EXE 找不到我引用的原始 DLL 。我知道我可以“引用” GAC 或使用反射,但我不想——因为这个 EXE 应该只能以这种方式工作。

有谁知道问题出在哪里以及如何解决?
谢谢

4

1 回答 1

12

确保您设置了正确的publicKeyToken. 在您展示的代码中,您使用publicKeyToken="32ab4ba45e0a69a1"的是来自 MSDN 链接的公钥令牌。这显然不是您程序集的公钥令牌。为此,您需要使用相同的密钥对两个程序集(1.0.0.0 和 2.1.6.0)进行签名。要提取公钥令牌,您可以使用sn.exe工具或查看您获得的异常堆栈跟踪(它告诉您publicKeyToken="9d8162944bd6fdc7"):

sn.exe -Tp myassembly.dll

但是,如果编译可执行文件的程序集没有使用相同的密钥签名,这将不起作用。

我还看到你已经设置了culture="en-us"但是你的程序集使用这种文化吗?你也可以试试culture="Neutral"

最后确保您已将正确版本的程序集部署到 GAC 中。

于 2012-04-17T06:45:25.430 回答