-
Notifications
You must be signed in to change notification settings - Fork 168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compare registry values to $INSTDIR
before removing keys
#684
Changes from all commits
2171748
a80b364
fa2040b
e6b0ce9
58a7b89
009f843
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -66,6 +66,8 @@ Unicode "true" | |
\Uninstall\${UNINSTALL_NAME}" | ||
|
||
var /global INSTDIR_JUSTME | ||
var /global INSTALLER_VERSION | ||
var /global INSTALLER_NAME_FULL | ||
|
||
# UAC shield overlay | ||
!ifndef BCM_SETSHIELD | ||
|
@@ -1201,10 +1203,36 @@ Section "Uninstall" | |
# carefully. More info at https://docs.conda.io/projects/conda/en/latest/user-guide/troubleshooting.html#solution | ||
System::Call 'kernel32::SetEnvironmentVariable(t,t)i("CONDA_DLL_SEARCH_MODIFICATION_ENABLE", "1").r0' | ||
|
||
# Read variables the uninstaller needs from the registry | ||
StrCpy $R0 "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" | ||
StrLen $R1 "Uninstall-${NAME}.exe" | ||
IntOp $R1 $R1 + 3 | ||
StrCpy $0 0 | ||
loop_path: | ||
EnumRegKey $1 SHCTX $R0 $0 | ||
StrCmp $1 "" endloop_path | ||
StrCpy $2 "$R0\$1" | ||
ReadRegStr $4 SHCTX $2 "UninstallString" | ||
StrLen $5 $4 | ||
IntOp $5 $5 - $R1 | ||
StrCpy $4 $4 $5 1 | ||
${If} $4 == $INSTDIR | ||
StrCpy $INSTALLER_NAME_FULL $1 | ||
ReadRegStr $INSTALLER_VERSION SHCTX $2 "DisplayVersion" | ||
goto endloop_path | ||
${EndIf} | ||
IntOp $0 $0 + 1 | ||
goto loop_path | ||
endloop_path: | ||
|
||
# Extra info for pre_uninstall scripts | ||
System::Call 'kernel32::SetEnvironmentVariable(t,t)i("PREFIX", "$INSTDIR").r0' | ||
System::Call 'kernel32::SetEnvironmentVariable(t,t)i("INSTALLER_NAME", "${NAME}").r0' | ||
System::Call 'kernel32::SetEnvironmentVariable(t,t)i("INSTALLER_VER", "${VERSION}").r0' | ||
StrCpy $0 ${VERSION} | ||
${If} $INSTALLER_VERSION != "" | ||
StrCpy $0 $INSTALLER_VERSION | ||
${EndIf} | ||
System::Call 'kernel32::SetEnvironmentVariable(t,t)i("INSTALLER_VER", "$0").r0' | ||
System::Call 'kernel32::SetEnvironmentVariable(t,t)i("INSTALLER_PLAT", "${PLATFORM}").r0' | ||
System::Call 'kernel32::SetEnvironmentVariable(t,t)i("INSTALLER_TYPE", "EXE").r0' | ||
|
||
|
@@ -1218,13 +1246,26 @@ Section "Uninstall" | |
# In case the last command fails, run the slow method to remove leftover | ||
RMDir /r /REBOOTOK "$INSTDIR" | ||
|
||
DeleteRegKey SHCTX "${UNINSTREG}" | ||
${If} $INSTALLER_NAME_FULL != "" | ||
DeleteRegKey SHCTX "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$INSTALLER_NAME_FULL" | ||
${EndIf} | ||
|
||
# If Anaconda was registered as the official Python for this version, | ||
# remove it from the registry | ||
ReadRegStr $0 SHCTX "Software\Python\PythonCore\${PY_VER}\InstallPath" "" | ||
${If} $0 == "$INSTDIR" | ||
DeleteRegKey SHCTX "Software\Python\PythonCore\${PY_VER}" | ||
${EndIf} | ||
StrCpy $R0 "SOFTWARE\Python\PythonCore" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This block is easier to understand, I think. Basically we don't want to assume that the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This also prevents issues in cross-installer usage, as described in my other comment. I do not think that |
||
StrCpy $0 0 | ||
loop_py: | ||
EnumRegKey $1 SHCTX $R0 $0 | ||
StrCmp $1 "" endloop_py | ||
ReadRegStr $2 SHCTX "$R0\$1\InstallPath" "" | ||
${If} $2 == $INSTDIR | ||
StrCpy $R1 $1 | ||
DeleteRegKey SHCTX "$R0\$1" | ||
goto endloop_py | ||
${EndIf} | ||
IntOp $0 $0 + 1 | ||
goto loop_py | ||
endloop_py: | ||
SectionEnd | ||
|
||
!if '@SIGNTOOL_COMMAND@' != '' | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
### Enhancements | ||
|
||
* The Windows uninstaller will check the registry for `$INSTDIR` before deleting hardcoded registry keys (#684) | ||
|
||
### Bug fixes | ||
|
||
* <news item> | ||
|
||
### Deprecations | ||
|
||
* <news item> | ||
|
||
### Docs | ||
|
||
* <news item> | ||
|
||
### Other | ||
|
||
* <news item> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand this correctly, this block will search the registry for two variables:
These were previously assumed to be constant and would have used the hardcoded values at install time (
${NAME}
[used in line 65] and${VERSION}
, respectively).However we are now saying that this might not be always the case. Could you elaborate under what circumstances this is true? e.g. updating Anaconda in place but not updating the registry keys (or not deleting the old ones before adding the new ones)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this logic allows the uninstaller to run for other conda installations if needed, I don't know if that's a bug or a feature 😬
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is already possible. The changes in this PR will, however, conduct checks to make sure the deletion is performed consistently on the file system and the registry.
There is another, admittedly nice, application: if you install the same Miniconda/Miniforge version twice, installation 2 will overwrite the registry keys of number 1. If you then run the uninstaller of number 1, it will delete the keys of number 2.