程序集版本号、签名程序集 为什么我会收到 FileLoadExceptions
我的问题:
我有一个已签名的程序集 A.dll,其版本为 1.0.0.0 我有另一个引用 A.dll 的程序集(比方说 B.dll)。
一旦两个程序集都加载良好,没有任何问题。 现在,如果A.dll的版本更改为1.0.0.1并重新编译,B.dll是否必须重新编译?
我问这个问题是因为我遇到了这样的情况,在 A.dll 的版本发生更改后,我现在在尝试加载 B.dll 时收到以下异常:
Unhandled Exception: System.IO.FileLoadException:
Could not load file or assembly A, Version=1.0.0.0,
Culture=neutral, PublicKeyToken…
这让我认为这个问题的答案始终是肯定的。但是,我有另一个示例,其中我有两个具有上述确切场景的程序集,并且加载程序集没有任何问题。
什么场景/条件会导致此异常?如果有人能对此提供一些见解,我们将不胜感激。 谢谢。
My Problem:
I have a signed assembly A.dll that it versioned as 1.0.0.0
I have another assembly (lets say B.dll) that references A.dll.
Once both assemblies both assemblies load fine without any problem.
Now if the version for A.dll changes to 1.0.0.1 and is recompiled Does B.dll have to be recompiled?
I asking because I have this exact scenario where after A.dll had it's version changed I now receive the following Exception trying to load B.dll:
Unhandled Exception: System.IO.FileLoadException:
Could not load file or assembly A, Version=1.0.0.0,
Culture=neutral, PublicKeyToken…
This makes me think that the answer to this question is always yes. However I have another example where I have two assemblies that have the exact scenario described above and I do not have any problem loading the assemblies.
What scenario/conditions cause this exception? If anyone can offer some insight to this it would be greatly appreciated.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当程序集被强命名时,引用它的任何内容都将查找该特定版本。
您是正确的,Visual Studio 中的“特定版本”不会以任何方式影响运行时。事实上,“特定版本”基本上意味着“当您运行构建时,如果 MSBUILD 找不到引用的版本,构建应该失败,还是只使用可以在文件系统上找到的下一个版本?”
如果您重新编译 A 并部署它,作为部分更新(而不是完全推出应用程序),那么如果应用程序中有任何内容引用旧版本,您的应用程序可能会崩溃,除非您仍然拥有旧版本的 A A 也可用(即您没有覆盖它)。
这是某些产品使用 GAC 的主要原因,因为它可以保存同一 DLL 的多个版本而不会相互覆盖 - 如果您尝试将同一文件的不同版本部署到 bin 文件夹中(假设它们具有相同的文件名) ,它们通常会这样做),它们会互相覆盖,最终您的产品中只会得到 1 个 DLL!
您可以做的另一个技巧是将“重新版本化”的 DLL 放入二进制目录下的子文件夹中,然后编辑 app.config 以告诉运行时在哪里可以找到它们。
http://support.microsoft.com/kb/837908
因此,总而言之,命名程序集不仅仅使用简单的名称来确定程序集的身份 - 更改其版本可以被认为是完全更改其名称。
When an assembly is strongly named, anything that references it will look for that specific version.
You are correct that 'Specific Version' in Visual Studio doesnt affect the runtime in any way. In fact, the 'Specific Version' basically means "When you run a build, if MSBUILD cannot find the version that was referenced, should the build fail, or just use the next version that can be found on the filesystem?"
If you recompile A, and deploy it, as a partial update (rather than fully rolling out the application), then if there is anything in the application that references the old version, your application may break, unless you still have the old version of A available as well (i.e. you didnt overwrite it).
This is a main reason why some products use the GAC, because it can hold multiple versions of the same DLL without overwriting each other - if you tried to deploy different versions of the same file into your bin folder (assuming they had the same file name, which they typically do), they would overwrite each other, and you'd only end up with 1 of the DLLs in your product!
Another trick you can do is put your 're-versioned' DLLs in a sub-folder under then binary directory, and edit the app.config to tell the runtime where to find them.
http://support.microsoft.com/kb/837908
So, to sum up, a strongly named assembly uses more than just the simple name to determine an assembly's identity - changing its version could be thought of as changing its name completely.
程序集 A 是否已签名并不一定重要。您是否在项目 B 的程序集引用 A 上使用“特定版本 = true”进行编译?如果是这样,那么 CLR 将使用严格的规则来确定 A 的给定版本是否可接受。如果不是,那么 CLR 将使用不太严格的规则,并且如果 A 增加其版本,您将不需要重新编译。
根据您的环境,您可能不担心 A 会在未来版本中破坏兼容性。如果您不关心这个问题,那么您应该将程序集引用更改为“特定版本= false”。 (在工作中,我们有两种情况:例如,当我们依赖第 3 方控件时,我们通常强制“特定版本 = true”,但是当我们使用内部共享组件时,我们将针对该组件进行测试使用它的应用程序,我们将确保“特定版本 = false”,这样我们就不需要重新编译。)
您可以找到更多信息,包括当您确实有时如何通过配置文件规避此问题针对特定版本进行编译但想要稍后要重定向绑定,请在 MSDN 上:重定向程序集版本
希望有帮助!
Whether or not the assembly A is signed does not necessarily matter. Did you compile with 'Specific Version = true' on project B's assembly reference to A? If so, then the CLR will use strict rules to determine whether a given version of A is acceptable. If not, then the CLR will use less strict rules, and you won't need to recompile if A increments its version.
Depending on your environment, you may not be concerned that A will break compatibility in a future version. If it's not a concern for you, then you should change your assembly references to 'Specific Version = false'. (At work, we have both situations: when we depend on a 3rd-party control, for example, we generally force 'Specific Version = true', but when we're consuming an in-house shared component that we will test against the applications which use it, we'll make sure 'Specific Version = false' so we do not need to recompile.)
You can find more information, including how to circumvent this via configuration files when you do have to compile against a specific version but want to redirect bindings later, on MSDN: Redirecting Assembly Versions
Hope that helps!