Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   C++ Anwendung nur einmal starten (https://www.delphipraxis.net/213479-anwendung-nur-einmal-starten.html)

ruppi98 4. Aug 2023 10:21

Anwendung nur einmal starten
 
Hallo,

ich benutze den C++Builder 11.2 für meine Programmierung. Nun habe ich ein Programm, welches nur
einmal gestartet werden soll.

Mein Problem ist folgendes.

* Führe ich einmal das Programm von der Aufgabenplanung aus und danach den Code aus der IDE, funktioniert alles wie gewollt.
* Führe ich das Programm vom Desktop aus, funktioniert auch alles wie gewollt.
* Führe ich einmal das Programm von der Aufgabenplanung aus und starte es erneut vom Desktop, funktioniert es nicht mehr.
Es wird nicht erkannt, das das Programm bereits im Hintergrund läuft.

Das Programm besitzt Admin-Rechte.

Wo liegt das Problem. Kann mir hier einer einen Tipp geben?

Ruppi

joachimd 4. Aug 2023 10:43

AW: Anwendung nur einmal starten
 
Die Aufgabenplanung wird wohl unter einem anderen Benutzerkontext (local SYSTEM account) ausgeführt. Die IDE vermutlich auch.

ruppi98 4. Aug 2023 10:44

AW: Anwendung nur einmal starten
 
Hallo,

nein der Aufgabenplaner läuft unter dem selben Konto.

Ruppi

ruppi98 4. Aug 2023 10:51

AW: Anwendung nur einmal starten
 
Hallo,

Sorry, habe es grade noch mal gescheckt :oops:.
Hatte mich geirrt. Der Aufgabentask wird unter SYSTEM ausgeführt, das Programm aber unter den Benutzernamen.

Ruppi

Sherlock 4. Aug 2023 10:56

AW: Anwendung nur einmal starten
 
Dann wirst Du etwas anderes nutzen müssen, um Dein SingleInstance zu gewährleisten. Einfach ist da eine Semaphordatei zu setzen/löschen. Nicht trivial ist dann herauszufinden, ob die Datei da ist, weil gerade das Programm läuft, oder weil vergessen wurde sie zu löschen (Programmabsturz).

Sherlock

himitsu 4. Aug 2023 11:03

AW: Anwendung nur einmal starten
 
Einmal kann die Aufgabenplanung für sich selbst prüfen, ob es nur einmal läuft.
In dem Task kann man einstellen was passieren soll (nicht starten, wenn noch läuft / das alte beenden, wenn neu gestartet / oder sonstwas ) ... aber nur für seine eigenen Ausführungen.


So, also nun das Wichtigste:
Wie prüfst du ob es schon läuft?
* beim Mutex kann man auch Global oder Local angeben
* und auch bei der Suche nach Prozessen könnte man im gesamten PC oder nur im aktiven Nutzer/Kontext oder auf dem aktuellen Desktop suchen
* ...

ruppi98 4. Aug 2023 11:50

AW: Anwendung nur einmal starten
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

der Aufgabenplaner ist so eingestellt, das nur eine Instanz läuft.
Das Problem ist, wenn sich der Benutzer Angemeldet hat und das Programm nochmals
startet.

Abfragen, ob das Programm bereits läuft, wird über die bekannten API-Funktionen
durchgeführt ( EnumProcesses, EnumProcessModules, GetModuleBaseName).

Hänge mal den Code als Datei an.

Ruppi

Uwe Raabe 4. Aug 2023 12:22

AW: Anwendung nur einmal starten
 
Ich würde das, wie Frank schon erwähnte, über einen globalen Mutex machen.

ruppi98 4. Aug 2023 12:29

AW: Anwendung nur einmal starten
 
Hallo Uwe,

habe Mutex lange nicht mehr benutzt. Hättest Du da ein kurzen Snippet?

Hatte mal folgendes vor langer langer Zeit:

HANDLE hMutex;
const char* myMutex = "mein programm.exe";

hMutex = CreateMutex(NULL, true, (wchar_t*) myMutex);
if (GetLastError() == ERROR_ALREADY_EXISTS) {
ShowMessage("Nur eine Instanz erlaubt !");
PostQuitMessage(0); // Mutex gibts schon,Programm beenden

Hatte aber irgendwie nicht so richtig geklappt.

Ruppi

himitsu 4. Aug 2023 12:31

AW: Anwendung nur einmal starten
 
Was passiert, wenn EnumProcesse, OpenProcess, EnumProcessModules oder GetModuleBaseName nicht funktionieren? (ihnen z.B. eine Berechtigung fehlt)
Niemand wertet die Fehlerfälle aus und dann wird blindlinks davon ausgegangen, das Programm liefe angeblich nicht (nur weil die Suche nicht wollte).

Selbst als Admin hat man nicht unbedingt automatisch das Recht, um auf alle fremden Prozesse zuzugreifen, vor allem nicht in anderen und sogar höherwertigen Sitzungen.



Delphi-Quellcode:
OneMutex := CreateMutex(nil, True, 'Global\xxxxxxxx');
if OneMutex = 0 then
  RaiseLastOSError;
if GetLastError = ERROR_ALREADY_EXISTS then
  ...; // Programm läuft schon

... // Application.Run; usw.

CloseHandle(OneMutex);
Da aber Windows den Mutex zum Programmende automatisch freigibt, ginge es auch einfach so:
Delphi-Quellcode:
if CreateMutex(nil, True, 'Global\xxxxxxxx') = 0 then
  RaiseLastOSError;
if GetLastError = ERROR_ALREADY_EXISTS then
  ...; // Programm läuft schon

...
xxxxxxxx ist irgendein eindeutiger Name (ID, Name deines Programms, sonstwas) oder z.B. auch eine GUID (Strg+Shift+G)


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:44 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz