From b9dfb9483572de66ead91715e2c5ce90988ac879 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Thu, 28 Dec 2017 15:41:47 -0500 Subject: [PATCH] Fetch the Blender install from MSI registry Somewhere around Blender 2.75, the SCONS build system was removed and CMake reigned supreme. The installer was of course changed to a Windows Installer generated by CPack. Unfortunately for us, the registry keys changed. Windows Installer's registry stuff sucks, but this is the easiest way for us to get at it. --- installer/Installer.nsi | 81 +++++++++++++++++++++--------------- installer/RegGuid.nsh | 91 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+), 34 deletions(-) create mode 100644 installer/RegGuid.nsh diff --git a/installer/Installer.nsi b/installer/Installer.nsi index 2b342d1..8b96969 100644 --- a/installer/Installer.nsi +++ b/installer/Installer.nsi @@ -4,10 +4,7 @@ !include MUI2.nsh !include WinVer.nsh !include x64.nsh -!include StrFunc.nsh - -; Enable StrStr -${StrStr} +!include RegGuid.nsh ;;;;;;;;;;;;;;;;;;;;;; ; Installer Settings ; @@ -43,7 +40,12 @@ VIProductVersion "0.0.0.0" ;;;;;;;;;;;;; ; Variables ; ;;;;;;;;;;;;; +!define BlenderUpgradeCode "B767E4FD-7DE7-4094-B051-3AE62E13A17A" +!define UninstallRegKey "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" +!define UpgradeRegKey "SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UpgradeCodes" + Var BlenderDir +Var BlenderDirScanned Var BlenderVer ;;;;;;;;;;;;;;;;; @@ -98,41 +100,52 @@ FunctionEnd ; Tries to find the Blender directory in the registry. Function FindBlenderDir ; To prevent overwriting user data, we will only do this once - StrCmp $BlenderDir "" 0 done - - ; Try to grab the Blender directory from the default registry... - ReadRegStr $BlenderDir HKLM "Software\BlenderFoundation" "Install_Dir" - ReadRegStr $BlenderVer HKLM "Software\BlenderFoundation" "ShortVersion" - - ; Bad news, old chap, certain x86 Blender versions will write their registry keys to the - ; x64 registry. Dang! It looks like we will have to try to hack around that. But only if - ; we got nothing... + StrCmp $BlenderDirScanned "" 0 done + StrCpy $BlenderDirScanned "true" + + StrCpy $1 "" + find_product_code: + ; Blender's CPack-generated MSI package has spewed mess into hidden registry keys. + ; We know what the upgrade guid is, so we will use that to find the install directory + ; and the Blender version. + ${MangleGuidForRegistry} ${BlenderUpgradeCode} $0 + EnumRegValue $0 HKLM "${UpgradeRegKey}\$0" 0 + + ; If we are on a 64-bit system, we might not have found the product code guid in the 32-bit registry + ; ergo, we will need to change over to that registry ${If} ${RunningX64} - StrCmp $BlenderDir "" try_again winning - - try_again: - SetRegView 64 - ReadRegStr $BlenderDir HKLM "Software\BlenderFoundation" "Install_Dir" - ReadRegStr $BlenderVer HKLM "Software\BlenderFoundation" "ShortVersion" - SetRegView 32 - - StrCmp $BlenderDir "" total_phailure - - ; Before we suggest this, let's make sure it's not Program Files (x64) version unleashed(TM) - StrCpy $0 "$PROGRAMFILES64\" ; Otherwise, it would match ALL Program Files directories... - ${StrStr} $1 $BlenderDir $0 - StrCmp $1 "" winning total_phailure + IfErrors 0 find_uninstall_info + StrCmp $1 "" 0 done + StrCpy $1 "DEADBEEF" + + ClearErrors + SetRegView 64 + Goto find_product_code + ${Else} + Goto done ${EndIf} - winning: - StrCpy $INSTDIR "$BlenderDir\$BlenderVer" - Goto done - - total_phailure: - StrCpy $INSTDIR "" - Goto done + find_uninstall_info: + ; Read the Blender directory and the versions from the uninstall record + ${UnmangleGuidFromRegistry} $0 $1 + StrCpy $0 "${UninstallRegKey}\{$1}" + ReadRegStr $BlenderDir HKLM $0 "InstallLocation" + IfErrors done + ReadRegDWORD $1 HKLM $0 "VersionMajor" + ReadRegDWORD $2 HKLM $0 "VersionMinor" + StrCpy $BlenderVer "$1.$2" + + ; Test our detected schtuff for validity + ; NOTE: Windows Installer puts a trailing slash on the end of directories! + StrCpy $3 "$BlenderDir$BlenderVer" + IfFileExists "$3\*.*" 0 done + StrCpy $INSTDIR $3 done: + ClearErrors + ${If} ${RunningX64} + SetRegView 32 + ${EndIf} FunctionEnd ;;;;;;;;; diff --git a/installer/RegGuid.nsh b/installer/RegGuid.nsh new file mode 100644 index 0000000..d07ce10 --- /dev/null +++ b/installer/RegGuid.nsh @@ -0,0 +1,91 @@ +!macro StrAppendChar src_str src_idx dst_str + Push $R0 + StrCpy $R0 ${src_str} 1 ${src_idx} + StrCpy ${dst_str} ${dst_str}$R0 + Pop $R0 +!macroend +!define StrAppendChar `!insertmacro StrAppendChar` + +; Takes a Guid string and returns the mangled form found in Windows Installer registry values +; Input MUST contain dashes but no brackets enclosing the guid +!macro MangleGuidForRegistry src dst + StrCpy ${dst} "" + ${StrAppendChar} ${src} 7 ${dst} + ${StrAppendChar} ${src} 6 ${dst} + ${StrAppendChar} ${src} 5 ${dst} + ${StrAppendChar} ${src} 4 ${dst} + ${StrAppendChar} ${src} 3 ${dst} + ${StrAppendChar} ${src} 2 ${dst} + ${StrAppendChar} ${src} 1 ${dst} + ${StrAppendChar} ${src} 0 ${dst} + ; Dash + ${StrAppendChar} ${src} 12 ${dst} + ${StrAppendChar} ${src} 11 ${dst} + ${StrAppendChar} ${src} 10 ${dst} + ${StrAppendChar} ${src} 9 ${dst} + ; Dash + ${StrAppendChar} ${src} 17 ${dst} + ${StrAppendChar} ${src} 16 ${dst} + ${StrAppendChar} ${src} 15 ${dst} + ${StrAppendChar} ${src} 14 ${dst} + ; Dash + ${StrAppendChar} ${src} 20 ${dst} + ${StrAppendChar} ${src} 19 ${dst} + ${StrAppendChar} ${src} 22 ${dst} + ${StrAppendChar} ${src} 21 ${dst} + ; Dash + ${StrAppendChar} ${src} 25 ${dst} + ${StrAppendChar} ${src} 24 ${dst} + ${StrAppendChar} ${src} 27 ${dst} + ${StrAppendChar} ${src} 26 ${dst} + ${StrAppendChar} ${src} 29 ${dst} + ${StrAppendChar} ${src} 28 ${dst} + ${StrAppendChar} ${src} 31 ${dst} + ${StrAppendChar} ${src} 30 ${dst} + ${StrAppendChar} ${src} 33 ${dst} + ${StrAppendChar} ${src} 32 ${dst} + ${StrAppendChar} ${src} 35 ${dst} + ${StrAppendChar} ${src} 34 ${dst} +!macroend +!define MangleGuidForRegistry `!insertmacro MangleGuidForRegistry` + +!macro UnmangleGuidFromRegistry src dst + StrCpy ${dst} "" + ${StrAppendChar} ${src} 7 ${dst} + ${StrAppendChar} ${src} 6 ${dst} + ${StrAppendChar} ${src} 5 ${dst} + ${StrAppendChar} ${src} 4 ${dst} + ${StrAppendChar} ${src} 3 ${dst} + ${StrAppendChar} ${src} 2 ${dst} + ${StrAppendChar} ${src} 1 ${dst} + ${StrAppendChar} ${src} 0 ${dst} + ${StrAppendChar} "-" 0 ${dst} + ${StrAppendChar} ${src} 11 ${dst} + ${StrAppendChar} ${src} 10 ${dst} + ${StrAppendChar} ${src} 9 ${dst} + ${StrAppendChar} ${src} 8 ${dst} + ${StrAppendChar} "-" 0 ${dst} + ${StrAppendChar} ${src} 15 ${dst} + ${StrAppendChar} ${src} 14 ${dst} + ${StrAppendChar} ${src} 13 ${dst} + ${StrAppendChar} ${src} 12 ${dst} + ${StrAppendChar} "-" 0 ${dst} + ${StrAppendChar} ${src} 17 ${dst} + ${StrAppendChar} ${src} 16 ${dst} + ${StrAppendChar} ${src} 19 ${dst} + ${StrAppendChar} ${src} 18 ${dst} + ${StrAppendChar} "-" 0 ${dst} + ${StrAppendChar} ${src} 21 ${dst} + ${StrAppendChar} ${src} 20 ${dst} + ${StrAppendChar} ${src} 23 ${dst} + ${StrAppendChar} ${src} 22 ${dst} + ${StrAppendChar} ${src} 25 ${dst} + ${StrAppendChar} ${src} 24 ${dst} + ${StrAppendChar} ${src} 27 ${dst} + ${StrAppendChar} ${src} 26 ${dst} + ${StrAppendChar} ${src} 29 ${dst} + ${StrAppendChar} ${src} 28 ${dst} + ${StrAppendChar} ${src} 31 ${dst} + ${StrAppendChar} ${src} 30 ${dst} +!macroend +!define UnmangleGuidFromRegistry `!insertmacro UnmangleGuidFromRegistry`