Code

installer remembers installed files and uninstaller does not delete user files
authortheadib <theadib@users.sourceforge.net>
Fri, 15 Jun 2007 22:15:35 +0000 (22:15 +0000)
committertheadib <theadib@users.sourceforge.net>
Fri, 15 Jun 2007 22:15:35 +0000 (22:15 +0000)
packaging/win32/AdvUninstLog.nsh [new file with mode: 0644]
packaging/win32/AdvUninstLog.txt [new file with mode: 0644]
packaging/win32/inkscape.nsi

diff --git a/packaging/win32/AdvUninstLog.nsh b/packaging/win32/AdvUninstLog.nsh
new file mode 100644 (file)
index 0000000..2b5b5c7
--- /dev/null
@@ -0,0 +1,437 @@
+     ;_____________________________ HEADER FILE BEGIN ____________________________\r
+\r
+     # Advanced Uninstall Log NSIS header\r
+     # Version 1.0 2007-01-31\r
+     # By Red Wine (http://nsis.sf.net/User:Red_Wine)\r
+     \r
+     # Usage: See included examples Uninstall_Log_Default_UI.nsi - Uninstall_Log_Modern_UI.nsi\r
+\r
+!verbose push\r
+   !verbose 3\r
+\r
+!ifndef ADVANCED_UNINSTALL.LOG_NSH\r
+   !define ADVANCED_UNINSTALL.LOG_NSH\r
+\r
+!ifndef INSTDIR_REG_ROOT | INSTDIR_REG_KEY\r
+   !error "You must properly define both INSTDIR_REG_ROOT and INSTDIR_REG_KEY"\r
+!endif\r
+\r
+!ifndef UNINSTALL_LOG\r
+   !define UNINSTALL_LOG         "Uninstall"\r
+!endif\r
+\r
+!ifndef UNINST_LOG_VERBOSE\r
+   !define UNINST_LOG_VERBOSE    "3"\r
+!endif\r
+\r
+!verbose pop\r
+\r
+!echo "Advanced Uninstall Log NSIS header v1.0 2007-01-31 by Red Wine (http://nsis.sf.net/User:Red_Wine)"\r
+\r
+!verbose push\r
+   !verbose ${UNINST_LOG_VERBOSE}\r
+\r
+!define UNINST_EXE     "$INSTDIR\${UNINSTALL_LOG}.exe"\r
+!define UNINST_DAT     "$INSTDIR\${UNINSTALL_LOG}.dat"\r
+!define UNLOG_PART     "$PLUGINSDIR\part."\r
+!define UNLOG_TEMP     "$PLUGINSDIR\unlog.tmp"\r
+!define EXCLU_LIST     "$PLUGINSDIR\exclude.tmp"\r
+!define UNLOG_HEAD     "=========== Uninstaller Log please do not edit this file ==========="\r
+\r
+ var unlog_tmp_0\r
+ var unlog_tmp_1\r
+ var unlog_tmp_2\r
+ var unlog_tmp_3\r
+ var unlog_error\r
+\r
+!include FileFunc.nsh\r
+!include TextFunc.nsh\r
+\r
+!insertmacro Locate\r
+!insertmacro un.Locate\r
+!insertmacro DirState\r
+!insertmacro un.DirState\r
+!insertmacro FileJoin\r
+!insertmacro TrimNewLines\r
+!insertmacro un.TrimNewLines\r
+\r
+;.............................. Uninstaller Macros ..............................\r
+\r
+!macro UNINSTALL.LOG_BEGIN_UNINSTALL\r
+  !verbose push\r
+     !verbose ${UNINST_LOG_VERBOSE}\r
+\r
+        IfFileExists "${UNINST_DAT}" +3\r
+        MessageBox MB_ICONSTOP|MB_OK "${UNINST_DAT} not found, unable to perform uninstall." /SD IDOK\r
+        Quit\r
+\r
+        StrCmp "$PLUGINSDIR" "" 0 +2\r
+           InitPluginsDir\r
+\r
+        CopyFiles "${UNINST_DAT}" "${UNLOG_TEMP}"\r
+        FileOpen $unlog_tmp_2 "${UNLOG_TEMP}" r\r
+\r
+  !verbose pop\r
+!macroend\r
+\r
+\r
+!macro UNINSTALL.LOG_END_UNINSTALL\r
+  !verbose push\r
+     !verbose ${UNINST_LOG_VERBOSE}\r
+\r
+        FileClose $unlog_tmp_2\r
+        DeleteRegValue ${INSTDIR_REG_ROOT} "${INSTDIR_REG_KEY}" "${UNINSTALL_LOG}.dat"\r
+        DeleteRegValue ${INSTDIR_REG_ROOT} "${INSTDIR_REG_KEY}" "${UNINSTALL_LOG}Directory"\r
+\r
+  !verbose pop\r
+!macroend\r
+\r
+\r
+!macro UNINSTALL.LOG_UNINSTALL TargetDir\r
+  !verbose push\r
+     !verbose ${UNINST_LOG_VERBOSE}\r
+\r
+     !ifndef INTERACTIVE_UNINSTALL & UNATTENDED_UNINSTALL\r
+        !error "You must insert either Interactive or Unattended Uninstall neither both, neither none."\r
+     !endif\r
+\r
+     !ifdef INTERACTIVE_UNINSTALL\r
+        GetTempFileName $unlog_tmp_5 "$PLUGINSDIR"\r
+        FileOpen $unlog_tmp_4 "$unlog_tmp_5" a\r
+     !endif\r
+\r
+        ${PerfomUninstall} "${TargetDir}" "${UnLog_Uninstall_CallBackFunc}"\r
+\r
+     !ifdef INTERACTIVE_UNINSTALL\r
+        FileClose $unlog_tmp_4\r
+     !endif\r
+\r
+  !verbose pop\r
+!macroend\r
+\r
+\r
+!define PerfomUninstall "!insertmacro PERFORMUNINSTALL"\r
+\r
+!macro PERFORMUNINSTALL TargetDir UninstCallBackFunc\r
+  !verbose push\r
+     !verbose ${UNINST_LOG_VERBOSE}\r
+\r
+   !define ID ${__LINE__}\r
+\r
+       ${un.Locate} "${TargetDir}" "/L=F" "${UninstCallBackFunc}"\r
+\r
+    loop_${ID}:\r
+\r
+       StrCpy $unlog_tmp_1 0\r
+\r
+       ${un.Locate} "${TargetDir}" "/L=DE" "${UninstCallBackFunc}"\r
+       StrCmp $unlog_tmp_1 "0" 0 loop_${ID}\r
+\r
+        ${un.DirState} "${TargetDir}" $unlog_tmp_0\r
+        StrCmp "$unlog_tmp_0" "0" 0 +2\r
+        RmDir "${TargetDir}"\r
+\r
+       IfErrors 0 +2\r
+       MessageBox MB_ICONEXCLAMATION|MB_OK "${UNINSTALL_LOG} Log error" /SD IDOK\r
+\r
+   !undef ID\r
+\r
+  !verbose pop\r
+!macroend\r
+\r
+\r
+!macro INTERACTIVE_UNINSTALL\r
+  !verbose push\r
+     !verbose ${UNINST_LOG_VERBOSE}\r
+     \r
+     !ifdef INTERACTIVE_UNINSTALL\r
+        !error "INTERACTIVE_UNINSTALL is already defined"\r
+     !endif\r
+\r
+        var unlog_tmp_4\r
+        var unlog_tmp_5\r
+\r
+     !define INTERACTIVE_UNINSTALL\r
+\r
+     !ifdef INTERACTIVE_UNINSTALL & UNATTENDED_UNINSTALL\r
+        !error "You must insert either Interactive or Unattended Uninstall neither both, neither none."\r
+     !endif\r
+\r
+     !ifdef UnLog_Uninstall_CallBackFunc\r
+        !undef UnLog_Uninstall_CallBackFunc\r
+     !endif\r
+\r
+     !ifndef UnLog_Uninstall_CallBackFunc\r
+        !insertmacro UNINSTALL.LOG_UNINSTALL_INTERACTIVE\r
+        !define UnLog_Uninstall_CallBackFunc "un._LocateCallBack_Function_Interactive"\r
+     !endif\r
+\r
+  !verbose pop\r
+!macroend\r
+\r
+\r
+!macro UNATTENDED_UNINSTALL\r
+  !verbose push\r
+     !verbose ${UNINST_LOG_VERBOSE}\r
+\r
+     !ifdef UNATTENDED_UNINSTALL\r
+        !error "UNATTENDED_UNINSTALL is already defined"\r
+     !endif\r
+\r
+     !define UNATTENDED_UNINSTALL\r
+\r
+     !ifdef INTERACTIVE_UNINSTALL & UNATTENDED_UNINSTALL\r
+        !error "You must insert either Interactive or Unattended Uninstall neither both, neither none."\r
+     !endif\r
+\r
+     !ifdef UnLog_Uninstall_CallBackFunc\r
+        !undef UnLog_Uninstall_CallBackFunc\r
+     !endif\r
+\r
+     !ifndef UnLog_Uninstall_CallBackFunc\r
+        !insertmacro UNINSTALL.LOG_UNINSTALL_UNATTENDED\r
+        !define UnLog_Uninstall_CallBackFunc "un._LocateCallBack_Function_Unattended"\r
+     !endif\r
+\r
+  !verbose pop\r
+!macroend\r
+\r
+\r
+!macro UNINSTALL.LOG_UNINSTALL_UNATTENDED\r
+\r
+  Function un._LocateCallBack_Function_Unattended\r
+    start:\r
+        FileRead $unlog_tmp_2 "$unlog_tmp_3" ${NSIS_MAX_STRLEN}\r
+        ${un.TrimNewLines} "$unlog_tmp_3" "$unlog_tmp_3"\r
+        StrCmp "$unlog_tmp_3" "$R9" islog\r
+        IfErrors nolog\r
+        goto start\r
+\r
+    islog:\r
+        IfFileExists "$R9\*.*" isdir\r
+\r
+    isfile:\r
+        Delete "$R9"\r
+        goto end\r
+\r
+    isdir:\r
+        RmDir "$R9"\r
+       IntOp $unlog_tmp_1 $unlog_tmp_1 + 1\r
+        goto end\r
+\r
+    nolog:\r
+        ClearErrors\r
+        StrCmp "$R9" "${UNINST_EXE}" isfile\r
+        StrCmp "$R9" "${UNINST_DAT}" isfile\r
+\r
+    end:\r
+        FileSeek $unlog_tmp_2 0 SET\r
+       Push $unlog_tmp_0\r
+  FunctionEnd\r
+\r
+!macroend\r
+\r
+\r
+!macro UNINSTALL.LOG_UNINSTALL_INTERACTIVE\r
+\r
+  Function un._LocateCallBack_Function_Interactive\r
+    start:\r
+        FileRead $unlog_tmp_2 "$unlog_tmp_3" ${NSIS_MAX_STRLEN}\r
+        ${un.TrimNewLines} "$unlog_tmp_3" "$unlog_tmp_3"\r
+        StrCmp "$unlog_tmp_3" "$R9" islog\r
+        IfErrors nolog\r
+        goto start\r
+\r
+    islog:\r
+        IfFileExists "$R9\*.*" isdir\r
+\r
+    isfile:\r
+        Delete "$R9"\r
+        goto end\r
+\r
+    isdir:\r
+        RmDir "$R9"\r
+       IntOp $unlog_tmp_1 $unlog_tmp_1 + 1\r
+        goto end\r
+\r
+    nolog:\r
+        ClearErrors\r
+       FileSeek $unlog_tmp_4 0 SET\r
+    read:\r
+        FileRead $unlog_tmp_4 "$unlog_tmp_3"\r
+        ${un.TrimNewLines} "$unlog_tmp_3" "$unlog_tmp_3"\r
+        StrCmp "$unlog_tmp_3" "$R9" end\r
+        IfErrors +2\r
+        goto read\r
+        ClearErrors \r
+        StrCmp "$R9" "${UNINST_EXE}" isfile\r
+        StrCmp "$R9" "${UNINST_DAT}" isfile\r
+        IfFileExists "$R9\*.*" msgdir\r
+\r
+       MessageBox MB_ICONQUESTION|MB_YESNO \\r
+        'Delete File "$R9"?' /SD IDNO IDYES isfile IDNO nodel\r
+\r
+    msgdir:\r
+        MessageBox MB_ICONQUESTION|MB_YESNO \\r
+        'Delete Directory "$R9"?' /SD IDNO IDYES isdir IDNO nodel\r
+\r
+    nodel:\r
+       FileSeek $unlog_tmp_4 0 END\r
+       FileWrite $unlog_tmp_4 "$R9$\r$\n"\r
+\r
+    end:\r
+        FileSeek $unlog_tmp_2 0 SET\r
+       Push $unlog_tmp_0\r
+  FunctionEnd\r
+\r
+!macroend\r
+\r
+;................................. Installer Macros .................................\r
+\r
+!macro UNINSTALL.LOG_INSTALL_UNATTENDED\r
+\r
+  Function _LocateCallBack_Function_Install\r
+    loop:\r
+        FileRead $unlog_tmp_2 "$unlog_tmp_3" ${NSIS_MAX_STRLEN}\r
+        ${TrimNewLines} "$unlog_tmp_3" "$unlog_tmp_3"\r
+        IfErrors 0 +4\r
+        ClearErrors\r
+        FileSeek $unlog_tmp_2 0 SET\r
+        goto next\r
+        StrCmp "$R9" "$unlog_tmp_3" end\r
+        goto loop\r
+    next:\r
+       FileWrite $unlog_tmp_1 "$R9$\r$\n"\r
+    end:\r
+       Push $unlog_tmp_0\r
+  FunctionEnd\r
+\r
+!macroend\r
+\r
+\r
+!ifdef UnLog_Install_Func_CallBack\r
+    !undef UnLog_Install_Func_CallBack\r
+!endif\r
+\r
+!ifndef UnLog_Install_Func_CallBack\r
+    !insertmacro UNINSTALL.LOG_INSTALL_UNATTENDED\r
+    !define UnLog_Install_Func_CallBack "_LocateCallBack_Function_Install"\r
+!endif\r
+\r
+\r
+!macro UNINSTALL.LOG_PREPARE_INSTALL\r
+  !verbose push\r
+     !verbose ${UNINST_LOG_VERBOSE}\r
+\r
+      Push $0\r
+      Push $1\r
+        ClearErrors\r
+        ReadRegStr "$0"  ${INSTDIR_REG_ROOT} "${INSTDIR_REG_KEY}" "${UNINSTALL_LOG}Directory"\r
+        IfErrors next\r
+        ${DirState} "$0" $1\r
+        StrCmp "$1" "-1" next\r
+        StrCmp "$1" "0" next\r
+        IfFileExists "$0\${UNINSTALL_LOG}.dat" next\r
+        MessageBox MB_ICONEXCLAMATION|MB_OK \\r
+        "Previous installation detected at $0.$\n\\r
+        Required file ${UNINSTALL_LOG}.dat is missing.$\n$\nIt is highly recommended \\r
+        to select an empty directory and perform a fresh installation." /SD IDOK\r
+        StrCpy $unlog_error "error"\r
+\r
+    next:\r
+        ClearErrors\r
+        StrCmp "$PLUGINSDIR" "" 0 +2\r
+           InitPluginsDir\r
+\r
+        GetTempFileName "$1"\r
+        FileOpen $0 "$1" w\r
+        FileWrite $0 "${UNLOG_HEAD}$\r$\n"\r
+        FileClose $0\r
+        Rename "$1" "${UNLOG_TEMP}"\r
+      Pop $1\r
+      Pop $0\r
+\r
+  !verbose pop\r
+!macroend\r
+\r
+\r
+!macro UNINSTALL.LOG_UPDATE_INSTALL\r
+  !verbose push\r
+     !verbose ${UNINST_LOG_VERBOSE}\r
+\r
+        Delete "${UNINST_DAT}"\r
+        Rename "${UNLOG_TEMP}" "${UNINST_DAT}"\r
+        WriteUninstaller "${UNINST_EXE}"\r
+        WriteRegStr ${INSTDIR_REG_ROOT} "${INSTDIR_REG_KEY}" "${UNINSTALL_LOG}.dat" "${UNINST_DAT}"\r
+        WriteRegStr ${INSTDIR_REG_ROOT} "${INSTDIR_REG_KEY}" "${UNINSTALL_LOG}Directory" "$INSTDIR"\r
+\r
+  !verbose pop\r
+!macroend\r
+\r
+\r
+!define uninstall.log_install "!insertmacro UNINSTALL.LOG_INSTALL"\r
+\r
+!macro UNINSTALL.LOG_INSTALL FileOpenWrite FileOpenRead TargetDir\r
+  !verbose push\r
+     !verbose ${UNINST_LOG_VERBOSE}\r
+\r
+       FileOpen $unlog_tmp_1 "${FileOpenWrite}" w\r
+       FileOpen $unlog_tmp_2 "${FileOpenRead}" r\r
+\r
+       ${Locate} "${TargetDir}" "/L=FD" "${UnLog_Install_Func_CallBack}"\r
+\r
+        StrCmp $unlog_error "error" 0 +2\r
+        ClearErrors\r
+\r
+       IfErrors 0 +2\r
+       MessageBox MB_ICONEXCLAMATION|MB_OK "Error creating ${UNINSTALL_LOG} Log." /SD IDOK\r
+\r
+       FileClose $unlog_tmp_1\r
+       FileClose $unlog_tmp_2\r
+\r
+  !verbose pop\r
+!macroend\r
+\r
+\r
+!define uninstall.log_mergeID "!insertmacro UNINSTALL.LOG_MERGE"\r
+\r
+!macro UNINSTALL.LOG_MERGE UnlogPart\r
+  !verbose push\r
+     !verbose ${UNINST_LOG_VERBOSE}\r
+\r
+        ${FileJoin} "${UNLOG_TEMP}" "${UnlogPart}" "${UNLOG_TEMP}"\r
+\r
+  !verbose pop\r
+!macroend\r
+\r
+\r
+!macro UNINSTALL.LOG_OPEN_INSTALL\r
+  !verbose push\r
+     !verbose ${UNINST_LOG_VERBOSE}\r
+\r
+        StrCmp $unlog_error "error" +2\r
+        ${uninstall.log_install} "${EXCLU_LIST}" "${UNINST_DAT}" "$OUTDIR"\r
+\r
+  !verbose pop\r
+!macroend\r
+\r
+\r
+!macro UNINSTALL.LOG_CLOSE_INSTALL\r
+  !verbose push\r
+     !verbose ${UNINST_LOG_VERBOSE}\r
+\r
+   !define ID ${__LINE__}\r
+\r
+        ${uninstall.log_install} "${UNLOG_PART}${ID}" "${EXCLU_LIST}" "$OUTDIR"\r
+        ${uninstall.log_mergeID} "${UNLOG_PART}${ID}"\r
+\r
+   !undef ID ${__LINE__}\r
+\r
+  !verbose pop\r
+!macroend\r
+\r
+!endif\r
+\r
+!verbose pop\r
+     ;_____________________________ HEADER FILE END ____________________________\r
+\r
diff --git a/packaging/win32/AdvUninstLog.txt b/packaging/win32/AdvUninstLog.txt
new file mode 100644 (file)
index 0000000..b92c5ce
--- /dev/null
@@ -0,0 +1,121 @@
+Overview\r
+\r
+Advanced Uninstall Log for NSIS was born in the need to cover a specific gap.\r
+It's been discussed fairly enough that the File /r command is very useful\r
+in cases when developers want to add a huge amount of sub directories and\r
+files, nevertheless it has the disadvantage that such an installation should\r
+be uninstalled with RmDir /r which is risky and removes also data that has\r
+been added/created later within the installation folder.\r
+\r
+\r
+\r
+\r
+About Advanced Uninstall Log.\r
+\r
+Advanced Uninstall Log is a macro system provided in a NSIS header that\r
+is able to monitor an installation and build an uninstall log file which\r
+is used by the uninstaller to uninstall files/directories that have been\r
+added within specific installation blocks.\r
+\r
+This means that files which have been installed outside these blocks,\r
+or added later either by the user or application's activities, ignored\r
+by the uninstaller.\r
+\r
+Moreover files that might exist into the target directory prior the current\r
+installation, ignored as well.\r
+\r
+Advanced Uninstall Log creates an uninstall log that removes only files that\r
+have been installed and optionally interacts with users for every other file\r
+and/or directory has found in installation folder and requires permission to\r
+remove these files/directories.\r
+\r
+It is enhanced as well to support updates, e.g. if the installer later would\r
+update the installation by adding new data, the uninstaller would remove the\r
+new data that has been added by the installer, without bothering users about.\r
+\r
+\r
+\r
+\r
+Features\r
+\r
+If target installation folder exists and contains files and/or directories\r
+they all preserved from being uninstalled.\r
+\r
+Uninstaller removes data that has been added within specific installation\r
+blocks, preserving all other data that has been created/added outside of\r
+these installation blocks. See included examples for details.\r
+\r
+Supports unlimited updates/reinstallations.\r
+\r
+Supports two uninstaller modes. Interactive mode requires confirmation\r
+to remove every other file exept those files that have been installed.\r
+Unattended mode leaves intact every other file without bothering users.\r
+\r
+In case when uninstall log (uninstall.dat) has been removed manually instead\r
+of execute uninstaller, if users attempt to run the installer later, a warning\r
+issued that they should select a new output folder.\r
+\r
+Implements only the included with NSIS release headers FileFunc and TextFunc.\r
+There is no need for external plugins and headers, adds a very small overhead.\r
+\r
+\r
+\r
+\r
+Restrictions\r
+\r
+If uninstall log (uninstall.dat) is missing uninstaller won't execute at all.\r
+\r
+Due to file create - write procedure that is required in order to add/update\r
+the uninstall log (uninstall.dat), restricted users on NT based systems won't \r
+be able to execute the installer.\r
+\r
+\r
+\r
+\r
+Disadvantage\r
+\r
+Since the header does not implement anything else than the common NSIS release,\r
+a delay occurs while builds and reads the uninstall log because it needs to\r
+throw the list several times. Talking for common cases, most likely the delay\r
+won't be noticeable, however, in cases where the target directory isn't empty\r
+and contains a large amount of data which will be excluded from uninstall log,\r
+or added large amount of data after the installation which will be excluded also,\r
+the delay should be noticeable.\r
+\r
+\r
+\r
+\r
+Credits\r
+\r
+A very big thanks goes to kichik.\r
+When my idea of the Advanced Uninstall Log became an NSIS header, it was \r
+indeed an amateur's attempt to write a flexible and errors free NSIS header.\r
+Kichik dropped me a dozen of suggestions helping me to achieve my plan.\r
+However, his main suggestion to eliminate the mentioned above disadvantage,\r
+still remains untouched by me.\r
+\r
+\r
+\r
+\r
+License\r
+\r
+This header file is provided 'as-is', without any express or implied warranty.\r
+In no event will the author be held liable for any damages arising from the use\r
+of this header file.\r
+\r
+Permission is granted to anyone to use this header file for any purpose,\r
+including commercial applications, and to alter it and redistribute it freely,\r
+subject to the following restrictions:\r
+\r
+   1. The origin of this header file must not be misrepresented; \r
+      you must not claim that you wrote the original header file.\r
+      If you use this header file in a product, an acknowledgment in \r
+      the product documentation would be appreciated but is not required.\r
+\r
+   2. Altered versions must be plainly marked as such, and must not be \r
+      misrepresented as being the original header file.\r
+\r
+   3. This notice may not be removed or altered from any distribution. \r
+\r
+\r
+eof
\ No newline at end of file
index 514ed6449163e04020a3dd65707324ed6ee1ac25..3a9561a7e5f32fe4a1487a7dc4f31438edaf0749 100644 (file)
@@ -29,6 +29,25 @@ SetCompressor /SOLID lzma
 !define MUI_HEADERIMAGE_BITMAP "header.bmp"
 !define MUI_COMPONENTSPAGE_SMALLDESC
 
