Laden...

Programm nicht mehrmals starten (.Net)

Erstellt von Lars Schmitt vor 16 Jahren Letzter Beitrag vor 14 Jahren 15.814 Views
Information von herbivore vor 16 Jahren

Dies ist ein Thread, auf den aus der FAQ verwiesen wird. Bitte keine weitere Diskussion, sondern nur wichtige Ergänzungen und diese bitte knapp und präzise. Vielen Dank!

Lars Schmitt Themenstarter:in
2.223 Beiträge seit 2005
vor 16 Jahren
Programm nicht mehrmals starten (.Net)

Beschreibung:

Aus den tiefen meiner Sourcen wieder mal ein kleiner Snippet

Es könnte ja mal passieren, dass Ihr nicht wollt das euer Programm mehrmals gestartet wird.

Hier ist die Lösung per .Net Boardmitteln

bool createdNew;

System.Threading.Mutex mutex = new System.Threading.Mutex(true, Application.ProductName, out createdNew);
if (createdNew) {
	// bitte Form1 ersetzen 
	Application.Run(new Form1());
        // und auch wieder Freigeben besser ist besser
        mutex.ReleaseMutex();
} else {
	MessageBox.Show("Programm wurde bereits gestartet!", "Info", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

Schlagwörter: Mutex, Programm, single, einmal, 2. Instanz verhindern

Quelle: .NET-Snippets

3.971 Beiträge seit 2006
vor 15 Jahren

Bitte auch hier zwingend drauf achten, dass der Mutex bis zum Programmende am leben erhalten wird.

Siehe auch:
mehrere Programminstanzen verhindern?

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

1.130 Beiträge seit 2007
vor 15 Jahren

Wer die andere Instanz benachrichtigen will, kann man das über windowsmeldungen tun:

string name = Assembly.GetExecutingAssembly().GetName().Name;
                int currentId=Process.GetCurrentProcess().Id;
                EnumThreadDelegate callbackDelegate=new EnumThreadDelegate(Callback);
                foreach(Process p in Process.GetProcessesByName(name))
                {
                    if (p.Id != currentId)
                    {
                        IntPtr mainwindowHandle = p.MainWindowHandle;
                        if (mainwindowHandle != IntPtr.Zero)
                        {
                            SendMessage(mainwindowHandle,
                                0x8000 + 1,//WM_APP + x = deineMeldung
                                (IntPtr)(0), (IntPtr)(0)//Parameter
                                );
                        }
                        //Wenn die Anwendung kein eingetragenes hauptfenser hat:
                        else
                        {
                            foreach (ProcessThread thread in p.Threads)
                            { EnumThreadWindows(thread.Id, callbackDelegate, (IntPtr)0); }
                        }
                        //---
                    }
                }

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
        static extern IntPtr SendMessage(IntPtr hWnd, Int32 Msg, IntPtr wParam, IntPtr lParam);

        //Wenn die Anwendung kein eingetragenes hauptfenser hat:

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);

        public delegate int EnumThreadDelegate(IntPtr hwnd, IntPtr lParam);

        public static int Callback(IntPtr handle,IntPtr garbage)
        {
            SendMessage(handle, 0x8000+1, (IntPtr)(0), (IntPtr)(0));
            return 1;
        }

Zum Empfangen muss wndproc überschrieben werden oder ein messagefilter hinzugefügt werden.

Projekte:Jade, HttpSaver
Zum Rechtschreiben gibts doch schon die Politiker. Aber die bauen auch nur mist!

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo blackcoin,

statt Application.ProductName sollte man eine besser eine GUID verwenden, um Konflikte zwischen Programmen mit (zufällig) gleichem ProductName auszuschließen.

herbivore

5.742 Beiträge seit 2007
vor 14 Jahren

Nur aus reiner Vorsicht:

statt Application.ProductName sollte man eine besser eine GUID verwenden

Diese sollte aber natürlich statisch sein und nicht bei jeder Mutexerzeugung neu erzeugt werden.