编译.NET版本无关的DLL [英] Compile a version agnostic DLL in .NET

查看:181
本文介绍了编译.NET版本无关的DLL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我身边的Microsoft Office两个包装,一是在2003年,一个是2007年以来有两个版本的Microsoft Office的运行并排是没有正式可能的,也不是建议由微软,我们有两个框,一个与Office 2003另一个与Office 2007,我们分别编译的包装。这些DLL包含在我们的解决方案,每个盒子具有的一样的结帐但无论是Office 2003或2007年的卸载,所以它不会尝试编译特定的DLL。否则,将抛出因无法使用办公室的COM DLL文件的编译错误。

I have two wrappers around Microsoft Office, one for 2003 and one for 2007. Since having two versions of Microsoft Office running side by side is "not officially possible" nor recommended by Microsoft, we have two boxes, one with Office 2003 and the other with Office 2007. We compile the wrappers separately. The DLLs are included in our solution, each box has the same checkout but with either Office 2003 or 2007 "unloaded" so it doesn't attempt to compile that particular DLL. Failure to do that will throw errors on compilation due to the Office COM DLLs not available.

我们使用.NET 2.0和Visual Studio 2008。

We use .NET 2.0 and Visual Studio 2008.

由于微软神秘地改变了Office 2003的API在2007年,重命名和改变一些方法(叹息的),从而使他们无法向后兼容,我们的需要的两种包装。 我们每个构建机器的解决方案和一个办公室的DLL激活。例如:机器与Office 2003有Office 2007的DLL卸载,因此不对其进行编译。另一框是相同的想法,但周围的其他方法。这一切都因为我们不能在为编程目的相同盒2不同的Office。 (你可以在技术上有两个办公室根据微软合作),但是的没有的编程,而不是没有一些问题。

Since Microsoft mysteriously changed the Office 2003 API in 2007, renaming and changing some methods (sigh) thus making them not backwards compatible, we need the two wrappers. We have each build machine with the solution and one Office DLL activated. E.g.: the machine with Office 2003 has the "Office 2007" DLL unloaded, therefore not compiling it. The other box is the same idea but the other way around. All this because we can't have 2 different Office in the same box for programming purposes. (you could technically have two Office together according to Microsoft) but not for programming and not without some issues.

当我们改变了应用程序版本(从1.5.0.1至1.5.0.2例如),我们需要重新编译该DLL以匹配应用程序的新版本,这是自动完成的,因为办公室包装包括在溶液。由于包装中包含的解决方案,这些继承APP版本,但我们必须这样做两次,然后复制其他DLL来创建安装程序的机器。 (一痛......)

When we change the Application Version (from 1.5.0.1 to 1.5.0.2 for example) we need to recompile the DLL to match the new version of the application, this is automatically done, because the Office wrapper is included in the solution. Since the wrappers are contained in the solution, those inherit the APP Version, but we have to do it twice and then "copy" the other DLL to the machine that creates the installer. (A Pain…)

是否有可能编译DLL,​​将使用的任意的版本的应用程序,尽管是老?我读过一些有关的清单,但我从来没有与这些交互。任何指针将AP preciated。

Is it possible to compile a DLL that will work with any version of the application, despite being "older"? I've read something about manifests but I have never had to interact with those. Any pointers will be appreciated.

这个秘密的原因是,我们没有改变我们的包装中的年龄和也没有微软与古老的API,但我们正在重新编译的DLL以匹配应用程序版本的每次的释放我们做。我想实现自动化,而不必依赖于这一进程的两个的机器。

The secret reason for this is that we haven't changed our wrappers in "ages" and neither did Microsoft with their ancient APIs, yet we are recompiling the DLL to match the app version on every release we make. I'd like to automate this process instead of having to rely on two machines.

我无法从项目中移除(他们都没有)的DLL,因为有依赖关系。

I can't remove the DLL from the project (neither of them) because there are dependencies.

我可以创建一个第三个主包装,但还没有想过这个问题呢。

I could create a third "master wrapper" but haven't thought about it yet.

任何想法?任何人有同样的要求?

Any ideas? Anyone else with the same requirement?

澄清:

我有1解决方案有N个项目。

I have 1 solution with N projects.

应用程序+ Office11Wrapper.dll + Office12Wrapper.dll。

"Application" + Office11Wrapper.dll + Office12Wrapper.dll.

两者包装使用依赖关系解决方案中的应用程序+其他库(datalayer,businesslayer,框架等)

Both "wrappers" use dependencies for application + other libraries in the solution (datalayer, businesslayer, framework, etc.)

每个包装都有了各自的Office程序包(2003年和2007年)的参考。

Each wrapper has references for the respective Office package (2003 and 2007).

如果我编译并没有办公室12安装,我得到没有找到Office 2007的库从Office12Wrapper.dll错误。 因此,我有两个建筑机械,一是与Office 2003,一个是Office 2007的后一个完整的SVN更新+编译每个机器上,我们只需使用office12.dll在安装程序有编对同一包装code,同一个版本。

If I compile and don't have office 12 installed, I get errors from Office12Wrapper.dll not finding the Office 2007 libraries. So what I have are two building machines, one with Office 2003, one with Office 2007. After a full SVN update + compile on each machine, we simply use office12.dll in the "installer" to have the wrapper compiled against the "same code, same version".

注:Office 2007的构建机器,有包装的Office 2003卸载,反之亦然

Note: The Office 2007 Build Machine, has the Wrapper for Office 2003 "unloaded" and viceversa.

在此先感谢。

推荐答案

在.NET程序集解析器无法找到在运行时引用的程序集(在这种情况下,它无法找到该应用程序已针对特定的包装DLL版本),它的默认行为是失败的,基本上崩溃的应用程序。但是,这种行为可以通过挂钩AppDomain.AssemblyResolve事件被覆盖。该事件被触发时引用的程序集无法找到,它让您有机会以另装配代替缺失的一(只要它们是兼容的)。所以,举例来说,你可以替代包装DLL的旧版本,你加载你自己。

When the .NET assembly resolver is unable to find a referenced assembly at runtime (in this case, it cannot find the particular wrapper DLL version the application was linked against), its default behavior is to fail and essentially crash the application. However, this behavior can be overridden by hooking the AppDomain.AssemblyResolve event. This event is fired whenever a referenced assembly cannot be found, and it gives you the opportunity to substitute another assembly in place of the missing one (provided that they are compatible). So, for instance, you could substitute an older version of the wrapper DLL that you load yourself.

我发现要做到这一点,最好的方法是添加静态构造函数的主类挂钩的情况下,应用程序,例如:

The best way I've found to do this is to add a static constructor on the main class of the application that hooks the event, e.g.:

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;
        }
    }
}

通过把这个在主应用程序类的静态构造函数,它保证任何code尝试访问任何的包装DLL之前运行,确保挂钩到位时间提前。

By putting this in a static constructor of the main application class, it is guaranteed to run before any code attempts to access anything in the wrapper DLL, ensuring that the hook is in place ahead of time.

您还可以使用策略文件做版本的重定向,但更趋于复杂。

You can also use policy files to do version redirection, but that tends to be more complex.

这篇关于编译.NET版本无关的DLL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