+;..................................................................................................
+;Following two definitions required. Uninstall log will use these definitions.
+;You may use these definitions also, when you want to set up the InstallDirRagKey,
+;store the language selection, store Start Menu folder etc.
+;Enter the windows uninstall reg sub key to add uninstall information to Add/Remove Programs also.
+
+!define INSTDIR_REG_ROOT "HKLM"
+!define INSTDIR_REG_KEY PRODUCT_UNINST_KEY
+
+;include the Uninstall log header
+!include AdvUninstLog.nsh
+
+;Specify the preferred uninstaller operation mode, either unattended or interactive.
+;You have to type either !insertmacro UNATTENDED_UNINSTALL, or !insertmacro INTERACTIVE_UNINSTALL.
+;Be aware only one of the following two macros has to be inserted, neither both, neither none.
+
+;!insertmacro UNATTENDED_UNINSTALL
+!insertmacro INTERACTIVE_UNINSTALL
+
 
 ; Welcome page
 !insertmacro MUI_PAGE_WELCOME
@@ -401,26 +420,42 @@ FunctionEnd
 !macro Language polng lng
   SectionIn 1 2 3
   SetOutPath $INSTDIR
+  !insertmacro UNINSTALL.LOG_OPEN_INSTALL
   File /nonfatal /a "..\..\inkscape\*.${lng}.txt"
