- NSIS Discussion
- Windows XP Home vs Windows XP Pro
Archive: Windows XP Home vs Windows XP Pro
jweinraub
6th July 2005 16:50 UTC
Windows XP Home vs Windows XP Pro
How do I detect if the OS is XP Pro vs XP Home. If it is Home, I plan on rejecting the installer, throwing an error and if its pro, to allow it. i got a script that detects 95,98,etc, but i like to know pro/home of xp.
thanks
Anders
6th July 2005 18:15 UTC
You must do some calls with the system plugin,
first determine if the os is xp (with code you already have, or by calling GetVersion or GetVersionEx)
then if the os is xp (>= 5.1) then call GetVersionEx again, but this time with the OSVERSIONINFOEX struct, then check the wSuiteMask member for the VER_SUITE_PERSONAL bit
You could also use this class if you want to create a plugin instead of using the system plugin
ref:
http://msdn.microsoft.com/library/de...tversionex.asp
http://msdn.microsoft.com/library/de...infoex_str.asp
jweinraub
6th July 2005 20:02 UTC
pardon my ignorance, but i am still quite new to NSIS. How do I do this? this is what i use right now.
GetWindowsVersion
;
; Based on Yazno's function, http://yazno.***********/powerpimpit/
; Updated by Joost Verburg
;
; Returns on top of stack
;
; Windows Version (95, 98, ME, NT x.x, 2000, XP, 2003)
; or
; '' (Unknown Windows Version)
;
; Usage:
; Call GetWindowsVersion
; Pop $R0
; ; at this point $R0 is "NT 4.0" or whatnot
Function GetWindowsVersion
Push $R0
Push $R1
ClearErrors
ReadRegStr $R0 HKLM \
"SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
IfErrors 0 lbl_winnt
; we are not NT
ReadRegStr $R0 HKLM \
"SOFTWARE\Microsoft\Windows\CurrentVersion" VersionNumber
StrCpy $R1 $R0 1
StrCmp $R1 '4' 0 lbl_error
StrCpy $R1 $R0 3
StrCmp $R1 '4.0' lbl_win32_95
StrCmp $R1 '4.9' lbl_win32_ME lbl_win32_98
lbl_win32_95:
StrCpy $R0 '95'
MessageBox MB_OK|MB_ICONSTOP "Windows 95 is not supported by the software. $\n$\nPlease call 1-800- for additional support options." IDOK
Quit
Goto lbl_done
lbl_win32_98:
StrCpy $R0 '98'
MessageBox MB_OK|MB_ICONSTOP "Windows 98 is not supported by the software. $\n$\nPlease call 1-800-) for additional support options." IDOK
Quit
Goto lbl_done
lbl_win32_ME:
StrCpy $R0 'ME'
MessageBox MB_OK|MB_ICONSTOP "Windows Millennium Edition is not supported by the software. $\n$\nPlease call 1-800- for additional support options." IDOK
Quit
Goto lbl_done
lbl_winnt:
StrCpy $R1 $R0 1
StrCmp $R1 '3' lbl_winnt_x
StrCmp $R1 '4' lbl_winnt_x
StrCpy $R1 $R0 3
StrCmp $R1 '5.0' lbl_winnt_2000
StrCmp $R1 '5.1' lbl_winnt_XP
StrCmp $R1 '5.2' lbl_winnt_2003 lbl_error
lbl_winnt_x:
StrCpy $R0 "NT $R0" 6
MessageBox MB_OK|MB_ICONSTOP "Windows NT is not supported by the software. $\n$\nPlease call 1-800- for additional support options." IDOK
Quit
Goto lbl_done
lbl_winnt_2000:
Strcpy $R0 '2000'
Goto lbl_done
lbl_winnt_XP:
Strcpy $R0 'XP'
;; TODO: Detect Home and Professional Editions, abort on home
;; MessageBox MB_OK|MB_ICONSTOP "Windows XP Home Edition is not supported by the software. $\n$\nPlease switch to Windows XP Professional or call for additional support options."
;; Quit
Goto lbl_done
lbl_winnt_2003:
Strcpy $R0 '2003'
Goto lbl_done
lbl_error:
Strcpy $R0 ''
lbl_done:
Pop $R1
Exch $R0
FunctionEnd
thanks
jweinraub
11th July 2005 19:51 UTC
I know i make use of System::Call Kernel32::getversionex but i dont get how i get the suite out of it, nor do i get the call itself using the system plugin. please clarify, sorry for asking such a silly question, but i dont get it
flizebogen
12th July 2005 07:43 UTC
In the german press was an interesting article of how to convert a home edition to a pro edition. The article said the following Registry Key determines the kind of edition:
HKLM\SYSTEM\ControlSet001\Control\ProductOptions\ProductSuite
If the Value is "Personal" than it's the home otherwise its the pro edition.
jweinraub
12th July 2005 13:31 UTC
Wunderbar, tausend dank!
Afrow UK
12th July 2005 13:58 UTC
Nice find.
You can then change the NSIS GetWindowsVersion function.
Change:
lbl_winnt_XP:
Strcpy $R0 'XP'
Goto lbl_done
To:
lbl_winnt_XP:
ReadRegStr $R0 HKLM "SYSTEM\ControlSet001\Control\ProductOptions" ProductSuite
StrCmp $R0 'personal' 0 +3
Strcpy $R0 'XP Home'
Goto lbl_done
Strcpy $R0 'XP Pro'
Goto lbl_done
-Stu
jweinraub
12th July 2005 15:36 UTC
i dont have XP Home here in the office, but i imagine the StrCmp is NOT case sensitive? if it is, i think it should be 'Personal' but i am not sure.
Afrow UK
12th July 2005 15:53 UTC
Nope, it's case insensitive.
-Stu
jweinraub
14th July 2005 01:19 UTC
Ok...Doesnt work because of this it is a reg_multi_sz
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\ProductOptions]
"ProductType"="WinNT"
"ProductSuite"=hex(7):50,00,65,00,72,00,73,00,6f,00,6e,00,61,00,6c,00,00,00,00,\
00
any ideas?
lbl_winnt_XP:
ReadRegStr $R5 HKLM "SYSTEM\ControlSet001\Control\ProductOptions" ProductSuite
MessageBox MB_OK "Suite: $R5" IDOK
; StrCmp $R5 'Personal' home_error lbl_done
Afrow UK
14th July 2005 17:51 UTC
I think ReadRegDWORD will work instead.
-Stu
jweinraub
14th July 2005 19:33 UTC
I dont have home in the office so i cant check it here, but i dont think that would work. I found this on the wiki http://nsis.sourceforge.net/wiki/REG_MULTI_SZ_Reader but its quite complex and it has a lot of functionality i dont need. i just need the string returned so i can do a strcmp.
thanks
Afrow UK
14th July 2005 20:07 UTC
Haven't tested this, but it should work.
!define HKEY_CLASSES_ROOT 0x80000000
!define HKEY_CURRENT_USER 0x80000001
!define HKEY_LOCAL_MACHINE 0x80000002
!define HKEY_USERS 0x80000003
!define HKEY_PERFORMANCE_DATA 0x80000004
!define HKEY_PERFORMANCE_TEXT 0x80000050
!define HKEY_PERFORMANCE_NLSTEXT 0x80000060
!define HKEY_CURRENT_CONFIG 0x80000005
!define HKEY_DYN_DATA 0x80000006
!define KEY_QUERY_VALUE 0x0001
!define KEY_ENUMERATE_SUB_KEYS 0x0008
!define REG_NONE 0
!define REG_SZ 1
!define REG_EXPAND_SZ 2
!define REG_BINARY 3
!define REG_DWORD 4
!define REG_DWORD_LITTLE_ENDIAN 4
!define REG_DWORD_BIG_ENDIAN 5
!define REG_LINK 6
!define REG_MULTI_SZ 7
!define RegOpenKeyEx "Advapi32::RegOpenKeyExA(i, t, i, i, i) i"
!define RegQueryValueEx "Advapi32::RegQueryValueExA(i, t, i, i, i, i) i"
!define RegCloseKey "Advapi32::RegCloseKeyA(i) i"
!define ReadRegMultiSz "!insertmacro ReadRegMultiSz"
!macro ReadRegMultiSz VAR ROOT_KEY SUB_KEY VALUE
Push "${ROOT_KEY}"
Push "${SUB_KEY}"
Push "${VALUE}"
Call ReadRegMultiSz
Pop "${Var}"
!macroend
Function ReadRegMultiSz
Exch $R0
Exch
Exch $R1
Exch 2
Exch $R2
Exch 2
Push $0
Push $1
Push $2
Push $3
StrCpy $0 ""
StrCpy $1 ""
StrCpy $2 ""
StrCpy $3 ""
SetPluginUnload alwaysoff
System::Call "*(i) i (0) .r0"
System::Call "*(i) i (0) .r1"
System::Call "*(i) i (0) .r2"
System::Call "${RegOpenKeyEx}($R2, '$R1', \
0, ${KEY_QUERY_VALUE}|${KEY_ENUMERATE_SUB_KEYS}, r0) .r3"
StrCmp $3 0 goon
DetailPrint "Can't open registry key! ($3)"
Goto done
goon:
System::Call "*$0(&i4 .r4)"
System::Call "${RegQueryValueEx}(r4, '$R0', 0, r1, 0, r2) .r3"
StrCmp $3 0 read
DetailPrint "Can't query registry value! ($3)"
Goto done
read:
System::Call "*$1(&i4 .r3)"
StrCmp $3 ${REG_MULTI_SZ} multisz
DetailPrint "Registry value no SZ_MULTI_SZ! ($3)"
Goto done
multisz:
System::Call "*$2(&i4 .r3)"
StrCmp $3 0 0 multiszalloc
DetailPrint "Registry value empty! ($3)"
Goto done
multiszalloc:
System::Free $1
System::Alloc $3
Pop $1
StrCmp $1 0 0 multiszget
DetailPrint "Can't allocate enough memory! ($3)"
Goto done
multiszget:
System::Call "${RegQueryValueEx}(r4, '${VALUE}', 0, 0, r1, r2) .r3"
StrCmp $3 0 multiszprocess
DetailPrint "Can't query registry value! ($3)[2]"
Goto done
multiszprocess:
StrCpy $4 $1
loop:
System::Call "*$4(&t${NSIS_MAX_STRLEN} .r3)"
StrCmp $3 "" done
StrLen $5 $3
IntOp $4 $4 + $5
IntOp $4 $4 + 1
Goto loop
done:
System::Free $2
System::Free $1
StrCmp $0 0 noClose
System::Call "${RegCloseKey}(r0)"
noClose:
SetPluginUnload manual
System::Free $0
StrCpy $R0 $3
Pop $3
Pop $2
Pop $1
Pop $0
Pop $R2
Pop $R1
Exch $R0
FunctionEnd
You might want to put it all in a seperate .nsh file and !include it.
Usage:
${ReadRegMultiSz} $R0 HKLM "Software\Blah" "BlahBlah"
You should try ReadRegStr and only if that fails, call this function (e.g. IfErrors is set - make sure to use ClearErrors before hand).
-Stu
jweinraub
15th July 2005 01:24 UTC
hmm we're getting warmer
1 warning:
unknown variable/constant "{VALUE}" detected, ignoring (registry.nsh:100)
;;;line 100 below label
multiszget:
System::Call "${RegQueryValueEx}(r4, '${VALUE}', 0, 0, r1, r2) .r3"
this is how i called it, maybe thats why
lbl_winnt_XP:
${ReadRegMultiSz} $R5 HKLM "SYSTEM\ControlSet001\Control\ProductOptions" "ProductSuite"
StrCmp $R5 'Personal' home_error lbl_done
Afrow UK
15th July 2005 08:25 UTC
Sorry, missed a replacement.
In the code above, ${VALUE} should be $R0
-Stu
jweinraub
16th July 2005 03:39 UTC
I apologise for not getting back sooner, I was unable to get to a test computer with home edition (apparently ms wont allow you to change the null sring to Personal if i use professional (odd as it should be the other way around).
However, my installer still allowed me to install on a home install. everything else works fine except for home. i reckon this shouldnt be a problem as i can just leave it as is.
in an earlier post in this thread someone mentions using the system call to kernel32, maybe thats the best way, as it uses a function that does just that instead? but i dont know how to make use of that function, esp in my function i currently use.
anna123
7th April 2006 20:56 UTC
how to diff b/w win2003 and win2003R2.....question related to the originalpost
how to diff b/w win2003 and win2003R2