首先,我阅读以下内容:
因此,从最后一个项目符号开始,我真的认为没有办法解决此问题,但是我必须看看我是否能够得到明确的答案,因为我的团队希望从.NET 4.0升级到.NET 4.5。但是,我们必须支持XP。
如果我们要支持XP,是否不可能使用.NET 4.5?
我唯一想到的就是创建两个单独的解决方案,但是如果我们使用.NET 4.5功能,则代码库将不得不分开。
因此,我正在寻找一些我可能找不到并且其他人可能已经知道的惊人解决方法。
我犹豫要发布此答案,实际上这在技术上是可行的,但在实践中效果并不理想。在4.5中,CLR和核心框架程序集的版本号未更改。您仍然将CLR v4.0.30319作为目标,并且框架程序集版本号仍为4.0.0.0。使用ildasm.exe这样的反汇编程序查看汇编清单时,唯一与众不同的地方是[TargetFramework]属性的存在,该属性表示需要4.5,必须对其进行更改。实际上并不那么容易,它是由编译器发出的。
最大的区别是看不到,Microsoft对程序集的可执行标头进行了姗姗来迟的更改。哪个指定可执行文件与哪个Windows版本兼容。XP属于上一代Windows,始于Windows2000。它们的主要版本号是5。Vista是当前一代的开始,主要版本号是6。
.NET编译器始终将最低版本号指定为4.00,即Windows NT和Windows 9x的版本。您可以通过在程序集上运行dumpbin.exe / headers来查看此信息。示例输出如下所示:
OPTIONAL HEADER VALUES 10B magic # (PE32) ... 4.00 operating system version 0.00 image version 4.00 subsystem version // <=== here!! 0 Win32 version ...
.NET 4.5中的新功能是编译器将该子系统版本更改为6.00。由于Windows会关注该数字,而不仅仅是检查它是否足够小,所以该更改之所以过期了。由于它假定该程序是为在Windows的旧版本上运行而编写的,因此它也启用了appcompat功能。这些功能会带来麻烦,尤其是Windows在Aero中的大小与窗口大小有关。当它可以看到该程序被设计为在具有Aero的Windows版本上运行时,它不再躺在Aero窗口的粗边框上。
您可以使用/ subsystem选项在程序集上运行Editbin.exe来更改该版本号并将其设置回4.00。 此答案显示了一个示例postbuild事件。
但这是关于好消息结束的地方,一个重要的问题是.NET 4.5与.NET 4.0不太兼容。到目前为止,最大的麻烦是将类从一个程序集移动到另一个程序集。最值得注意的是,[Extension]属性发生了这种情况。以前在System.Core.dll中,它已移至.NET 4.5中的Mscorlib.dll。如果您声明自己的扩展方法,那么这在XP上就是一个大爆炸。程序说要在Mscorlib中查找该属性,该属性由.NET 4.5版本的System.Core参考程序集中的[TypeForwardedTo]属性启用。但是,当您在.NET 4.0上运行程序时,它不存在
当然,没有什么可以帮助您停止使用仅在.NET 4.5上可用的类和方法的。当您这样做时,在4.0上运行时,程序将因TypeLoadException或MissingMethodException而失败。
仅针对4.0,所有这些问题都将消失。或打破僵局并停止支持XP,这是程序员通常无法做出的业务决策,但可以指出造成的麻烦,当然可以鼓励这样做。当然,支持古老的操作系统要付出非零的代价,只是测试工作量很大。除非经常指出,否则Windows兼容性是一项传奇性的费用,管理人员通常不认识。将这笔费用转给客户,他们往往会更快地做出正确的决定:)但是我们不能为您提供帮助。