고수닷넷 - 데미소다오렌지님
1. Introduction
Windows XP 부터 프로그램 호환성이라는 항목이 새로 생겼습니다. 프로그램의 등록 정보에서 설정할 수 있는 기능으로 해당 프로그램의 호환성을 체크할 수 있습니다. Windows 95, 98, NT4 Sp5, Win2000등으로 호환성을 설정할 수 있으며, 호환성 체크를 제거할 수 있습니다.
호환성 체크를 단순히 그런 기능이 있구나 하고 넘어가신다면 큰 오산입니다. 해당 기능이 체크될 경우 각종 API들의 기능이 변경됩니다. 만약 Windows 95 호환성을 체크했다면 GetVersion API는 95에 해당하는 버전을 리턴할 것 입니다. 따라서 XP상에서 동작함에도 잘못된 정보를 인지할 수 있다는 문제점이 있습니다. 물론 잘못된 호환성 체크를 한 것은 사용자의 실수지만, 이러한 것들을 프로그램에서 판단해서 알려주면 좀 더 잘 만들어진 프로그램이라는 인상을 사용자에게 심어줄 수 있을 겁니다.
2장에서 프로그램 호환성에 대한 좀 더 상세한 정보를 알아보도록 하겠습니다.
2. Behind the scene
프로그램 호환성 정보는 레지스트리에 저장됩니다. 저장되는 경로는 아래와 위치입니다.
HKLM\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers
위 경로에 가 보면 호환성이 체크된 프로그램의 경우에는 해당 실행 파일 경로가 키값으로 존재하는 것을 볼 수 있습니다. 체크 상태와 매칭되는 값들은 다음과 같습니다.
- Windows 95 - "Win95"
- Windows 98 - "Win98"
- Windows NT4 Sp5 - "WinNT4SP5"
- Windows 2000 - "Win2000"
여기까지가 호환성과 관계된 전부입니다. 호환성을 체크하고 싶은 경우 해당 경로에 값을 남겨주면 됩니다. 제거하고 싶은 경우에는 해당 키를 제거하면 되죠.
그리고 잊지 말아야 할 중요한 점은 정확한 OS 버전을 체크해야 한다는 점 입니다. 1장에서도 언급했듯이, 이 기능은 XP이상에서 지원하는 기능이며 체크될 경우 GetVersion으로 버전 판단을 하게 되면 잘못된 버전을 리턴합니다. 그럼 어떻게 버전을 판단해야 할까요? 답은 VerifyVersion API입니다. VerifyVersion의 경우 호환성 체크를 하더라도 정상적으로 동작합니다.
3. Codes
아래는 프로그램의 호환성 모드를 구하고 설정하는 간단한 두가지 함수입니다. 각각 프로그램 경로와 APPCOMPATTYPE 값을 넣어주면 해당 값으로 설정되고 구해옵니다.
typedef enum _APPCOMPATTYPE
{
actNone = -1,
actWin95,
actWin98,
actWinNT4SP5,
actWin2000
} APPCOMPATTYPE, *PAPPCOMPATTYPE;
APPCOMPATTYPE GetAppCompatLayer(LPCTSTR szFileName)
{
HKEY hKey;
LPCTSTR szRegAppCompatLayerKey =
"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers";
APPCOMPATTYPE actRet = actNone;
LPCTSTR szActName[5] = {"Win95", "Win98", "WinNT4SP5", "Win2000", NULL};
if(IsWinXP() &&
RegOpenKey(HKEY_CURRENT_USER, szRegAppCompatLayerKey, &hKey) == ERROR_SUCCESS)
{
TCHAR szCompatType[MAX_PATH] = {0};
DWORD dwType;
DWORD dwSize = sizeof szCompatType;
if(RegQueryValueEx(hKey, szFileName, NULL, &dwType,
(LPBYTE) szCompatType, &dwSize) == ERROR_SUCCESS)
{
for(int i=0; szActName[i] != NULL; ++i)
{
if(stricmp(szCompatType, szActName[i]) == 0)
{
actRet = (APPCOMPATTYPE) i;
break;
}
}
}
RegCloseKey(hKey);
}
return actRet;
}
BOOL SetAppCompatLayer(LPCTSTR szFileName, APPCOMPATTYPE actNewType)
{
HKEY hKey;
LPCTSTR szRegAppCompatLayerKey =
"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers";
BOOL bRet = FALSE;
LPCTSTR szActName[6] = {"", "Win95", "Win98", "WinNT4SP5", "Win2000", NULL};
if(IsWinXP() &&
RegOpenKey(HKEY_CURRENT_USER, szRegAppCompatLayerKey, &hKey) == ERROR_SUCCESS)
{
TCHAR szNewType[MAX_PATH] = {0};
strcpy(szNewType, szActName[actNewType+1]);
if(strcmp(szNewType, "") == 0)
{
if(RegDeleteValue(hKey, szFileName) == ERROR_SUCCESS)
bRet = TRUE;
}
else
{
if(RegSetValueEx(hKey, szFileName, 0, REG_SZ, (LPBYTE) szNewType,
strlen(szNewType)+1) == ERROR_SUCCESS)
bRet = TRUE;
}
RegCloseKey(hKey);
}
return bRet;
}
- 작업관리자에 표시되는 응용프로그램 열거하기 (0)2007/01/02
- 트레이로 내려가는 애니메이션 출력 (0)2007/01/02
- XP 프로그램 호환성 정보 얻기 (0)2007/01/02
- PE 포맷 분석3 (0)2007/01/02
- PE 포맷 분석2 (0)2007/01/02

수안이의 컴퓨터 연구실



Leave your greetings.