[c#] Nur XX Instanzen erlauben

Passer

Erfahrenes Mitglied
NAbend zusammen,

ich bastel grade ein wenig daran rum, dass es meinem Programm nur in 1-2 Instanzen erlaubt ist zu starten. Derzeit mach ich das, indem ich nach Prozessnamen suche.

gibt es da vielleicht noch einen eleganteren Weg?

MfG
Passer
 
Hallo Passer!

Das mit dem Process ist schonmal der richtige Weg. Den Process benötigst aber nur,
um die bereits aktive Anwendung in den Vordergund zu holen.
Es gibt aber ein Objekt dass es Dir ermöglicht festzustellen, ob etwas im gesamten System bereits vorhanden ist.
Das System.Threading.Mutex Objekt.
Dieses Objekt wird in der Regel dazu verwendet, um ApplicationDomain übergreifend Dinge zu synchronisieren.

Hier mal ein Beispiel.
C#:
sealed class Program
{
	[STAThread]
	static void Main() {
		MyForm app = null;
		Mutex mutexObj = null;
		bool mutexCreated = false;

		try {
			mutexObj = new Mutex( true, "MyApp only One-Instance Startupcheck", out mutexCreated );
			Process proc = InstanceHandler.RunningInstance();
			if ( proc != null || !mutexCreated ){
				ErrorMessages.Show_OnlyOneProgInstance();
				InstanceHandler.HandleRunningInstance( proc );
			}
			else{
				Application.EnableVisualStyles();
				Application.DoEvents();
				app = new MyForm();
				Application.Run( app );
			}
		}
		catch ( Exception ex ) {
			MessageBox.Show(
				string.Format( "{0}{1}{1}{2}", ex.GetType().FullName, Environment.NewLine, ex.ToString() ),
				string.Format( "{0} ({1})", ex.Source, ex.GetType().Name ) );
		}
		finally {
			if ( app != null ) {
				app.Dispose();
				app = null;
			}
			if ( mutexObj != null ){
				if ( mutexCreated )
					mutexObj.ReleaseMutex();
				mutexObj = null;				
			}
			GC.WaitForPendingFinalizers();
			GC.Collect();
		}
	}
}
Um den bereits aktiven Prozess in den Vordergund zu holen, wird die nachfolgende Klasse benötigt.
C#:
public sealed class InstanceHandler
{
	[System.Runtime.InteropServices.DllImport("User32.dll")] 
	public static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);

	[System.Runtime.InteropServices.DllImport("User32.dll")] 
	public static extern bool SetForegroundWindow(IntPtr hWnd);
	private const int WS_SHOWNORMAL = 1;

	public InstanceHandler(){}

	public static Process RunningInstance() {

		Process current = Process.GetCurrentProcess();
		Process[] processes = Process.GetProcessesByName( current.ProcessName );

		foreach ( Process process in processes ){
			if ( process.Id != current.Id ){
				if ( System.Reflection.Assembly.GetExecutingAssembly().Location.Replace("/", "\\") ==
					process.MainModule.FileName ){
					return process;
				}
			}
		}
		return null;
	}

	public static void HandleRunningInstance( Process instance ) {

		if ( instance != null ){
			ShowWindowAsync( instance.MainWindowHandle , WS_SHOWNORMAL );
			SetForegroundWindow( instance.MainWindowHandle );
		}
	}
}
Nun kann deine Anwendung immer nur einmal existieren. :)
 
Zurück