Archive: WinVer does not detect Vista


WinVer does not detect Vista
Hi all,

I am currently writing an Installer for XP / Vista. I use Winver to detect the Windows Version. On the Vista System (Vista Home Basic) WinVer detects XP. Here is the script I use, perhaps someone can point me in the right direction.

!include "LogicLib.nsh"
!include "WinVer.nsh"
.
var version
.
Function CheckWindowsVersion

${if} ${IsWinVista}
StrCpy $version "vista"
MessageBox MB_OK "Windows Vista detected"
${elseif} ${IsWinXP}
StrCpy $version "xp"
MessageBox MB_OK "Windows XP detected"
${else}
MessageBox MB_OK "Windows XP or Windows Vista required"
abort
${endif}

FunctionEnd

Thanks very much in advance

Protagonist


What does the GetVersion plug-in return?

Stu


Make sure you didn't forget to use RequestExecutionLevel to disable Vista's compatibility patches.


@ kichik: Adding RequestExecutionLevel admin lead to the same result. The example script under NSIS\Examples\GetVersion runs without it too and returns the correct result (see below)

@ Stu: here comes the funny part: I tried the GetVersion Plugin by creating the getversion.exe from the example.nsi file which comes with the plugin. I returned the correct result, identifying Vista correctly. I altered my script to the following:

!define CUST_INI "$PLUGINSDIR\custom.ini"

Name "Testinstaller"
OutFile "Setuptester.exe"
ShowInstDetails show
!include "LogicLib.nsh"
!include "mui.nsh"

Function CheckWindowsVersion

Push $R0
dumpstate::debug
GetVersion::WindowsName
Pop $R0
dumpstate::debug
FunctionEnd

Function .onInit
Call CheckWindowsVersion
FunctionEnd

Running the above script returns on the same Vista machine as the GetVersion.exe from the sample script returned Windowsname = XP
Dumbstate shows that $R0 ist empty prior to GetVersion::WindowsName but its value changes to XP after Getversion.

GetVersion is the first function I call, as the rest of the installer process depends on the variable returned.

The only difference I could find compared to the sample script is the inclusion of Logiclib and Mui, the rest of the code is identical.

Thanks for the help, I appreciate it very much.

Protagonist


This is strange. Both WinVer and GetVersion use the GetVersion/GetVersionEx API's and therefore on your system it is returning 5 for the major version which is wrong (6 is Vista and 5.x is XP I believe).

By any chance is Vista running the application in compatibility mode for XP? I have heard GetVersion can return 5 if this is the case.

Edit: And applying a Vista manifest (RequestExecutionLevel?) should stop this...
Edit #2: Maybe the System/GetVersion plug-in dll's need a manifest as well lol: http://forums.microsoft.com/MSDN/Sho...22199&SiteID=1

Stu


Woah, thanks :d

What also helped was renaming the installer from "Setuptester.exe" to "testit.exe" for Vista not to run it under XP compatibility mode.

As the installer i write will be used for different projects I will just get work around by reading HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion.

Thanks very much, you helped a Kraut in despair :D

Prota


Awesome, no problem.

Stu


So I've been doing testing with 2003, VISTA Enterprise, and Vista Enterprise SP1.

I've found with 2003, that when the user uses compatibility mode for the specific application, I cna use the registry key to determine the current real OS, (it will always say 2003)

However I've also discovered on Vista Enterprise SP1, that if my application is set to compatibility mode XP, that the registry key now returns XP, and not Vista as it does in previous versions of Vista and earlier OS's.


Thats the point of compatibility mode is it not? You can't have it both ways, either fix your app to run on Vista, or pretend its XP and stick to your old ways. If you must know the real OS, you could probably check the version info for kernel32.dll or make a little helper app with a manifest that checks the real version and saves it in $pluginsdir (its $exedir if you run it from the parents $pluginsdir)


Yes we actually do have manifests in our installers.

So the reason we need to do this, is because our Customer Service dept used this as a catch all for all problems people had on Vista. We have only a couple places we care about the OS, and now we are attempting to release a newer version of the product, and because our Customer Service dept used this pretty much as their catch all, (even though it never seemed to help anyone,) we have versions of our applications which are starting up.

However when running on the latest version of Vista, we find that when use the following chunk of code in our installer:

ReadRegStr $R0 HKLM \
"SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion

$R0 will be equal to the Windows version value for which the installer is configured to run in compatibility mode for.


I hate to repeat myself but, that behaviour is by design, MS is doing the right thing.

I have not tested Vista SP1, but I'm pretty sure using GetDLLVersion on kernel32.dll should do the trick and give you the real version. Or you could go the other way, detect compatibility mode and tell the user to turn it off


The only reason I even bothered to mention it, is that our application we are installing, also does the same check, and it does not read that registry entry as what the compatibility mode it is using is set to.

I'll try the kernel32.dll version check.


A note on why changing the file's name helped you
There are two important reg keys that control Vista Compatibility Assistant behavior:

HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Persisted\<EXE_FULL_PATH>
which is a DWORD, and when set to 1 even from withing the installer, will prevent Compatibility Assistant from popping up.

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers\<EXE_FULL_PATH>
which is a string (REG_SZ). If Vista thinks your installer is incompatible, it pops up Compatibility Assistant. If the user clicked "Reinstall using recommended settings", it will add this reg entry with value of "WINXPSP2" or something similar. From that moment on, most methods of detecting OS version will return the wrong result, because your installer and every process it starts will run in compatibility mode, getting fake values from registry.