I have an install script with Pascal code to determine if the app to be installed is currently running:
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
[Setup]
AppName=MyApp
AppVerName=MyApp v1.0
DiskSpanning=no
AppPublisher=me
AppPublisherURL=http://www.example.com
AppSupportURL=http://www.example.com
AppUpdatesURL=http://www.example.com
DefaultDirName={pf}\MyApp
UsePreviousAppDir=yes
DefaultGroupName=MyApp
OutputBaseFilename=Setup
OutputDir=.\MyAppSetup
MinVersion=5.0
[Tasks]
Name: desktopicon; Description: Create a &desktop icon; GroupDescription: Additional icons:; MinVersion: 4,4
[Files]
Source: .\Release\MyApp.exe; DestDir: {app}; Flags: ignoreversion
[Icons]
Name: {group}\EasyCash&Tax; Filename: {app}\MyApp.exe
Name: {userdesktop}\EasyCash&Tax; Filename: {app}\MyApp.exe; MinVersion: 4,4; Tasks: desktopicon
[Run]
Filename: {app}\MyApp.exe; Description: Launch MyApp; Flags: nowait postinstall skipifsilent
[Code]
function CheckProcessRunning( aProcName,
aProcDesc: string ): boolean;
var
ShellResult: boolean;
ResultCode: integer;
cmd: string;
sl: TStringList;
f: string;
d: string;
begin
cmd := 'for /f "delims=," %%i ' +
'in (''tasklist /FI "IMAGENAME eq ' + aProcName + '" /FO CSV'') ' +
'do if "%%~i"=="' + aProcName + '" exit 1';
f := 'CheckProc.cmd';
d := AddBackSlash( ExpandConstant( '{tmp}' ));
sl := TStringList.Create;
sl.Add( cmd );
sl.Add( 'exit /0' );
sl.SaveToFile( d + f );
sl.Free;
Result := true;
while ( Result ) do
begin
ResultCode := 1;
ShellResult := Exec( f,
'',
d,
SW_HIDE,
ewWaitUntilTerminated,
ResultCode );
Result := ResultCode > 0;
if Result and
( MsgBox( aProcDesc + ' is active and must be closed to proceed',
mbConfirmation,
MB_OKCANCEL ) <> IDOK ) then
Break;
end;
DeleteFile( d + f );
end;
// Perform some initializations. Return False to abort setup
function InitializeSetup: Boolean;
begin
// Do not use any user defined vars in here such as {app}
Result := not ( CheckProcessRunning( 'MyApp.exe', 'MyApp' ));
end;
function InitializeUninstall: Boolean;
begin
Result := not ( CheckProcessRunning( 'MyApp.exe', 'MyApp' ));
end;
This works for 99% of the cases but every now and then users report a false positive and are unable to proceed with installation.
Users report that in command line tasklist /FI "IMAGENAME eq MyApp.exe" /FO CSV
(which is used by the Pascal script) is returning nothing.
Is there an error in the script that may give false positives or is there a better way to determine if the app is running than tasklist
?
AppMutex
directive to the name of that mutex and let the Inno Setup do what installers usually do, they check if there's a mutex of that name and ask the user to exit the application (they don't forcibly terminate it behind the user's back). – Lashaunda