This should be simple, I need to stop any previous version of my program from running when the installer starts.
Most people suggested making an exe
wh
If the application has a Mutex, you can add an AppMutex
value in your Inno Setup installer and it will display a message telling the user to stop the program. You might be able to find the Mutex (if it's got one) by using SysInternals Process Explorer and selecting the program / process and looking at the Handles (CTRL-H) in the Lower Pane.
Here's a link to the a KB article that mentions several methods:
http://www.vincenzo.net/isxkb/index.php?title=Detect_if_an_application_is_running
Alternatively, you might try this (UNTESTED) code in the InitializeSetup
:
[Setup]
;If the application has Mutex, uncomment the line below, comment the InitializeSetup function out, and use the AppMutex.
;AppMutex=MyApplicationMutex
[Code]
const
WM_CLOSE = 16;
function InitializeSetup : Boolean;
var winHwnd: Longint;
retVal : Boolean;
strProg: string;
begin
Result := True;
try
//Either use FindWindowByClassName. ClassName can be found with Spy++ included with Visual C++.
strProg := 'Notepad';
winHwnd := FindWindowByClassName(strProg);
//Or FindWindowByWindowName. If using by Name, the name must be exact and is case sensitive.
strProg := 'Untitled - Notepad';
winHwnd := FindWindowByWindowName(strProg);
Log('winHwnd: ' + IntToStr(winHwnd));
if winHwnd <> 0 then
Result := PostMessage(winHwnd,WM_CLOSE,0,0);
except
end;
end;
Here's a link to an Inno Setup script that prompts a user to close the target program, if it detects that the program is running. After the user closes the program, they can click on a "Retry" button to proceed with the installation:
http://www.domador.net/extras/code-samples/inno-setup-close-a-program-before-reinstalling-it/
This script is based on a simpler script, found in the Inno Setup Extensions Knowledge Base:
http://www.vincenzo.net/isxkb/index.php?title=Call_psvince.dll_on_install_and_uninstall
I tried using the accepted answer (and the follow up by jachguate) but it wouldn't kill my application. It looks like part of the reason was that my application window had no text associated with it but whatever is the real reason, I used shell command to kill it and that worked. In the [code] section, you want to add the following function. It is called just before setup files are copied.
function PrepareToInstall(var NeedsRestart: Boolean): String;
var
ErrorCode: Integer;
begin
ShellExec('open', 'taskkill.exe', '/f /im MyProg.exe','',SW_HIDE,ewNoWait,ErrorCode);
end;
I have had success using WMIC :
procedure CurStepChanged(CurStep: TSetupStep);
var
ResultCode: Integer;
wmicommand: string;
begin
// before installing any file
if CurStep = ssInstall then
begin
wmicommand := ExpandConstant('PROCESS WHERE "ExecutablePath like ''{app}\%%''" DELETE');
// WMIC "like" expects escaped backslashes
StringChangeEx(wmicommand, '\', '\\', True);
// you can/should add an "if" around this and check the ResultCode
Exec('WMIC', wmicommand, '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
end;
end;
You can also do it in the InitializeSetup
but if you do, keep in mind you don't have yet access to the {app}
constant. My program doesn't ask for install path, but yours might.