在.NET中编译与版本无关的DLL

Mar*_*ini 9 .net c# dll version visual-studio-2008

脚本

我有两个围绕Microsoft Office的包装器,一个用于2003,一个用于2007.由于有两个版本的Microsoft Office并行运行"不正式",也没有Microsoft推荐,我们有两个盒子,一个用Office 2003,另一个用Office 2003使用Office 2007.我们分别编译包装器.DLL包含在我们的解决方案中,每个框都有相同的结帐但Office 2003或2007"卸载",因此它不会尝试编译该特定的DLL.由于Office COM DLL不可用,如果不这样做将导致编译错误.

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

事实

由于Microsoft在2007年神秘地改变了Office 2003 API,重命名和更改了一些方法(叹气)从而使它们不向后兼容,我们需要两个包装器.我们为每台构建机器提供了解决方案,并激活了一个Office DLL.例如:具有Office 2003的计算机已卸载"Office 2007"DLL,因此无法对其进行编译.另一个盒子是相同的想法,但反过来.这一切都是因为我们不能在同一个盒子中有2个不同的Office用于编程.(根据微软,你可以在技术上将两个Office放在一起),但不能用于编程,也不能没有一些问题.

问题

当我们改变了应用程序版本(从1.5.0.1至1.5.0.2为例),我们需要重新编译DLL相匹配的应用程序的新版本,这是自动完成的,因为Office包装包含在解决方案.由于包装器包含在解决方案中,因此它们继承了APP版本,但我们必须执行两次,然后将另一个DLL"复制"到创建安装程序的计算机上.(痛苦......)

是否可以编译一个可以与任何版本的应用程序一起使用的DLL ,尽管它"更老"?我已经阅读了一些关于清单的内容,但我从未与这些内容进行过互动.任何指针将不胜感激.

秘密原因是,我们没有在"时代"改变了我们的包装和也没有微软与他们的古老的API,但我们正在重新编译DLL以匹配应用程序版本,每一个我们做的释放.我想自动化这个过程,而不是依赖两台机器.

我无法从项目中删除DLL(它们都没有),因为存在依赖项.

我可以创建第三个"主包装器"但尚未考虑过它.

有任何想法吗?有其他要求相同的人吗?

UPDATE

澄清:

我有一个N项目的解决方案.

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

两个"包装器"都使用应用程序的依赖关系+解决方案中的其他库(数据层,业务层,框架等)

每个包装器都有相应Office包的引用(2003和2007).

如果我编译并且没有安装office 12,我会从Office12Wrapper.dll中找不到Office 2007库的错误.所以我拥有两台构建机器,一台使用Office 2003,一台使用Office 2007.在每台机器上进行完整的SVN更新+编译之后,我们只需在"安装程序"中使用office12.dll就可以将编译器编译为"相同"代码,相同版本".

注意:Office 2007 Build Machine,Office 2003的Wrapper"已卸载",反之亦然.

提前致谢.

Eri*_*ger 19

当.NET程序集解析程序无法在运行时找到引用的程序集时(在这种情况下,它无法找到应用程序链接的特定包装DLL版本),其默认行为是失败并且实质上使应用程序崩溃.但是,可以通过挂钩AppDomain.AssemblyResolve事件来覆盖此行为.无论何时找不到引用的程序集,都会触发此事件,并且它使您有机会替换另一个程序集来代替缺少的程序集(前提是它们是兼容的).因此,例如,您可以替换自己加载的旧版本的包装器DLL.

我发现这样做的最好方法是在挂钩事件的应用程序的主类上添加一个静态构造函数,例如:

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

通过将它放在主应用程序类的静态构造函数中,可以保证在任何代码尝试访问包装器DLL中的任何内容之前运行它,确保挂钩提前到位.

您还可以使用策略文件进行版本重定向,但这往往更复杂.