+  !insertmacro UNINSTALL.LOG_CLOSE_INSTALL
   SetOutPath $INSTDIR\locale
+  !insertmacro UNINSTALL.LOG_OPEN_INSTALL
   File /nonfatal /a /r "..\..\inkscape\locale\${polng}"
+  !insertmacro UNINSTALL.LOG_CLOSE_INSTALL
   SetOutPath $INSTDIR\lib\locale
+  !insertmacro UNINSTALL.LOG_OPEN_INSTALL
   File /nonfatal /a /r "..\..\inkscape\lib\locale\${polng}"
+  !insertmacro UNINSTALL.LOG_CLOSE_INSTALL
   SetOutPath $INSTDIR\share\clipart
+  !insertmacro UNINSTALL.LOG_OPEN_INSTALL
   File /nonfatal /a /r "..\..\inkscape\share\clipart\*.${polng}.svg"  
+  !insertmacro UNINSTALL.LOG_CLOSE_INSTALL
   ; the keyboard tables
   SetOutPath $INSTDIR\share\screens
+  !insertmacro UNINSTALL.LOG_OPEN_INSTALL
   File /nonfatal /a /r "..\..\inkscape\share\screens\*.${polng}.svg"  
+  !insertmacro UNINSTALL.LOG_CLOSE_INSTALL
   SetOutPath $INSTDIR\share\templates
