windows的兼容模式

Windows从Vista之后,新增了一个应用程序的兼容模式。比如程序在XP系统下面可以正常运行,但是系统升级到Win7之后,调用的一个XP的系统接口在Win7系统里不存在或者接口行为或者参数意义发生了改变,这样程序运行的时候就会发生崩溃或者异常。兼容模式就是让程序不变的情况下,操作系统自己去兼容程序的API调用。

我们在Win7上面右键菜单查看属性,选择兼容性,可以看到如下图所示:

选择兼容模式,就可以让应用程序兼容所选定的操作系统运行。

比如我们选择兼容Windows XP(Service Pack 3)来运行程序,这时候操作系统就会在注册表的HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers位置建立一个以程序路径为key,值为WINXPSP3的字符串,如下图所示:

在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers里面也有同样的设置,它是对所有用户都生效。

此外,程序的环境变量里面也多了一个”__COMPAT_LAYER=WinXPSp3”,如下图所示:

不同的兼容模式,其值不一样的,可以参加这篇文档的最底部https://msdn.microsoft.com/en-us/windows/compatibility/pca-scenarios-for-windows-8,下面是一些常见的值:

Mode Description
Windows7RTM This mode emulates common Windows 7 behavior including the operating system version number 6.1
WindowsVistaSP2 This mode emulates common Windows 7 behavior including the operating system version number 6.1
WindowsXPSp3 This mode emulates common Windows XP SP3 behavior including the operating system version number 5.1. This also includes the RUNASHIGHEST mode
RUNASHIGHEST This mode prompts the user to run the app with the highest available privilege. Users with administrative privileges will see a UAC elevation prompt for the app
RUNASADMIN This mode always prompts the user to run the app with administrative privileges; apps with this mode will always get the UAC elevation prompt
ELEVATECREATEPROCESS This mode makes child processes of the main app run with administrative privileges; the child processes will get a UAC elevation dialog
PINDLL This mode forces a DLL to be in memory for an app even if the app unloads the DLL
DISABLEUSERCALLBACKEXCEPTION This mode intercepts user call back exceptions and allows the app to continue on without having to handle the exception
VIRTUALIZEDELETE This mode intercepts delete operations on protected files and prevents apps from failing due to unhandled exceptions from the delete operation
WRPMITIGATION This mode returns success when an app tries to write, modify, or delete Windows protected files or registry entries (without actually completing the operation)
DXMAXIMIZEDWINDOWEDMODE This mode identifies apps that go into full screen mode and redirects them into a maximized Window mode
HIGHDPIAWARE This mode lets the rest of Windows know that the app is High DPI aware, and helps proper rendering of UI elements, text, font, etc.

所以,通过代码的方法以兼容模式运行程序,有两种办法:

  1. 在注册表的HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers位置建立一个以程序路径为key,值为WINXPSP3的字符串。这个是持久化的办法,只有注册表里面存在这个值,程序就一直以兼容模式运行。
  2. 父进程设置环境变量”__COMPAT_LAYER=WinXPSp3”,然后启动子进程,那么子进程就是以兼容模式运行。这个是非持久化的让程序以兼容模式运行。

Windows是如何实现兼容模式的呢。其实很简单,当程序设置了以兼容模式运行的标志之后,操作系统会为程序加载C:\Windows\AppPatch目录下面的AcGenral.dll、AcLayers.dll、AcXtrnal.dll,这个Dll会Hook住程序的系统API调用,返回程序兼容的结果。如下面:

程序在兼容模式里调用CreateProcessW,实际上调用的是cLayers.dll!NS_ElevateCreateProcess::APIHook_CreateProcessW

说到这里,这就是Windows的Application Compatibility Shims技术。Shim是微软系统中一个小型函数库,用于透明地拦截API调用,修改传递的参数、自身处理操作、或把操作重定向到其他地方。Shim主要用于解决遗留应用程序在新版Windows系统上的兼容性问题。相关介绍见https://technet.microsoft.com/en-us/library/dd837644(v=ws.10).aspx、http://www.freebuf.com/news/48878.html。

发表评论

电子邮件地址不会被公开。 必填项已用*标注