Selbst reingelegt beim Test von “XP oder später”
Manche Codezeilen schreibt man ja einfach im Schlaf so in etwa wie diesen hier
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | static const OSVERSIONINFO &GetOSVersionInfo() { static OSVERSIONINFO osVersionInfo; if (osVersionInfo.dwOSVersionInfoSize==0) { osVersionInfo.dwOSVersionInfoSize = sizeof(osVersionInfo); ::GetVersionEx(&osVersionInfo); } // return pointer to struct return osVersionInfo; } bool OSIsWinXP() { // Check if OS is XP or later const OSVERSIONINFO &osvi= GetOSVersionInfo(); return (osvi.dwPlatformId & VER_PLATFORM_WIN32_NT)!=0 && osvi.dwMajorVersion>=5 && osvi.dwMinorVersion>=1; } |
Der Sinn und Zweck ist eindeutig. Ich benötige diese Funktion um zu Testen ob Windows XP oder ein späteres OS wie Vista oder Windows 7 installiert ist. Dumm nur das dieser Code dämlich falsch ist.
Die Betriebssysteme haben die folgenden internen Versionsnummern
5.0 – Windows 2000
5.1 – Windows XP
5.2 – Windows Server 2003
6.0 – Windows Vista
6.1 – Windows 7 (Anmerkung: idotisch, dass hier nicht 7.0 verwendet wird)
Als ich den Code schrieb war Windows XP gerade draußen und selbst Windows Server 2003 gerade am Horizont. Dämlicherweise schrieb ich in dem Test osvi.dwMajorVersion>=5 && osvi.dwMinorVersion>=1.
ohne natürlich daran zu denken, dass ein späteres OS wieder mit einer 0 als minor Version kommen könnte.
Dadurch ergibt sich natürlich das der Test für alle Betriebssysteme nach Windows XP funktioniert nur nicht für Windows Vista weil eben die Minor Version hier 0 ist. Ich war drauf und dran mal wieder einen Bug einzureichen bis mir schlagartig klar war, dass nicht Vista einen Fehler hat sondern mein eigener Code.
Der korrekte Test muss natürlich so lauten:
13 14 15 16 17 18 19 20 21 | bool OSIsWinXP() { // Check if OS is XP or later const OSVERSIONINFO &osvi= GetOSVersionInfo(); return (osvi.dwPlatformId & VER_PLATFORM_WIN32_NT)!=0 && (osvi.dwMajorVersion>5 || // May be vista or later (osvi.dwMajorVersion==5 && // that's XP osvi.dwMinorVersion>=1)); } |
Code wie im Schlaf zu schreiben bringt es manchmal eben nicht.
8 Kommentare zu “Selbst reingelegt beim Test von “XP oder später””
Link für diesen Beitrag | RSS-Feed zu diesem Beitrag
Hinterlassen sie einen Kommentar:
Beachten sie bitte, dass Kommentare evtl. nicht sofort hier erscheinen. Die Kommentare werden zur Moderation an den Webmaster gesendet. Es kann also etwas dauern, bis Ihr Kommentar hier veröffentlicht wird!
on Do 05 Mrz 2009 um 20:26 #
Sven
Entsprechend des Funktionsnamens würde ich erwarten, dass nur bei Windows XP ‘true’ zurückgegeben wird. ‘OSIsWinXPOrHigher’ wäre hier eindeutiger.
on Do 05 Mrz 2009 um 21:37 #
Martin Richter
@Sven: Gebe ich Dir recht. Ich habe die Funktionsnamen für meinen Artikel angepasst und etwas unglücklich gewählt.
on Fr 06 Mrz 2009 um 10:39 #
Thorsten
Ich habe das bei mir so gelöst, dass ich die MajorVersion mit 10 multipliziere und dann die MinorVersion addiere. “XpOrHigher” wäre dann >=51 Das funktioniert ab Windows 2000 und auf Systemen mit der Major Version 4 läuft unsere Software sowieso nicht (mehr). Hoffentlich bleibt Microsoft da auch in Zukunft im Schema.
@Martin
Ich finde die interne Versionsnummer für Windows 7 in einer Art schon konsistent. Immer, wenn sich auf dem Desktop die Major Version geändert hat (Win 2000, Vista) hat es auch an der Win32 API größere Erweiterungen gegeben, und es war auch ein größerer Aufwand nötig, um das Programm an die Möglichkeiten der Plattform anzupassen. Bis jetzt sieht es bei mir so aus, als ob ein Vista kompatibles Programm (Trustinfo Manifest, nichts mehr in das Programm Verzeichnis schreiben, größere Icons, keine Adminrechte nötig) ohne weitere Änderungen auch unter Windows 7 rund läuft.
on Fr 06 Mrz 2009 um 10:57 #
Patrick
Sprecht Ihr euch ab?
http://blogs.msdn.com/larryosterman/archive/2009/03/05/checking-file-versions-is-surprisingly-hard.aspx
on Fr 06 Mrz 2009 um 13:17 #
Martin Richter
Und nein ich habe nicht abgeschrieben
So wie ich die Daten des RSS-Feeds interpretiere hat Larry seinen Artikel kurz nach mir heute in der Nacht veröffentlicht und soweit ich weiß kann er kein Deutsch
on Mi 22 Apr 2009 um 12:06 #
Dirk Gebhard
Euch ist aber schon bekannt, das die internen Versionnummern von
Windows XP-64 und Windows Server 2003 Identisch sind. Also
5.2 tragen. Das ist ein echtes Problem, konnte hier aber noch nichts finden.
on Mi 22 Apr 2009 um 13:34 #
Martin Richter
Ich verstehe Dein Problem nicht, denn das ist dokumentiert in der MSDN
OSVERSIONINFOEX http://msdn.microsoft.com/en-us/library/ms724833(VS.85).aspx
- Windows Server 2003 Version: 5.2
GetSystemMetrics(SM_SERVERR2) == 0
- Windows Server 2003 R2 Version: 5.2
GetSystemMetrics(SM_SERVERR2) != 0
- Windows XP Professional x64 Edition Version 5.2
(OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION) && (SYSTEM_INFO.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
on Mi 06 Okt 2010 um 01:24 #
Martin der andere
“Windows 7 (Anmerkung: idotisch, dass hier nicht 7.0 verwendet wird)”
=> FALSCH
Es wird immer nach der Buildnummer und Version des Kernels gegangen. Da Windows 7 nur ein aufgepepptes Windows Vista ist und sich nichts wesentliches im Kernel tat, wurde die Versionsnummer nur im Minor-oder Maintenance-Bereich geändert.
Du wirst’s nicht glauben, aber dies ist ebenfalls mit Windows 2000 und Windows XP 32 Bit so (5.0 zu 5.01). Windows XP 64 Bit besitzt allerdings schon 5.02, da dieses einen Windows 2003 Server Kernel besitzt und grössere Änderungen umgesetzt wurden insb. bei der Sicherheit.
Also Windows XP 64 Bit ist das wesentlich sicherere Windows XP.
Cheers