+  !insertmacro UNINSTALL.LOG_OPEN_INSTALL
   File /nonfatal /a /r "..\..\inkscape\share\templates\*.${polng}.svg"  
+  !insertmacro UNINSTALL.LOG_CLOSE_INSTALL
   SetOutPath $INSTDIR\doc
+  !insertmacro UNINSTALL.LOG_OPEN_INSTALL
   File /nonfatal /a /r "..\..\inkscape\doc\keys.${polng}.xml"  
   File /nonfatal /a /r "..\..\inkscape\doc\keys.${polng}.html"  
+  !insertmacro UNINSTALL.LOG_CLOSE_INSTALL
   SectionGetFlags ${SecTutorials} $R1 
   IntOp $R1 $R1 & ${SF_SELECTED} 
   IntCmp $R1 ${SF_SELECTED} 0 skip_tutorials 
     SetOutPath $INSTDIR\share\tutorials
+    !insertmacro UNINSTALL.LOG_OPEN_INSTALL
     File /nonfatal /a "..\..\inkscape\share\tutorials\*.${polng}.*"
+    !insertmacro UNINSTALL.LOG_CLOSE_INSTALL
   skip_tutorials:
 !macroend
 
@@ -521,6 +556,7 @@ Section $(lng_Core) SecCore
 
   SectionIn 1 2 3 RO
   SetOutPath $INSTDIR
