场景
我有两个 Microsoft Office 包装器,一个用于 2003 年,一个用于 2007 年。由于同时运行两个版本的 Microsoft Office 是“官方不可能的”,Microsoft 也不推荐,所以我们有两个盒子,一个用于 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 用于编程目的。 (根据 Microsoft 的说法,从技术上讲,您可以将两个 Office 放在一起)但不是用于编程并且并非没有一些问题。
问题
当我们更改应用程序版本(例如从 1.5.0.1 到 1.5.0.2)时,我们需要重新编译 DLL 以匹配应用程序的新版本,这是自动完成的,因为 Office 包装器包含在解决方案中.由于包装器包含在解决方案中,因此它们继承了 APP 版本,但我们必须执行两次,然后将另一个 DLL“复制”到创建安装程序的机器上。 (痛苦……)
问题
是否有可能编译一个 DLL,它可以与应用程序的任何 版本一起工作,尽管是“旧的”?我读过一些关于 list 的内容,但我从来没有与这些进行过交互。任何指针将不胜感激。
这样做的 secret 原因是我们“多年以来”都没有更改我们的包装器,Microsoft 也没有使用他们古老的 API,但我们正在重新编译 DLL 以匹配 每个 上的应用程序版本释放我们做的。我想自动执行此过程,而不必依赖两台机器。
我无法从项目(两者都没有)中删除 DLL,因为存在依赖关系。
我可以创建第三个“主包装器”,但还没有考虑过。
有什么想法吗?还有其他人有同样的要求吗?
更新
澄清:
我有 1 个解决方案和 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 的包装程序,反之亦然。
提前致谢。
最佳答案
当 .NET 程序集解析器无法在运行时找到引用的程序集(在这种情况下,它无法找到应用程序所链接的特定包装器 DLL 版本),它的默认行为是失败并使应用程序崩溃。但是,可以通过 Hook AppDomain.AssemblyResolve 事件来覆盖此行为。只要找不到引用的程序集,就会触发此事件,它使您有机会用另一个程序集替换丢失的程序集(前提是它们兼容)。因此,例如,您可以替换您自己加载的包装器 DLL 的旧版本。
我发现最好的方法是在 Hook 事件的应用程序的主类上添加一个静态构造函数,例如:
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;
}
}
}
通过将它放在主应用程序类的静态构造函数中,可以保证它在任何代码尝试访问包装器 DLL 中的任何内容之前运行,确保钩子(Hook)提前到位。
您也可以使用策略文件进行版本重定向,但这往往更复杂。
关于c# - 在 .NET 中编译与版本无关的 DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/277817/