I have an application setup build in NSIS. The set requires a key to be created at the following location for my application to start:-
HKEY_LOCAL_MACHINE\Software\\\" "VersionNo" 0
HKEY_LOCAL_MACHINE\Software\Wow6432Node\\" "VersionNo" "11"
In the script, i have used:-
WriteRegDWORD HKLM "SOFTWARE\<Key1>\<Key2>\<Key3>" "VersionNo" 0
WriteRegStr HKLM "SOFTWARE\<Key1>\<Key2>" "VersionNo" "11"
This key is created successfully on a 32-bit Windows 7 system. However, when i install the setup on a 64-bit Windows 7 system the key is not created in the above location. Instead it creates the key at:-
HKEY_LOCAL_MACHINE\Software\Wow6432Node\<Key1>\<Key2>\<Key3>" "VersionNo" 0
HKEY_LOCAL_MACHINE\Software\Wow6432Node\<Key1>\<Key2>" "VersionNo" "11"
This results in my application not starting after installation.
--Can someone please suggest command/script for NSIS to compulsorily create the key(s) under HKEY_LOCAL_MACHINE\Software\ for a 64-bit system instead of it getting created under HKEY_LOCAL_MACHINE\Software\Wow6432Node?
Eagerly waiting for a solution....
Use SetRegView to switch between 32-bit and 64-bit registry. Your code should looks like:
SetRegView 64
WriteRegDWORD HKLM "SOFTWARE\<Key1>\<Key2>" "VersionNo" 0
SetRegView 32
WriteRegStr HKLM "SOFTWARE\<Key1>\<Key2>" "VersionNo" "11"
Related
I need to check if Microsoft filter pack 2.0 application is installed. I found this answer, but in my case I haven't the Application name, instead the name directory with program in registry named as {95140000-2000-0409-1000-0000000FF1CE} Here is my code to detect for installed app:
ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${FILTER_PACK_KEY}" "UninstallString"
IfErrors FilterPackNotFound FilterPackFound
The registry on 64-bit Windows has two "views" and 32-bit applications access the 32-bit view by default.
NSIS can access the 64-bit view by using the SetRegView instruction:
Section
SetRegView 64
RegReadStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\{95140000-2000-0409-1000-0000000FF1CE}" "UninstallString"
SetRegView 32
MessageBox mb_ok $0
SectionEnd
I am trying to write to the reg and cant seem to find the correct way.
HKEY_LOCAL_MACHINE
"SOFTWARE\Microsoft\Windows\CurrentVersion\Run" "XboxStat" '"C:\\Program Files\\Microsoft Xbox 360 Accessories\\XboxStat.exe\" silentrun'
"SOFTWARE\Microsoft\Windows\CurrentVersion\Run" "Hyperspin" "D:\\Arcade\\Hyperspin.exe\"
I have tried:
WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Run" "Hyperspin" "D:\\Arcade\\Hyperspin.exe\"
WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Run" "Hyperspin" "D:\\Arcade\\Hyperspin.exe\"
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Run" "Hyperspin" "D:\\Arcade\\Hyperspin.exe\"
WriteRegDWORD HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Run" "Hyperspin" "D:\\Arcade\\Hyperspin.exe\"
But nothing ever shows up in reg.
1) Your installer needs to run as a elevated administrator to write to HKLM. Add RequestExecutionLevel Admin to your script.
2) On 64-bit Windows there are two different views of the registry and by default 32-bit applications write to the HKLM\Software\Wow6432Node key in the "real" registry you see in RegEdit. Use SetRegView in NSIS to write to the 64-bit registry.
I force an uninstall of the previous version prior to installing the new one.
For some reason, it does not work on XP/Vista/10 x64. The uninstall string is blank. I am nearly sure it is looking in the wrong registry. is there a way to force it to check the non wow64 (or vice versa)? I am at a loss as to what else it can possibly be.
# The ExecWait seems not to work on Windows XP x64/Vista x64/10 x64 (it seems to work fine on Vista x64/8 x64)
${If} ${RunningX64}
${GetWindowsVersion} $R0
ReadRegStr $R1 HKLM "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString"
MessageBox MB_OK "You are running $R0 x64! R1 is $R1"
StrCmp $R1 "" no_remove_uninstaller
${Else}
${GetWindowsVersion} $R0
ReadRegStr $R1 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString"
MessageBox MB_OK "You are running $R0 x86! R1 is $R1"
StrCmp $R1 "" no_remove_uninstaller
${EndIf}
MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \
"${PRODUCT_LONG_NAME} is already installed. $\n$\nIf you have software older than XXX 1.3, please manually uninstall it with Windows before proceeding. $\n$\nClick `OK` to remove the \
previous version or `Cancel` to cancel this upgrade." \
IDOK uninst IDCANCEL giveup
giveup:
Abort
# Run the uninstaller
uninst:
ExecWait '"$INSTDIR\uninst.exe" _?=$INSTDIR' $R1
StrCmp $R1 0 no_remove_uninstaller # Success? If so we are done...
Abort # Uninstaller was canceled or failed, we cannot continue
Edited - I removed the x64 functions above. And made the changes you mentioned. Due to the lack of InstallString I used the filefunc getparent function to do the test. Should this do the trick or do I need to still do the regview? It seems to work on XP x86 and 7 x64 though they always had worked. Which made it odd that the in between OSes didn't.
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString"
${GetParent} $0 $R0
IfFileExists "$R0\uninst.exe" 0 no_remove_uninstaller
ExecWait '"$R0\uninst.exe" _?=$R0' $R1
StrCmp 0 $R1 0 giveup
Delete "$R0\uninst.exe"
RMDir "$R0"
Additional Update: It still does not work on Vista x64 and XP x64. Other flavours of Windows all work now.
Last update I think it works now... i swapped regview 64 from 32 since my thinking of what i was doing was reversed.
You code does not make sense.
You are checking for ${RunningX64} but still forcing it to access the 32-bit part of the registry. A 32-bit installer will always read from the 32-bit part of the registry unless you use SetRegView 64.
A bigger problem is that when running the uninstaller of a previous version you must use the previous versions path, not $InstDir! If your old versions write the InstallLocation value you can use that, otherwise you must extract the path from the UninstallString value. The important part is to remember that the previous install might be in a different directory than the one you end up installing to so you must also do some extra cleanup:
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "InstallLocation"
IfFileExists "$0\uninst.exe" 0 no_previous_version
ExecWait '"$0\uninst.exe" _?=$0' $R1
StrCmp 0 $R1 0 uninst_aborted
Delete "$0\uninst.exe"
RMDir "$0"
I'm trying to determine which arquitecture has the OS. I'm using this code:
!include x64.nsh
${If} ${RunningX64}
# 64 bit code
${Else}
# 32 bit code
${EndIf}
But always enters to #32 bit code in spite of I'm executing it on W7 x64 OS.
Try running this:
DetailPrint "NSIS=${NSIS_VERSION}"
System::Call 'kernel32::GetCurrentProcess()i.r0'
DetailPrint "GetCurrentProcess=$0"
System::Call 'kernel32::IsWow64Process(ir0,*i.r1)i.r2?e'
pop $3
DetailPrint "IsWow64Process: ret=$2 gle=$3 result=$1"
On my Win8 x64 OS this gives me:
NSIS=v2.46
GetCurrentProcess=-1
IsWow64Process: ret=1 gle=80 result=1
Why does this script try to install the jre when it doesn't need to? I verified that C:\Windows\System32\java.exe does in fact exist, but this script doesn't see it. The script is targeting XP, Vista, 32 bit, and 64 bit. The script !includes x64.nsh. The reason for the first ElseIf is that the javaw.exe is sometimes installed in C:\Windows\System32\ on 64 bit systems. Is the logic bogus? If so, how? Is the use of C:\Windows\System32\javaw.exe improper?
${If} ${FileExists} `$SYSDIR\javaw.exe`
; Skip JRE install
${ElseIf} ${FileExists} `C:\Windows\System32\javaw.exe`
; Skip JRE install
${ElseIf} ${RunningX64}
ExecWait '"jre-6u22-windows-x64.exe"'
${Else}
ExecWait '"jre-6u22-windows-i586-s.exe"'
${EndIf}
Needed Unless blocks and DisableX64FSRedirection.
${If} ${RunningX64}
${DisableX64FSRedirection}
${Unless} ${FileExists} "$SYSDIR\javaw.exe"
ExecWait '"jre-6u22-windows-x64.exe"'
${EndUnless}
${EnableX64FSRedirection}
${Else}
${Unless} ${FileExists} "$SYSDIR\javaw.exe"
ExecWait '"jre-6u22-windows-i586-s.exe"'
${EndUnless}
${EndIf}