+  !insertmacro UNINSTALL.LOG_OPEN_INSTALL
   SetOverwrite on
   SetAutoClose false
 
@@ -537,22 +573,31 @@ Section $(lng_Core) SecCore
   File /nonfatal /a /r "..\..\inkscape\doc"
   File /nonfatal /a /r "..\..\inkscape\plugins"
   File /nonfatal /a /r /x *.??*.???* /x "examples" /x "tutorials" "..\..\inkscape\share"
+  !insertmacro UNINSTALL.LOG_CLOSE_INSTALL
   ; this files are added because it slips through the filter
   SetOutPath $INSTDIR\share\clipart
+  !insertmacro UNINSTALL.LOG_OPEN_INSTALL
   File /a "..\..\inkscape\share\clipart\inkscape.logo.svg"
   ;File /a "..\..\inkscape\share\clipart\inkscape.logo.classic.svg"  
+  !insertmacro UNINSTALL.LOG_CLOSE_INSTALL
   SetOutPath $INSTDIR\share\extensions
+  !insertmacro UNINSTALL.LOG_OPEN_INSTALL
   File /a "..\..\inkscape\share\extensions\pdf_output.inx.txt"
   File /a "..\..\inkscape\share\extensions\pdf_output_via_gs_on_win32.inx.txt"
