Erkennen einer bereits aktiven Programm-Instanz

Erkennen einer bereits aktiven Programm-Instanz

Veröffentlicht: 07. Aug 2002 | Aktualisiert: 22. Jun 2004
Von Dirk Primbs

Unter bestimmten Bedingungen ist es wichtig festzustellen, ob bereits eine Instanz eines Programms läuft. Dieser MSDN Quickie zeigt Ihnen, wie Sie das ermitteln können. Code in C# und VB.NET.

Um Prozesse zu ermitteln, gibt es in .NET eine eigene Klasse im Namespace System.Diagnostics. Die darin enthaltene Klasse Process gibt Ihnen die Hilfsmittel an die Hand, um laufende Prozesse zu ermitteln und Informationen über sie einzuholen.

Diese Klasse hilft aber nur beim Ermitteln eines Prozesses. Will man auf ihn Einfluss nehmen, etwa indem man sein Fenster in den Vordergrund holt, ist man auf P/Invoke- und API-Aufrufe angewiesen. Grundsätzlich helfen hier folgende API-Kommandos:

  • SetForegroundWindow()

  • IsIconic()

  • OpenIcon()

Da es sich hier um API-Befehle handelt, besteht der erste Schritt darin, die P/Invoke-Deklarationen zu ermitteln. Sie sind notwendig, um die Kommandos einzubinden:

'VB.NET
Public Declare Function SetForegroundWindow Lib "user32" _
      Alias "SetForegroundWindow" _
      (ByVal hwnd As IntPtr) As Integer
Private Declare Auto Function IsIconic Lib "user32" _
      Alias "IsIconic" (ByVal hwnd As IntPtr) As Int32
Private Declare Auto Function OpenIcon Lib "user32" _
      Alias "OpenIcon" (ByVal hwnd As IntPtr) As Int32
// C#
[DllImport("user32.dll")]
public  static extern int  SetForegroundWindow(IntPtr hwnd);
[DllImport("user32.dll")]
public  static extern int  IsIconic(IntPtr hwnd);
[DllImport("user32.dll")]
public  static extern int  OpenIcon(IntPtr hwnd);

Nun fehlt nur noch, alle Prozesse mit demselben Namen wie der eigene, im starten begriffene Prozess aufzuzählen. Falls bereits ein Prozess dieses Namens existiert, muss er aktiviert und der gerade startende beendet werden.

In VB bietet sich an, den dazu notwendigen Code in der Sub Main() (sie kann man unter Projekt | Eigenschaften als Startprozedur auswählen) unterzubringen, in C# ist die Main()-Function der geeignete Platz:

'VB.NET
Dim p As Process
Dim Ret As Int32
Dim hWndMain As IntPtr
Dim MyProcesses() As Process = _
Process.GetProcessesByName( _
Process.GetCurrentProcess().ProcessName)
For Each p In MyProcesses   
  ' eigenen Prozeß ausschließen 
  If (p.Id <> Process.GetCurrentProcess().Id) Then 
    hWndMain = p.MainWindowHandle()  
    If (IsIconic(hWndMain) <> 0) Then ' Fenster minimiert?
      Ret = OpenIcon(hWndMain)                        ' 
      If Ret = 0 Then
        Throw New Exception( _
          "Error restoring Window from icon");
      End If
    End If
    Ret = SetForegroundWindow(hWndMain)  
    If Ret = 0 Then
      Throw New Exception("Error bringing Window to front")
    End If
    Exit Sub
  End If
Next
// C#
int ret;
IntPtr hwndMain;
Process[] myProcesses = Process.GetProcessesByName(
    Process.GetCurrentProcess().ProcessName);
foreach (Process p in myProcesses) {
  if (p.Id!=Process.GetCurrentProcess().Id) {
    hwndMain = p.MainWindowHandle;
    if (IsIconic(hwndMain)!=0) {  // Fenster minimiert?
      ret = OpenIcon(hwndMain);
      if (ret==0) {
        throw new Exception(
"Error restoring Window from icon");
      }
    }
    ret = SetForegroundWindow(hwndMain);
    if (ret==0) {
      throw new Exception(
"Error bringing Window to front");
    }
    return;
  }
}

Weitere Informationen:

Q185730 HOWTO: Prevent Multiple Instances of a 32-bit VB Application http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q185730 (in englischer Sprache)


Anzeigen:
© 2016 Microsoft