Wie kann man werhindern, das die gleiche Applikation nicht mehrmals auf dem Rechner gestartet werden kann?
-
Man kann sich bei VB bedienen:
http://www.codeproject.com/KB/cs/CSSIApp.aspx
-
bool pobjIOwnMutex = false; System.Threading.Mutex pobjMutex = new System.Threading.Mutex(true, "meinprogramm", out pobjIOwnMutex); if (pobjIOwnMutex) { try { // Was möchte ich machen } catch (Exception ex) { Console.WriteLine("Unbekannter Fehler Main!" + ex.Message); } finally { Console.WriteLine("Mutex release"); pobjMutex.ReleaseMutex(); } } else { //exit application Console.WriteLine("Mutex nicht angelegt"); }
-
Hallo, wie binde ich das von Unix-Tom ein und was wird bei dem Mutexe in der ToDo-Codeeonfügeregion genau eingefügt? Eine FOrm die ich starte oder was?
Kan mir noch jemand eine Besispiel geben, wie ich die Registry in Programmcode überprüfe, wenn ich diese Variante benute?
-
Hm, Grundlagen?
Bei Start deines Programmes
System.Threading.Mutex pobjMutex = new System.Threading.Mutex(true, "meinprogramm", out pobjIOwnMutex);
dann gleich auf
if (pobjIOwnMutex)
überprüfen
Wenn true dann wurde der Mutex angelegt.
Wenn FALSE dann besteht der Mutex bereits und das Programm wurde bereits gestartet.Beim beenden des Programmes
pobjMutex.ReleaseMutex();
damit der Mutex gelöscht wird und das Programm wieder gestartet werden kann.
-
Knuddlbaer schrieb:
Die Sache mit der Registrierung ist blödsinn.
Why? :xmas2:
-
a) Racebedinnungen
b) Das schreiben der Registrierung könnte untersagt sein
c) Deine SW stürzt ab ohne den Eintrag zu entfernen
d) eine andere Anwendung könnte den Eintrag einfach entfernen
e) eine andere Anwendung könnte den Eintrag setzenund letztendlich ist ein Mutex deutlich besser geeignet.
-
Ja stimmt, daran habe ich auch gedacht.
Ja Mutex ist in diesem Falle wirklich besser.
-
Hallo Leute,
habe dies mal bei mir eingebaut.
Aber das funzt nur in der Debug-Version und nicht in der Release.
Warum?int main(array<System::String ^> ^args) { // Aktivieren visueller Effekte von Windows XP, bevor Steuerelemente erstellt werden Application::EnableVisualStyles(); Application::SetCompatibleTextRenderingDefault(false); bool pobjIOwnMutex = false; System::Threading::Mutex^ pobjMutex = gcnew System::Threading::Mutex(true, "TestProg", pobjIOwnMutex); if (pobjIOwnMutex) { // Hauptfenster erstellen und ausführen Application::Run(gcnew Form1()); } else { MessageBox::Show("Programm läuft schon..."); } return 0; }
Kann mir einer helfen?
Gruß
-
C++/CLI?
Was bedeutet "funzt nur in der Debug-Version"? Was "funzt" denn bei Release nicht?
-
Du solltest den Mutex beim Beenden des (eigentlichen) Hauptprogrammes auch wieder freigeben:
if (pobjIOwnMutex) { // Hauptfenster erstellen und ausführen Application::Run(gcnew Form1()); pobjMutex->ReleaseMutex(); // Mutex freigeben } else { MessageBox::Show("Programm läuft schon..."); }
Ansonsten sollte es völlig egal sein, ob du das Programm im Debug oder im Release laufen läßt.
(Evtl. könnte es aber bei deiner Version passiert sein, daß im Release der Mutex-Aufruf wegoptimiert wird, da kein weiterer Zugriff damit passiert ist).P.S. Von C# kenne ich die Möglichkeit GC.KeepAlive(object) für das Objekt aufzurufen (evtl. mußt du es bei C++/CLI auch so machen).
-
Danke Th69, das funzt wie verrückt.
Nun würde ich aber gerne die Anwendung in den Fordergrund bringen.
Ich versuche das schon fast 3 Tage.
Ich kann leider keinen this Zeiger übergeben.Dieser Code funzt in der Form1.h ohne Probleme, aber nicht in der int main(array<System::String ^> ^args).
HWND hwnd = (HWND)this->Handle.ToPointer(); SetForegroundWindow(hwnd);
Was kann ich da machen um ein Handle auf die laufende Anwendung zu bekommen?
bool _OwnMutex = false; System::Threading::Mutex^ _Mutex = gcnew System::Threading::Mutex(true, "TestProg", _OwnMutex); if (_OwnMutex) { Application::Run(gcnew Form1()); _Mutex->ReleaseMutex(); } else { MessageBox::Show("Programm läuft schon..."); HWND hwnd = (HWND)_Mutex->Handle.ToPointer();//geht auch nicht: SetForegroundWindow(hwnd); }
Kann mir nochmal jemand helfen?
Gruß,
Felice
-
Hallo Felice,
schön, daß mein Code bei dir klappt.
Das Handle des Mutex hat aber nichts mit dem Application- (bzw. Window)-Handle zu tun.
Mir fällt da nur ein, den anderen Prozess zu suchen und dann auf dessen MainForm zuzugreifen.Process[] processes = Process.GetProcessesByName("YourApp.exe"); if(processes != null) { foreach(Process process in processes) if(process.MainWindowHandle != null) { SetForegroundWindow(process.MainWindowHandle}; break; } }
Der Trick dabei ist, daß sowohl der aktuelle Prozess sowie der andere den gleichen Namen haben, aber nur der andere ein Fenster geöffnet hat (so daß MainWindowHandle gesetzt ist).
P.S. Dieser Code wird auch benutzt, um nur eine Instanz einer Applikation zu erzeugen (statt eines Mutex) - hat aber den Nachteil, daß evtl. ein anderer Prozess den gleichen Namen trägt. Als Kombination beider sollte es ausreichend sein (evtl. noch den MainWindowTitle zusätzlich abfragen).
Edit: Ups, sehe gerade, daß ich ja C#-Code gepostet habe (denke aber, daß du dies selber als C++/CLI umcodieren kannst -)
-
Super Th69 haut hin...
Stimmt ja, wir sind hier ja im C# Forum...uppsHier meine Abwandlung...
array<Process^>^ processes = Process::GetProcessesByName("TestProg");//Ohne .exe if(processes != nullptr) { for each(Process^ process in processes) { if(process->MainWindowHandle.ToPointer() != nullptr) { HWND hwnd = (HWND)process->MainWindowHandle.ToPointer(); SetForegroundWindow(hwnd); break; } } }
Super, danke Dir 1001 Mal...