ENH: allow for desktop link to be created and fix chop of last char in PATH on uninstall

This commit is contained in:
Bill Hoffman 2007-09-18 15:16:21 -04:00
parent ec207513e4
commit 0eba9b638f
4 changed files with 213 additions and 172 deletions

View File

@ -42,6 +42,7 @@ IF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
# sure there is at least one set of four (4) backlasshes. # sure there is at least one set of four (4) backlasshes.
SET(CPACK_PACKAGE_ICON "${CMake_SOURCE_DIR}/Utilities/Release\\\\CMakeInstall.bmp") SET(CPACK_PACKAGE_ICON "${CMake_SOURCE_DIR}/Utilities/Release\\\\CMakeInstall.bmp")
SET(CPACK_PACKAGE_EXECUTABLES "CMakeSetup" "CMake") SET(CPACK_PACKAGE_EXECUTABLES "CMakeSetup" "CMake")
SET(CPACK_CREATE_DESKTOP_LINK_CMakeSetup 1)
SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\CMakeSetup.exe") SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\CMakeSetup.exe")
SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} a cross-platform, open-source build system") SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} a cross-platform, open-source build system")
SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.cmake.org") SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\www.cmake.org")

View File

@ -1,5 +1,5 @@
[Settings] [Settings]
NumFields=4 NumFields=5
[Field 1] [Field 1]
Type=label Type=label
@ -35,3 +35,12 @@ Right=-1
Top=50 Top=50
Bottom=60 Bottom=60
State=0 State=0
[Field 5]
Type=CheckBox
Text=Create @CPACK_PACKAGE_NAME@ Desktop Icon
Left=0
Right=-1
Top=80
Bottom=90
State=0

View File

