I would like to create a class that compiles into a single DLL. This DLL would add functionality to an existing product.
我想创建一个编译成单个DLL的类。此DLL将为现有产品添加功能。
To make this work, the custom class references DLLs contained in the underlying product. These references are needed to compile.
为了使其工作,自定义类引用底层产品中包含的DLL。编译需要这些引用。
Everything works fine here and the custom class compiles. I can drop the DLL produced into the product and everything works fine.
这里一切正常,自定义类编译。我可以将生成的DLL放到产品中,一切正常。
However, this product has several versions (minor versions, service packs). I would like to distribute this DLL to others but I'm finding the DLL must match perfectly the version of the product. If there isn't a perfect match, then the following error occurs:
但是,此产品有多个版本(次要版本,服务包)。我想将此DLL分发给其他人,但我发现DLL必须完美匹配产品的版本。如果没有完美匹配,则会发生以下错误:
Could not load file or assembly 'Product.Web.UI, Version=3.6.1920.2, Culture=neutral, PublicKeyToken=dfeaee0e3978ac79' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
无法加载文件或程序集'Product.Web.UI,Version = 3.6.1920.2,Culture = neutral,PublicKeyToken = dfeaee0e3978ac79'或其依赖项之一。定位的程序集的清单定义与程序集引用不匹配。 (HRESULT异常:0x80131040)
How do I produce a DLL that isn't picky about the version reference?
如何生成一个对版本引用不挑剔的DLL?
3 个解决方案
#1
7
This is an excellent solution. It solved a similar problem for me.
这是一个很好的解决方案。它为我解决了类似的问题。
Compile a version agnostic DLL in .NET
在.NET中编译与版本无关的DLL
In case that link ever dies, the key is to handle the AppDomain.CurrentDomain.AssemblyResolve event like below. The event fires any time an assembly binding fails, so you can resolve it yourself, fixing version conflicts.
如果链接死亡,关键是处理AppDomain.CurrentDomain.AssemblyResolve事件,如下所示。只要程序集绑定失败,事件就会触发,因此您可以自行解决它,修复版本冲突。
using System.Reflection;
static Program()
{
AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs e)
{
AssemblyName requestedName = new AssemblyName(e.Name);
if (requestedName.Name == "Office11Wrapper")
{
// Put code here to load whatever version of the assembly you actually have
return Assembly.LoadFile("Office11Wrapper.DLL");
}
else
{
return null;
}
}
}
#2
4
I don't yet have an answer to my question, but I'll use this answer to log breadcrumbs I found while searching for a solution.
我还没有回答我的问题,但我会用这个答案来记录我在搜索解决方案时发现的面包屑。
I found a somewhat related question on *:
我在*上发现了一个有点相关的问题:
Compile a version agnostic .DLL in .NET (Using Manifests?)
在.NET中编译与版本无关的.DLL(使用清单?)
I have no ability to modify the underlying product however, so the answer does not work for me.
但我没有能力修改基础产品,所以答案对我不起作用。
Updated:
更新:
I emailed someone much smarter than me and here was the reply:
我通过电子邮件发送了比我更聪明的人,以下是回复:
When you reference strong-named assembly, by default Visual Studio adds full reference to the referenced assembly. That means it includes the name of the assembly, the exact version, the culture and the public key token. If any of this information don't match the described exception is thrown.
引用强命名程序集时,默认情况下Visual Studio会添加对引用程序集的完全引用。这意味着它包括程序集的名称,确切的版本,文化和公钥令牌。如果任何此类信息不匹配,则抛出所描述的异常。
Removing the strong-names of our assemblies is simply not an option. I won't go in details why, but you can do some research in MSDN.
删除我们的程序集的强名称根本不是一个选项。我不会详细说明原因,但你可以在MSDN上做一些研究。
So, you have two options to workaround building against every version of the assemblies you are referencing.
因此,您有两种方法可以针对您引用的每个版本的程序集进行构建。
- You could do partial referencing. See this article: http://msdn.microsoft.com/en-us/library/0a7zy9z5(VS.71).aspx.
- 你可以做部分参考。请参阅此文章:http://msdn.microsoft.com/en-us/library/0a7zy9z5(VS.71).aspx。
- You can declare compatible versions with binding redirection in the web.config. See this article: http://msdn.microsoft.com/en-us/library/433ysdt1.aspx.
- 您可以在web.config中使用绑定重定向声明兼容版本。请参阅此文章:http://msdn.microsoft.com/en-us/library/433ysdt1.aspx。
In general the second approach is recommended because: 1. You cannot use partial reference to assemblies in the Global Assembly cache, meaning your control will throw the same exception if assemblies are in the GAC. 2. You explicitly state compatible versions.
通常建议使用第二种方法,因为:1。您不能在全局程序集缓存中使用对程序集的部分引用,这意味着如果程序集在GAC中,则控件将抛出相同的异常。 2.您明确说明兼容版本。
#3
0
In VisualStudio - have you tried right clicking on the referenced assembly (dll) and then selected properties and set "requires specific version" (or so) yet? That may solve your issue.
在VisualStudio中 - 您是否尝试右键单击引用的程序集(dll),然后选择属性并设置“需要特定版本”(或左右)?这可能会解决您的问题。
Andreas
安德烈亚斯
#1
7
This is an excellent solution. It solved a similar problem for me.
这是一个很好的解决方案。它为我解决了类似的问题。
Compile a version agnostic DLL in .NET
在.NET中编译与版本无关的DLL
In case that link ever dies, the key is to handle the AppDomain.CurrentDomain.AssemblyResolve event like below. The event fires any time an assembly binding fails, so you can resolve it yourself, fixing version conflicts.
如果链接死亡,关键是处理AppDomain.CurrentDomain.AssemblyResolve事件,如下所示。只要程序集绑定失败,事件就会触发,因此您可以自行解决它,修复版本冲突。
using System.Reflection;
static Program()
{
AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs e)
{
AssemblyName requestedName = new AssemblyName(e.Name);
if (requestedName.Name == "Office11Wrapper")
{
// Put code here to load whatever version of the assembly you actually have
return Assembly.LoadFile("Office11Wrapper.DLL");
}
else
{
return null;
}
}
}
#2
4
I don't yet have an answer to my question, but I'll use this answer to log breadcrumbs I found while searching for a solution.
我还没有回答我的问题,但我会用这个答案来记录我在搜索解决方案时发现的面包屑。
I found a somewhat related question on *:
我在*上发现了一个有点相关的问题:
Compile a version agnostic .DLL in .NET (Using Manifests?)
在.NET中编译与版本无关的.DLL(使用清单?)
I have no ability to modify the underlying product however, so the answer does not work for me.
但我没有能力修改基础产品,所以答案对我不起作用。
Updated:
更新:
I emailed someone much smarter than me and here was the reply:
我通过电子邮件发送了比我更聪明的人,以下是回复:
When you reference strong-named assembly, by default Visual Studio adds full reference to the referenced assembly. That means it includes the name of the assembly, the exact version, the culture and the public key token. If any of this information don't match the described exception is thrown.
引用强命名程序集时,默认情况下Visual Studio会添加对引用程序集的完全引用。这意味着它包括程序集的名称,确切的版本,文化和公钥令牌。如果任何此类信息不匹配,则抛出所描述的异常。
Removing the strong-names of our assemblies is simply not an option. I won't go in details why, but you can do some research in MSDN.
删除我们的程序集的强名称根本不是一个选项。我不会详细说明原因,但你可以在MSDN上做一些研究。
So, you have two options to workaround building against every version of the assemblies you are referencing.
因此,您有两种方法可以针对您引用的每个版本的程序集进行构建。
- You could do partial referencing. See this article: http://msdn.microsoft.com/en-us/library/0a7zy9z5(VS.71).aspx.
- 你可以做部分参考。请参阅此文章:http://msdn.microsoft.com/en-us/library/0a7zy9z5(VS.71).aspx。
- You can declare compatible versions with binding redirection in the web.config. See this article: http://msdn.microsoft.com/en-us/library/433ysdt1.aspx.
- 您可以在web.config中使用绑定重定向声明兼容版本。请参阅此文章:http://msdn.microsoft.com/en-us/library/433ysdt1.aspx。
In general the second approach is recommended because: 1. You cannot use partial reference to assemblies in the Global Assembly cache, meaning your control will throw the same exception if assemblies are in the GAC. 2. You explicitly state compatible versions.
通常建议使用第二种方法,因为:1。您不能在全局程序集缓存中使用对程序集的部分引用,这意味着如果程序集在GAC中,则控件将抛出相同的异常。 2.您明确说明兼容版本。
#3
0
In VisualStudio - have you tried right clicking on the referenced assembly (dll) and then selected properties and set "requires specific version" (or so) yet? That may solve your issue.
在VisualStudio中 - 您是否尝试右键单击引用的程序集(dll),然后选择属性并设置“需要特定版本”(或左右)?这可能会解决您的问题。
Andreas
安德烈亚斯