La meilleure approche, je sais, c'est pour vérifier si spécifique de l'API est exporté à partir de quelques DLL. Chaque nouvelle version de Windows ajoute de nouvelles fonctions et par la vérification de l'existence de ces fonctions, on peut dire que l'OS de l'application est en cours d'exécution sur. Par exemple, Vista exportations GetLocaleInfoEx de kernel32.dll alors que les précédents Windowses n'a pas.
Pour couper la longue histoire courte, voici une liste ne contenant que les exportations de kernel32.dll.
> *fonction: mise en œuvre dans*
> GetLocaleInfoEx: Vista
> GetLargePageMinimum: Vista, Server 2003
GetDLLDirectory: Vista, Server 2003, XP SP1
GetNativeSystemInfo: Vista, Server 2003, XP SP1, XP
ReplaceFile: Vista, Server 2003, XP SP1, XP, 2000
OpenThread: Vista, Server 2003, XP SP1, XP, 2000, ME
GetThreadPriorityBoost: Vista, Server 2003, XP SP1, XP, 2000, NT 4
IsDebuggerPresent: Vista, Server 2003, XP SP1, XP, 2000, ME, NT 4, 98
GetDiskFreeSpaceEx: Vista, Server 2003, XP SP1, XP, 2000, ME, NT 4, 98, 95 OSR2
ConnectNamedPipe: Vista, Server 2003, XP SP1, XP, 2000, NT 4, NT 3
Bip: Vista, Server 2003, XP SP1, XP, 2000, ME, 98, 95 OSR2, 95
L'écriture de la fonction afin de déterminer la vraie version de l'OS est simple; il vous suffit de procéder de la plus récente de l'OS à la plus ancienne et l'utilisation de GetProcAddress pour vérifier exporté Api. La mise en œuvre de ce dans n'importe quelle langue devrait être trivial.
Le code suivant dans Delphi a été extrait à partir de la libre DSiWin32 de la bibliothèque):
TDSiWindowsVersion = (wvUnknown, wvWin31, wvWin95, wvWin95OSR2, wvWin98,
wvWin98SE, wvWinME, wvWin9x, wvWinNT3, wvWinNT4, wvWin2000, wvWinXP,
wvWinNT, wvWinServer2003, wvWinVista);
function DSiGetWindowsVersion: TDSiWindowsVersion;
var
versionInfo: TOSVersionInfo;
begin
versionInfo.dwOSVersionInfoSize := SizeOf(versionInfo);
GetVersionEx(versionInfo);
Result := wvUnknown;
case versionInfo.dwPlatformID of
VER_PLATFORM_WIN32s: Result := wvWin31;
VER_PLATFORM_WIN32_WINDOWS:
case versionInfo.dwMinorVersion of
0:
if Trim(versionInfo.szCSDVersion[1]) = 'B' then
Result := wvWin95OSR2
else
Result := wvWin95;
10:
if Trim(versionInfo.szCSDVersion[1]) = 'A' then
Result := wvWin98SE
else
Result := wvWin98;
90:
if (versionInfo.dwBuildNumber = 73010104) then
Result := wvWinME;
else
Result := wvWin9x;
end; //case versionInfo.dwMinorVersion
VER_PLATFORM_WIN32_NT:
case versionInfo.dwMajorVersion of
3: Result := wvWinNT3;
4: Result := wvWinNT4;
5:
case versionInfo.dwMinorVersion of
0: Result := wvWin2000;
1: Result := wvWinXP;
2: Result := wvWinServer2003;
else Result := wvWinNT
end; //case versionInfo.dwMinorVersion
6: Result := wvWinVista;
end; //case versionInfo.dwMajorVersion
end; //versionInfo.dwPlatformID
end; { DSiGetWindowsVersion }
function DSiGetTrueWindowsVersion: TDSiWindowsVersion;
function ExportsAPI(module: HMODULE; const apiName: string): boolean;
begin
Result := GetProcAddress(module, PChar(apiName)) <> nil;
end; { ExportsAPI }
var
hKernel32: HMODULE;
begin { DSiGetTrueWindowsVersion }
hKernel32 := GetModuleHandle('kernel32');
Win32Check(hKernel32 <> 0);
if ExportsAPI(hKernel32, 'GetLocaleInfoEx') then
Result := wvWinVista
else if ExportsAPI(hKernel32, 'GetLargePageMinimum') then
Result := wvWinServer2003
else if ExportsAPI(hKernel32, 'GetNativeSystemInfo') then
Result := wvWinXP
else if ExportsAPI(hKernel32, 'ReplaceFile') then
Result := wvWin2000
else if ExportsAPI(hKernel32, 'OpenThread') then
Result := wvWinME
else if ExportsAPI(hKernel32, 'GetThreadPriorityBoost') then
Result := wvWinNT4
else if ExportsAPI(hKernel32, 'IsDebuggerPresent') then //is also in NT4!
Result := wvWin98
else if ExportsAPI(hKernel32, 'GetDiskFreeSpaceEx') then //is also in NT4!
Result := wvWin95OSR2
else if ExportsAPI(hKernel32, 'ConnectNamedPipe') then
Result := wvWinNT3
else if ExportsAPI(hKernel32, 'Beep') then
Result := wvWin95
else // we have no idea
Result := DSiGetWindowsVersion;
end; { DSiGetTrueWindowsVersion }
--- mis à jour le 2009-10-09
Il s'avère qu'il devient très dur de faire un "sans-papiers", détection de système d'exploitation sur Vista SP1 et supérieur. Un regard sur les changements de l'API montre que tous les Windows 2008 fonctions sont également mis en œuvre dans Vista SP1 et que tous les Windows 7 fonctions sont également mis en œuvre dans Windows 2008 R2. Dommage :(
--- fin de la mise à jour
FWIW, c'est un problème que j'ai rencontré dans la pratique. Nous (la société où je travaille) ont un programme qui n'était pas vraiment avec Vista quand Vista est sorti (et quelques semaines après ...). Il n'a pas de travail en vertu de la couche de compatibilité soit. (Quelques problèmes DirectX. Ne demandez pas.)
Nous ne voulions pas trop-intelligent-pour-leur-propre-bonne les utilisateurs d'exécuter cette application sur Vista à tous les mode de compatibilité ou pas - j'ai donc dû trouver une solution (un mec plus intelligent que moi, m'a orienté dans la bonne direction; les trucs ci-dessus n'est pas de mon invention). Maintenant, je suis le poster, pour votre plaisir et pour aider tous les pauvres âmes qui auront à résoudre ce problème à l'avenir. Google, veuillez indice de cet article!
Si vous avez une meilleure solution (ou une mise à niveau et/ou de fixer, pour le mien), merci de poster une réponse ici ...