@ -17,6 +17,7 @@
Var DO_NOT_ADD_TO_PATH Var DO_NOT_ADD_TO_PATH
Var ADD_TO_PATH_ALL_USERS Var ADD_TO_PATH_ALL_USERS
Var ADD_TO_PATH_CURRENT_USER Var ADD_TO_PATH_CURRENT_USER
Var INSTALL_DESKTOP
;-------------------------------- ;--------------------------------
;Include Modern UI ;Include Modern UI
@ -122,182 +123,173 @@ FunctionEnd
;---------------------------------------------------- ;----------------------------------------------------
!define NT_current_env 'HKCU "Environment"' !define NT_current_env 'HKCU "Environment"'
!define NT_all_env 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' !define NT_all_env 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
;====================================================
!ifndef WriteEnvStr_RegKey
!ifdef ALL_USERS
!define WriteEnvStr_RegKey \
'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
!else
!define WriteEnvStr_RegKey 'HKCU "Environment"'
!endif
!endif
; AddToPath - Adds the given dir to the search path. ; AddToPath - Adds the given dir to the search path.
; Input - head of the stack ; Input - head of the stack
; Note - Win9x systems requires reboot ; Note - Win9x systems requires reboot
;====================================================
Function AddToPath Function AddToPath
Exch $0 Exch $0
Push $1 Push $1
Push $2 Push $2
Push $3
Call IsNT
Pop $1
StrCmp $1 1 AddToPath_NT
; Not on NT
StrCpy $1 $WINDIR 2
FileOpen $1 "$1\autoexec.bat" a
FileSeek $1 0 END
GetFullPathName /SHORT $0 $0
FileWrite $1 "$\r$\n\
$\r$\n\
SET PATH=%PATH%;$0$\r$\n\
$\r$\n\
"
FileClose $1
Goto AddToPath_done
AddToPath_NT: # don't add if the path doesn't exist
Push $4 IfFileExists "$0\*.*" "" AddToPath_done
Call select_NT_profile
Pop $4
AddToPath_NT_selection_done: ReadEnvStr $1 PATH
StrCmp $4 "current" read_path_NT_current Push "$1;"
ReadRegStr $1 ${NT_all_env} "PATH" Push "$0;"
Goto read_path_NT_resume Call StrStr
read_path_NT_current: Pop $2
ReadRegStr $1 ${NT_current_env} "PATH" StrCmp $2 "" "" AddToPath_done
read_path_NT_resume: Push "$1;"
StrCmp $1 "" AddToPath_NoCurrentPath Push "$0\;"
StrCpy $2 "$0;$1" Call StrStr
Goto AddToPath_NTdoIt Pop $2
AddToPath_NoCurrentPath: StrCmp $2 "" "" AddToPath_done
DetailPrint "No current path, so just use $0" GetFullPathName /SHORT $3 $0
StrCpy $2 $0 Push "$1;"
Goto AddToPath_NTdoIt Push "$3;"
AddToPath_NTdoIt: Call StrStr
StrCmp $4 "current" write_path_NT_current Pop $2
ClearErrors StrCmp $2 "" "" AddToPath_done
WriteRegExpandStr ${NT_all_env} "PATH" $2 Push "$1;"
IfErrors 0 write_path_NT_resume Push "$3\;"
MessageBox MB_YESNO|MB_ICONQUESTION "The path could not be set for all users$\n\ Call StrStr
$\n\ Pop $2
Should I try for the current user?" \ StrCmp $2 "" "" AddToPath_done
IDNO write_path_NT_failed
; change selection Call IsNT
StrCpy $4 "current" Pop $1
Goto AddToPath_NT_selection_done StrCmp $1 1 AddToPath_NT
write_path_NT_current: ; Not on NT
ClearErrors StrCpy $1 $WINDIR 2
WriteRegExpandStr ${NT_current_env} "PATH" $2 FileOpen $1 "$1\autoexec.bat" a
IfErrors 0 write_path_NT_resume FileSeek $1 -1 END
MessageBox MB_OK|MB_ICONINFORMATION "The path could not be set for the current user." FileReadByte $1 $2
Goto write_path_NT_failed IntCmp $2 26 0 +2 +2 # DOS EOF
write_path_NT_resume: FileSeek $1 -1 END # write over EOF
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 FileWrite $1 "$\r$\nSET PATH=%PATH%;$3$\r$\n"
DetailPrint "Added path for user ($4), $0" FileClose $1
DetailPrint "New path is: $2" SetRebootFlag true
write_path_NT_failed: Goto AddToPath_done
Pop $4 AddToPath_NT:
AddToPath_done: ReadRegStr $1 ${WriteEnvStr_RegKey} "PATH"
Pop $2 StrCmp $1 "" AddToPath_NTdoIt
Pop $1 Push $1
Pop $0 Call Trim
Pop $1
StrCpy $0 "$1;$0"
AddToPath_NTdoIt:
WriteRegExpandStr ${WriteEnvStr_RegKey} "PATH" $0
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
AddToPath_done:
Pop $3
Pop $2
Pop $1
Pop $0
FunctionEnd FunctionEnd
;====================================================
; RemoveFromPath - Remove a given dir from the path ; RemoveFromPath - Remove a given dir from the path
; Input: head of the stack ; Input: head of the stack
;====================================================
Function un.RemoveFromPath Function un.RemoveFromPath
Exch $0 Exch $0
Push $1 Push $1
Push $2 Push $2
Push $3 Push $3
Push $4 Push $4
Push $5
Call un.IsNT Push $6
Pop $1
StrCmp $1 1 unRemoveFromPath_NT IntFmt $6 "%c" 26 # DOS EOF
; Not on NT
StrCpy $1 $WINDIR 2 Call un.IsNT
FileOpen $1 "$1\autoexec.bat" r Pop $1
GetTempFileName $4 StrCmp $1 1 unRemoveFromPath_NT
FileOpen $2 $4 w ; Not on NT
GetFullPathName /SHORT $0 $0 StrCpy $1 $WINDIR 2
StrCpy $0 "SET PATH=%PATH%;$0" FileOpen $1 "$1\autoexec.bat" r
SetRebootFlag true GetTempFileName $4
FileOpen $2 $4 w
GetFullPathName /SHORT $0 $0
StrCpy $0 "SET PATH=%PATH%;$0"
Goto unRemoveFromPath_dosLoop
unRemoveFromPath_dosLoop:
FileRead $1 $3
StrCpy $5 $3 1 -1 # read last char
StrCmp $5 $6 0 +2 # if DOS EOF
StrCpy $3 $3 -1 # remove DOS EOF so we can compare
StrCmp $3 "$0$\r$\n" unRemoveFromPath_dosLoopRemoveLine
StrCmp $3 "$0$\n" unRemoveFromPath_dosLoopRemoveLine
StrCmp $3 "$0" unRemoveFromPath_dosLoopRemoveLine
StrCmp $3 "" unRemoveFromPath_dosLoopEnd
FileWrite $2 $3
Goto unRemoveFromPath_dosLoop Goto unRemoveFromPath_dosLoop
unRemoveFromPath_dosLoopRemoveLine:
unRemoveFromPath_dosLoop: SetRebootFlag true
FileRead $1 $3 Goto unRemoveFromPath_dosLoop
StrCmp $3 "$0$$\r$\n\
$\r$\n\
" unRemoveFromPath_dosLoop
StrCmp $3 "$0$\r$\n\
" unRemoveFromPath_dosLoop
StrCmp $3 "$0" unRemoveFromPath_dosLoop
StrCmp $3 "" unRemoveFromPath_dosLoopEnd
FileWrite $2 $3
Goto unRemoveFromPath_dosLoop
unRemoveFromPath_dosLoopEnd: unRemoveFromPath_dosLoopEnd:
FileClose $2 FileClose $2
FileClose $1 FileClose $1
StrCpy $1 $WINDIR 2 StrCpy $1 $WINDIR 2
Delete "$1\autoexec.bat" Delete "$1\autoexec.bat"
CopyFiles /SILENT $4 "$1\autoexec.bat" CopyFiles /SILENT $4 "$1\autoexec.bat"
Delete $4 Delete $4
Goto unRemoveFromPath_done Goto unRemoveFromPath_done
unRemoveFromPath_NT: unRemoveFromPath_NT:
StrLen $2 $0 ReadRegStr $1 ${WriteEnvStr_RegKey} "PATH"
Call un.select_NT_profile StrCpy $5 $1 1 -1 # copy last char
Pop $4 StrCmp $5 ";" +2 # if last char != ;
StrCpy $1 "$1;" # append ;
Push $1
Push "$0;"
Call un.StrStr ; Find `$0;` in $1
Pop $2 ; pos of our dir
StrCmp $2 "" unRemoveFromPath_done
; else, it is in path
# $0 - path to add
# $1 - path var
StrLen $3 "$0;"
StrLen $4 $2
StrCpy $5 $1 -$4 # $5 is now the part before the path to remove
StrCpy $6 $2 "" $3 # $6 is now the part after the path to remove
StrCpy $3 $5$6
StrCmp $4 "current" un_read_path_NT_current StrCpy $5 $3 1 -1 # copy last char
ReadRegStr $1 ${NT_all_env} "PATH" StrCmp $5 ";" 0 +2 # if last char == ;
Goto un_read_path_NT_resume StrCpy $3 $3 -1 # remove last char
un_read_path_NT_current:
ReadRegStr $1 ${NT_current_env} "PATH"
un_read_path_NT_resume:
StrCpy $8 $0 WriteRegExpandStr ${WriteEnvStr_RegKey} "PATH" $3
Push $1 SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
Push $0
Call un.StrStr ; Find $0 in $1
Pop $0 ; pos of our dir
IntCmp $0 -1 unRemoveFromPath_done
; else, it is in path
StrLen $5 $1 ; Get the length of the original path
StrLen $6 $0 ; get the length of path without the first path
IntOp $5 $5 - $6
IntOp $5 $5 - 1
IntCmp $5 -1 unRemoveFromPath_nothingBefore
StrCpy $3 $1 $5 ; $3 now has the part of the path before our dir
Goto unRemoveFromPath_AfterBefore
unRemoveFromPath_nothingBefore:
StrCpy $3 ""
unRemoveFromPath_AfterBefore:
StrCpy $7 $0 "" $2 ; $3 now has the part of the path after our dir
StrCpy $3 "$3$7"
; $3 now holds path, but there may be some stray semicolon at
; beginning. Let's remove it
StrCpy $7 $3 1
StrCmp $7 ";" 0 unRemoveFromPath_NoTrailingSemiColon
StrCpy $3 $3 "" 1
unRemoveFromPath_NoTrailingSemiColon:
StrCmp $4 "current" un_write_path_NT_current unRemoveFromPath_done:
WriteRegExpandStr ${NT_all_env} "PATH" $3 Pop $6
Goto un_write_path_NT_resume Pop $5
un_write_path_NT_current: Pop $4
WriteRegExpandStr ${NT_current_env} "PATH" $3 Pop $3
un_write_path_NT_resume: Pop $2
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 Pop $1
DetailPrint "Removed $8 from the path" Pop $0
DetailPrint "New path is: $3"
unRemoveFromPath_done:
Pop $4
Pop $3
Pop $2
Pop $1
Pop $0
FunctionEnd FunctionEnd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Uninstall sutff ; Uninstall sutff
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -385,6 +377,24 @@ FunctionEnd
!insertmacro StrStr "" !insertmacro StrStr ""
!insertmacro StrStr "un." !insertmacro StrStr "un."
Function Trim ; Added by Pelaca
Exch $R1
Push $R2
Loop:
StrCpy $R2 "$R1" 1 -1
StrCmp "$R2" " " RTrim
StrCmp "$R2" "$\n" RTrim
StrCmp "$R2" "$\r" RTrim
StrCmp "$R2" ";" RTrim
GoTo Done
RTrim:
StrCpy $R1 "$R1" -1
Goto Loop
Done:
Pop $R2
Exch $R1
FunctionEnd
Function ConditionalAddToRegisty Function ConditionalAddToRegisty
Pop $0 Pop $0
Pop $1 Pop $1
@ -443,17 +453,6 @@ FunctionEnd
;-------------------------------- ;--------------------------------
;Installer Sections ;Installer Sections
Section "Add to path"
Push $INSTDIR\bin
;Read a value from an InstallOptions INI file
!insertmacro MUI_INSTALLOPTIONS_READ $DO_NOT_ADD_TO_PATH "NSIS.InstallOptions.ini" "Field 2" "State"
!insertmacro MUI_INSTALLOPTIONS_READ $ADD_TO_PATH_ALL_USERS "NSIS.InstallOptions.ini" "Field 3" "State"
!insertmacro MUI_INSTALLOPTIONS_READ $ADD_TO_PATH_CURRENT_USER "NSIS.InstallOptions.ini" "Field 4" "State"
StrCmp $DO_NOT_ADD_TO_PATH "1" doNotAddToPath 0
Call AddToPath
doNotAddToPath:
SectionEnd
Section "Installer Section" InstSection Section "Installer Section" InstSection
;Use the entire tree produced by the INSTALL target. Keep the ;Use the entire tree produced by the INSTALL target. Keep the
@ -492,9 +491,9 @@ Section "Installer Section" InstSection
Push "Contact" Push "Contact"
Push "@CPACK_NSIS_CONTACT@" Push "@CPACK_NSIS_CONTACT@"
Call ConditionalAddToRegisty Call ConditionalAddToRegisty
!insertmacro MUI_INSTALLOPTIONS_READ $INSTALL_DESKTOP "NSIS.InstallOptions.ini" "Field 5" "State"
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
;Create shortcuts ;Create shortcuts
CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER" CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER"
@CPACK_NSIS_CREATE_ICONS@ @CPACK_NSIS_CREATE_ICONS@
@ -513,6 +512,9 @@ Section "Installer Section" InstSection
Push "AddToPathCurrentUser" Push "AddToPathCurrentUser"
Push "$ADD_TO_PATH_CURRENT_USER" Push "$ADD_TO_PATH_CURRENT_USER"
Call ConditionalAddToRegisty Call ConditionalAddToRegisty
Push "InstallToDesktop"
Push "$INSTALL_DESKTOP"
Call ConditionalAddToRegisty
@CPACK_NSIS_EXTRA_INSTALL_COMMANDS@ @CPACK_NSIS_EXTRA_INSTALL_COMMANDS@
@ -520,6 +522,18 @@ Section "Installer Section" InstSection
SectionEnd SectionEnd
Section "Add to path"
Push $INSTDIR\bin
;Read a value from an InstallOptions INI file
!insertmacro MUI_INSTALLOPTIONS_READ $DO_NOT_ADD_TO_PATH "NSIS.InstallOptions.ini" "Field 2" "State"
!insertmacro MUI_INSTALLOPTIONS_READ $ADD_TO_PATH_ALL_USERS "NSIS.InstallOptions.ini" "Field 3" "State"
!insertmacro MUI_INSTALLOPTIONS_READ $ADD_TO_PATH_CURRENT_USER "NSIS.InstallOptions.ini" "Field 4" "State"
StrCmp $DO_NOT_ADD_TO_PATH "1" doNotAddToPath 0
Call AddToPath
doNotAddToPath:
SectionEnd
;-------------------------------- ;--------------------------------
; Create custom pages ; Create custom pages
Function InstallOptionsPage Function InstallOptionsPage
@ -567,6 +581,9 @@ Section "Uninstall"
ReadRegStr $ADD_TO_PATH_CURRENT_USER SHCTX \ ReadRegStr $ADD_TO_PATH_CURRENT_USER SHCTX \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_DIRECTORY@" "AddToPathCurrentUser" "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_DIRECTORY@" "AddToPathCurrentUser"
;MessageBox MB_OK "Add to path: $DO_NOT_ADD_TO_PATH all users: $ADD_TO_PATH_ALL_USERS" ;MessageBox MB_OK "Add to path: $DO_NOT_ADD_TO_PATH all users: $ADD_TO_PATH_ALL_USERS"
ReadRegStr $INSTALL_DESKTOP SHCTX \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_DIRECTORY@" "InstallToDesktop"
;MessageBox MB_OK "Install to desktop: $INSTALL_DESKTOP "
@CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS@ @CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS@