+  !insertmacro UNINSTALL.LOG_CLOSE_INSTALL
   SetOutPath $INSTDIR\share\icons
+  !insertmacro UNINSTALL.LOG_OPEN_INSTALL
   File /a "..\..\inkscape\share\icons\inkscape.file.png"
   File /a "..\..\inkscape\share\icons\inkscape.file.svg"
+  !insertmacro UNINSTALL.LOG_CLOSE_INSTALL
   SetOutPath $INSTDIR\modules
+  !insertmacro UNINSTALL.LOG_OPEN_INSTALL
   File /nonfatal /a /r "..\..\inkscape\modules\*.*"
+  !insertmacro UNINSTALL.LOG_CLOSE_INSTALL
   SetOutPath $INSTDIR\python
-  File /nonfatal /a /r "..\..\inkscape\python\*.*"
-
-  
+  !insertmacro UNINSTALL.LOG_OPEN_INSTALL
+  File /nonfatal /a /r "..\..\inkscape\python\*.*" 
+  !insertmacro UNINSTALL.LOG_CLOSE_INSTALL
 SectionEnd
 
 Section $(lng_GTKFiles) SecGTK
@@ -561,10 +606,12 @@ Section $(lng_GTKFiles) SecGTK
   
   SectionIn 1 2 3 RO
   SetOutPath $INSTDIR
