2

I want to allow only one instance of my app to run. I'm using the code below to close additional instances of my app, but the problem is it will kill the current session as well. How can i edit this code to close additional instances, but not the current one ?

function killDuplicates: integer;
const
PROCESS_TERMINATE = $0001;
var
ContinueLoop: BOOL;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32;
pna : string;
begin
Result := 0;
FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
while Integer(ContinueLoop) <> 0 do
    begin
    pna := lowercase(ExtractFileName(FProcessEntry32.szExeFile));
    if pna = 'myapp.exe' then
      Result := Integer(TerminateProcess(OpenProcess(PROCESS_TERMINATE, BOOL(0), FProcessEntry32.th32ProcessID), 0));
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
    end;
CloseHandle(FSnapshotHandle);
end;
delphirules
  • 6,443
  • 17
  • 59
  • 108
  • 3
    Much better solution to use a mutex. With your method, every instance will be fighting to destroy each other. Reverse the logic, so that when your app starts, it shuts itself down if it finds another instance. – Jerry Dodge Jul 24 '17 at 13:33
  • 2
    This is not the way to create a single instance application. In any case what you seek is `GetCurrentProcessId` API, compare it against `FProcessEntry32.th32ProcessID `. – kobik Jul 24 '17 at 13:36
  • This did the trick @kobik. Post as solution, i will accept, thanks ! – delphirules Jul 24 '17 at 13:48
  • 1
    I would still highly advise not to do this. You never know which instance will win the fight. Actually, I see it more likely that *new* instances will win over the *original* one. – Jerry Dodge Jul 24 '17 at 13:51

1 Answers1

8

To answer the question asked:

How can i edit this code to close additional instances, but not the current one ?

Compare FProcessEntry32.th32ProcessID with GetCurrentProcessId. if they match, it's your current process.

That said, I strongly urge you not to use this kind of method to create a single instance application, as already mentioned by @Jerry.
consider this: Your program is running and the user interacts with it already. Now the user launches a second instance. What do you think will happen? The already running application will be killed literally by the second instance. Instead let the second instance terminate itself gracefully if it finds an already running instance (optionally notifying the running process about it, so it can bring itself to the front for example).

Take a look here for possible solutions:

kobik
  • 21,001
  • 4
  • 61
  • 121