View File

@ -241,6 +241,20 @@ int cmCPackNSISGenerator::InitializeInternal()
<< std::endl; << std::endl;
deleteStr << " Delete \"$SMPROGRAMS\\$MUI_TEMP\\" << linkName deleteStr << " Delete \"$SMPROGRAMS\\$MUI_TEMP\\" << linkName
<< ".lnk\"" << std::endl; << ".lnk\"" << std::endl;
// see if CPACK_CREATE_DESKTOP_LINK_ExeName is on
// if so add a desktop link
std::string desktop = "CPACK_CREATE_DESKTOP_LINK_";
desktop += execName;
if(this->IsSet(desktop.c_str()))
{
str << " StrCmp \"$INSTALL_DESKTOP\" \"1\" 0 +2\n";
str << " CreateShortCut \"$DESKTOP\\"
<< linkName << ".lnk\" \"$INSTDIR\\bin\\" << execName << ".exe\""
<< std::endl;
deleteStr << " StrCmp \"$INSTALL_DESKTOP\" \"1\" 0 +2\n";
deleteStr << " Delete \"$DESKTOP\\" << linkName
<< ".lnk\"" << std::endl;
}
} }
this->SetOptionIfNotSet("CPACK_NSIS_CREATE_ICONS", str.str().c_str()); this->SetOptionIfNotSet("CPACK_NSIS_CREATE_ICONS", str.str().c_str());
this->SetOptionIfNotSet("CPACK_NSIS_DELETE_ICONS", this->SetOptionIfNotSet("CPACK_NSIS_DELETE_ICONS",