+  !insertmacro UNINSTALL.LOG_OPEN_INSTALL
   SetOverwrite on
   File /a /r "..\..\inkscape\*.dll"
   File /a /r /x "locale" "..\..\inkscape\lib"
   File /a /r "..\..\inkscape\etc"
+  !insertmacro UNINSTALL.LOG_CLOSE_INSTALL
 SectionEnd
 
 Section $(lng_Alluser) SecAlluser
@@ -662,13 +709,17 @@ SectionGroup $(lng_Addfiles) SecAddfiles
 Section $(lng_Examples) SecExamples
   SectionIn 1 2
   SetOutPath $INSTDIR\share
+  !insertmacro UNINSTALL.LOG_OPEN_INSTALL
   File /nonfatal /a /r /x "*.??*.???*" "..\..\inkscape\share\examples"
+  !insertmacro UNINSTALL.LOG_CLOSE_INSTALL
 SectionEnd
 
 Section $(lng_Tutorials) SecTutorials
   SectionIn 1 2
   SetOutPath $INSTDIR\share
+  !insertmacro UNINSTALL.LOG_OPEN_INSTALL
   File /nonfatal /a /r /x "*.??*.???*" "..\..\inkscape\share\tutorials"
+  !insertmacro UNINSTALL.LOG_CLOSE_INSTALL
 SectionEnd
 
 SectionGroupEnd
