诡异的dll(2)

还是昨天,还是同一个哥们。他要实现一个语音叫号的功能,要先普通话叫号,然后再粤语叫号。

诡异的事情发生了,在调试状态下,怎么运行都是正常的,
但直接双击运行,只能叫第一种声音(粤语或普通话),另一个声音(粤语或普通话)怎么都发不出来。
悲剧的是,他语音叫号也是调用了一个dll。

只好慢慢调试了,开始以为是线程退出的太快,或者变量作用域问题,或变量中繁体中文乱码问题,或者函数退出太快,或者是release时优化掉了…

弄了一个多小时,没有任何进展。无奈之下,我翻出了Process Explorer,去查看环境变量。
结果调试的时候,第一个环境变量是

__COMPAT_LAYER=WinXpsp3

天啊,这不是兼容模式吗。
于是将exe设成兼容模式,双击运行,就好了。

原来,他用BCB6做开发,在Win7 sp1上无法正常运行,就设成了兼容模式,调试时运行的exe当然也继承了兼容模式的环境变量咯。
吐血啊……

回家,搜了一下__COMPAT_LAYER环境变量,可以设置为以下数值:

兼容性:

兼容模式
WIN95 Windows 95
WIN98 Windows 98 / Windows Me
NT4SP5 Windows NT 4.0 (Service Pack 5)
WIN2000 Windows 2000
WINXP Windows XP
WINXPSP2 Windows XP (Service Pack 2)
WINXPSP3 Windows XP (Service Pack 3)
WINSRV03SP1 Windows Server 2003 (Service Pack 1)
WINSRV08SP1 Windows Server 2008 (Service Pack 1)
VISTARTM Windows Vista
VISTASP1 Windows Vista (Service Pack 1)
VISTASP2 Windows Vista (Service Pack 2)
WIN7RTM Windows 7

权限:

权限
RUNASADMIN 以管理员权限运行
RUNASINVOKER 以调用者权限运行

显示模式:

显示模式
DISABLETHEMES 禁用视觉主题
640X480 用640×480屏幕分辨率运行
HIGHDPIAWARE 高DPI设置时禁用显示缩放
256COLOR 用256色运行
DISABLEDWM 禁用桌面元素

另外,也可以通过注册表,设置程序的兼容模式:

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers]
"D:\\TEST\\Hello.exe"="WINXPSP3"
    HKEY hKey;
    LPCTSTR strSubKey = "Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers";
    long lRet = ::RegOpenKeyEx( HKEY_CURRENT_USER, strSubKey, 0, KEY_WRITE, &hKey );
    if ( lRet == ERROR_SUCCESS )
    {
        TCHAR achValue[] = { _T("WINXPSP3") };
        CString strExePath = _T("D:\\Test\\Hello.exe");
        lRet  = ::RegSetValueEx( hKey, strExePath, NULL, REG_SZ, (LPBYTE)&achValue, sizeof(achValue) );
        RegCloseKey( hKey );
    } 

Comments are closed.