[wpkg-users] InnoSetup Uninstall

Rainer Meier r.meier at wpkg.org
Wed Dec 9 19:09:43 CET 2009


Hi,

On 09.12.2009 17:45, le dahut wrote:
> InnoSetup says :
> """
> Because Windows doesn't allow programs to delete their own EXEs, the
> uninstaller creates and spawns a copy of itself in the TEMP directory.
> This "clone" performs the actual uninstallation, and at the end,
> terminates the original uninstaller EXE (at which point you get an exit
> code back), deletes it, then displays the "uninstall complete" message box
> """
> 
> The problem is that the file "unin000.exe" is not deleted at the end of
> uninstall.
> I think the "exit code = 1" reflects that.

Oh, quite stupid way of doing it - from my point of view. Actually the
uninstaller could advise the OS to remove remaining files at next reboot and
return code 0 if there is only the unin000.exe running.


> The side effect of this is that next time the application is installed,
> it will generate an "unin001.exe" file (because a unin000.exe already
> exists). And every time the app is installed/uninstalled it generates
> "unin<prec_unin_number +1>.exe".
> 
> This makes next uninstall fail because "unin000.exe", as specified in
> the "remove" section, is not the real uninstaller.

Uninstallation might be boxed into a small script which runs all available
unins*.exe scripts


@echo off
for /f "tokens=*" %%G in ('dir /b "%ProgramFiles%\program\unins*.exe"') DO %%G
exit /b 0


Actually I wrote another uninstall script I am using for some stupid
uninstallers which fork a sub-process...


@echo off

:: This script is an extended uninstaller script for programs which have tricky
:: uninstallers (e.g. VLC media player).
:: It is able to run an uninstaller application and then to monitor if the
:: uninstaller is erased from the system. Depending on the result (either
:: remove completes or timeout occurs) it exits with different ecit code:
:: code 0: all fine, program uninstalled
:: code 1: failed, uninstaller still exissts after timeout


:: This is required to evaluate the target of %ProgramFiles% on 64-bit systems
:: Please note that this is required only if you uninstall a 32-bit application.
set PROGRAM_FILES=%ProgramFiles%
if not "%ProgramFiles(x86)%" == "" set PROGRAM_FILES=%ProgramFiles(x86)%

:: Path where the uninstaller is located
set APP_DIR=%PROGRAM_FILES%\dia

:: Path to the uninstaller (see path definition above)
set UNINSTALLER=%APP_DIR%\dia-0.96.1-9-uninstall.exe

:: Options to be passed to the uninstaller in order to uninstall silently
set OPTIONS=/S


:: ############################################################################
:: No need to change anything below this line (usually ;-))
:: ############################################################################
echo Removing Program

if not exist "%UNINSTALLER%" goto good_end
start /wait "Uninstall" "%UNINSTALLER%" %OPTIONS%
REM Unfortunately the uninstaller seems to fork a child process and the parent
REM process exits immediately. So give it some time to uninstall
for /L %%C IN (1,1,30) DO (
  if not exist "%UNINSTALLER%" goto good_end
  ping -n 2 127.0.0.1 > NUL
)
:bad_end
exit /B 1

:good_end
if exist "%APP_DIR%" rmdir /s /q "%APP_DIR%"
exit /B 0


It supports 32-bit and 64-bit IS and you just need to fill the data in the header.
Well, this will not really work if the uninstlaler referred is not removed.

But this can be extended... just an (untested) example:



@echo off

:: This script is an extended uninstaller script for programs which have tricky
:: uninstallers (e.g. VLC media player).
:: It is able to run an uninstaller application and then to monitor if the
:: uninstaller is erased from the system. Depending on the result (either
:: remove completes or timeout occurs) it exits with different ecit code:
:: code 0: all fine, program uninstalled
:: code 1: failed, uninstaller still exissts after timeout


:: This is required to evaluate the target of %ProgramFiles% on 64-bit systems
:: Please note that this is required only if you uninstall a 32-bit application.
set PROGRAM_FILES=%ProgramFiles%
if not "%ProgramFiles(x86)%" == "" set PROGRAM_FILES=%ProgramFiles(x86)%

:: Path where the uninstaller is located
set APP_DIR=%PROGRAM_FILES%\dia

:: Path to the file to be checked in order to detect if uninstall  is complete
set APP_BIN=%APP_DIR%\app.exe

:: Options to be passed to the uninstaller in order to uninstall silently
set OPTIONS=/S


:: ############################################################################
:: No need to change anything below this line (usually ;-))
:: ############################################################################
echo Removing Program

if not exist "%APP_BIN%" goto good_end
for /f "tokens=*" %%G in ('dir /b "%ProgramFiles%\program\unins*.exe"') DO start
/wait "uninstall" "%%G" %OPTIONS%

for /L %%C IN (1,1,30) DO (
  if not exist "%APP_BIN%" goto good_end
  ping -n 2 127.0.0.1 > NUL
)
:bad_end
exit /B 1

:good_end
if exist "%APP_DIR%" rmdir /s /q "%APP_DIR%"
exit /B 0



> I've written a service that runs under SYSTEM account. It succeeds in
> installing/uninstalling InnoSetup apps with exactly the same command
> line as in <package>.xml.
> 
> Is it possible that WPKG puts its own lock on "unin000.exe" preventing
> it to be erased ?

No. WPKG just executes the processes listed in XML package definition. The only
known issue we cannot work-around is a bug in Microsoft which makes the process
to get stuck if it prints more than 4k of data to STDOUT/STDERR. So just
redirect the output to NUL by appending " > NUL" to the command if in doubt.
Make sure to use the latest WPKG version (1.1.2).

br,
Rainer



More information about the wpkg-users mailing list