@@ -997,6 +1048,9 @@ SectionEnd
 !macroend
 
 Function .onInit
+  ;prepare log always within .onInit function
+  !insertmacro UNINSTALL.LOG_PREPARE_INSTALL
+
   ;Extract InstallOptions INI files
   StrCpy $AskMultiUser "1"
   StrCpy $MultiUser "0"
@@ -1164,6 +1218,12 @@ FunctionEnd
 Function .onSelChange
 FunctionEnd
 
+
+Function .onInstSuccess
+  ;create/update log always within .onInstSuccess function
+  !insertmacro UNINSTALL.LOG_UPDATE_INSTALL
+FunctionEnd
+
 ; --------------------------------------------------
 
 Function un.CustomPageUninstall
@@ -1180,6 +1240,9 @@ FunctionEnd
 
 
 Function un.onInit
+  ;begin uninstall, could be added on top of uninstall section instead
+  !insertmacro UNINSTALL.LOG_BEGIN_UNINSTALL
+
   ClearErrors
   StrCpy $User ""
        UserInfo::GetName
@@ -1351,7 +1414,26 @@ Section Uninstall
   RMDir  "$SMPROGRAMS\Inkscape"
 
   DetailPrint "removing uninstall info"
-  RMDir /r "$INSTDIR"
+
+  ;uninstall from path, must be repeated for every install logged path individual
+  !insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR\lib\locale"
+  !insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR\locale"
+  !insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR\doc"
+  !insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR\share\tutorials"
+  !insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR\share\templates"
+  !insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR\share\screens"
+  !insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR\share\clipart"
+  !insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR\share\extensions"
+  !insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR\share\icons"
+  !insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR\share"
+  !insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR\modules"
+  !insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR\python"
+  !insertmacro UNINSTALL.LOG_UNINSTALL "$INSTDIR"
+
+  ;end uninstall, after uninstall from all logged paths has been performed
+  !insertmacro UNINSTALL.LOG_END_UNINSTALL
+
+  ;RMDir /r "$INSTDIR"
 
   SetAutoClose false