Witam!
Problem jak w temacie.
Wiem, że było coś podobnego w FAQ ale nie wiem jak to przerobić, żeby exe zamknął poprzednie uruchomienie samego siebie.
Z góry dzięki,
szukasz czy jest juz otwarte okno http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowreference/windowfunctions/findwindow.asp
i jak jest to je kill http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowreference/windowfunctions/destroywindow.asp
Zeby uprościć to troche pomogę.
Nie wiem czy nie jest to łopatologicznie(nie bijcie:D), ale koledze może wysarczy.
Bierzesz uchwyt do okna aplikacji która jest już uruchomiona:
var uchwyt:hwnd;
a potem
uchwyt:= FindWindow(nil,PChar('Serwer'));
gdzie parametr w cudzysłowie to albo nazwa klasy okna, albo napis na belce tytułowej.
Potem sprawdzasz czy uchwyt nie jest pusty(=0) bo jeżeli jest to znaczy żę ten program jest pierwszym uruchomionym: jeżeli <> to wysyłasz komunikat:
PostMessage(uchwyt, WM_USER+120, Atom, 0);
gdzie atom jest typu TAtom. To są paramtery - tutaj nas nie interesujace. Można w nich przekazać różne dane np wskaźnik to tablicy itp.
Ok. Już komunikat jest wysłany. Teraz trzeba go odebrać:
Dajesz na formatkę komponent ApplicationEvents. I podpinasz sie w pod zdarzenie onMessage - czyli gdy dojdzie komunikat. Sprawdzasz czy to nasz komunikat:
if Msg.message = WM_USER+120 then application.terminate
I to tyle. Mała uwaga: pamiętaj, że jak będziesz pisał program, to masz dodatkowe okno otwarte - to w delphi z formatką o takiej samej nazwie jak program. Będzie je znajdywał jak będziesz szukał uchwyt.</delphi>
Sposób następny - "procesowy":
Ścieżka Twojego programu to ParamStr(0).
Dokonujesz enumeracji procesów (CreateToolHelp32Snapshot + TH32CS_SNAPPROCESS) i sprawdzasz, czy ścieżka danego procesu = ParamStr(0). Do pobrania pełnej ścieżki danego procesu możesz wykorzystać funkcję GetProcessFileName z postu http://4programmers.net/Forum/viewtopic.php?id=45226.
Jeśli powyższy warunek jest spełniony, sprawdzasz, czy ID danego procesu jest różny od ID bieżącego (czy TProcessEntry32.th32ProcessID <> GetCurrentProcessId).
Jeśli tak, to masz do czynienia z drugą instancją aplikacji.
Teraz już wystarczy tylko otworzyć ten proces za pomocą OpenProcess (z access rights ustawionymi na PROCESS_TERMINATE) i przekazać handle zwrócony przez poprzednią funkcję do TerminateProcess.
Nie wiem czy dokładnie o to chodzi, ale moze lepiej zastosować komponent, który nie pozwala na dwukrotne uruchamianie programu juz odpalonego.
Np JustOne jest na stej stronie wystarczy poszukac :) Jezeli oto biega :)