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
Windows XP Home vs Windows XP Pro
17 posts
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:
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:
pardon my ignorance, but i am still quite new to NSIS. How do I do this? this is what i use right now.
thanks
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
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
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.
HKLM\SYSTEM\ControlSet001\Control\ProductOptions\ProductSuite
If the Value is "Personal" than it's the home otherwise its the pro edition.
Wunderbar, tausend dank!
Nice find.
You can then change the NSIS GetWindowsVersion function.
Change:
You can then change the NSIS GetWindowsVersion function.
Change:
To:lbl_winnt_XP:
Strcpy $R0 'XP'
Goto lbl_done
-Stulbl_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
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.
Nope, it's case insensitive.
-Stu
-Stu
Ok...Doesnt work because of this it is a reg_multi_sz
Windows Registry Editor Version 5.00any ideas?
[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
lbl_winnt_XP:
ReadRegStr $R5 HKLM "SYSTEM\ControlSet001\Control\ProductOptions" ProductSuite
MessageBox MB_OK "Suite: $R5" IDOK
; StrCmp $R5 'Personal' home_error lbl_done
I think ReadRegDWORD will work instead.
-Stu
-Stu
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
thanks
Haven't tested this, but it should work.
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
You might want to put it all in a seperate .nsh file and !include it.
!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
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
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
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
Sorry, missed a replacement.
In the code above, ${VALUE} should be $R0
-Stu
In the code above, ${VALUE} should be $R0
-Stu
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.
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.
how to diff b/w win2003 and win2003R2.....question related to the originalpost
how to diff b/w win2003 and win2003R2
how to diff b/w win2003 and win2003R2