it-swarm.com.de

Wie kann ich die C # .net-App zwingen, unter Windows nur eine Instanz auszuführen?

Mögliches Duplikat:
Wie kann eine Einzelinstanzanwendung korrekt erstellt werden?

Wie kann ich die C # .net-App zwingen, unter Windows nur eine Instanz auszuführen?

61
jinsungy

Ich bevorzuge eine Mutex-Lösung ähnlich der folgenden. Auf diese Weise wird die App neu fokussiert, wenn sie bereits geladen ist

using System.Threading;

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
   bool createdNew = true;
   using (Mutex mutex = new Mutex(true, "MyApplicationName", out createdNew))
   {
      if (createdNew)
      {
         Application.EnableVisualStyles();
         Application.SetCompatibleTextRenderingDefault(false);
         Application.Run(new MainForm());
      }
      else
      {
         Process current = Process.GetCurrentProcess();
         foreach (Process process in Process.GetProcessesByName(current.ProcessName))
         {
            if (process.Id != current.Id)
            {
               SetForegroundWindow(process.MainWindowHandle);
               break;
            }
         }
      }
   }
}
104
Mitchel Sellers

um zu erzwingen, dass nur eine Instanz eines Programms in .NET (C #) ausgeführt wird, verwenden Sie diesen Code in der Datei program.cs:

public static Process PriorProcess()
    // Returns a System.Diagnostics.Process pointing to
    // a pre-existing process with the same name as the
    // current one, if any; or null if the current process
    // is unique.
    {
        Process curr = Process.GetCurrentProcess();
        Process[] procs = Process.GetProcessesByName(curr.ProcessName);
        foreach (Process p in procs)
        {
            if ((p.Id != curr.Id) &&
                (p.MainModule.FileName == curr.MainModule.FileName))
                return p;
        }
        return null;
    }

und die folgende:

[STAThread]
    static void Main()
    {
        if (PriorProcess() != null)
        {

            MessageBox.Show("Another instance of the app is already running.");
            return;
        }
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form());
    }
23
snir

Dies ist, was ich in meiner Anwendung verwende:

static void Main()
{
  bool mutexCreated = false;
  System.Threading.Mutex mutex = new System.Threading.Mutex( true, @"Local\slimCODE.slimKEYS.exe", out mutexCreated );

  if( !mutexCreated )
  {
    if( MessageBox.Show(
      "slimKEYS is already running. Hotkeys cannot be shared between different instances. Are you sure you wish to run this second instance?",
      "slimKEYS already running",
      MessageBoxButtons.YesNo,
      MessageBoxIcon.Question ) != DialogResult.Yes )
    {
      mutex.Close();
      return;
    }
  }

  // The usual stuff with Application.Run()

  mutex.Close();
}
9
Martin Plante

eine andere Möglichkeit für eine einzelne Instanz einer Anwendung besteht darin, ihre Hashsummen zu überprüfen. Nachdem ich mit Mutex rumgespielt habe (hat nicht so funktioniert wie ich will), habe ich es so gemacht:

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool SetForegroundWindow(IntPtr hWnd);

    public Main()
    {
        InitializeComponent();

        Process current = Process.GetCurrentProcess();
        string currentmd5 = md5hash(current.MainModule.FileName);
        Process[] processlist = Process.GetProcesses();
        foreach (Process process in processlist)
        {
            if (process.Id != current.Id)
            {
                try
                {
                    if (currentmd5 == md5hash(process.MainModule.FileName))
                    {
                        SetForegroundWindow(process.MainWindowHandle);
                        Environment.Exit(0);
                    }
                }
                catch (/* your exception */) { /* your exception goes here */ }
            }
        }
    }

    private string md5hash(string file)
    {
        string check;
        using (FileStream FileCheck = File.OpenRead(file))
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] md5Hash = md5.ComputeHash(FileCheck);
            check = BitConverter.ToString(md5Hash).Replace("-", "").ToLower();
        }

        return check;
    }

es prüft nur MD5-Summen nach Prozess-ID.

wenn eine Instanz dieser Anwendung gefunden wurde, fokussiert sie die ausgeführte Anwendung und beendet sich selbst.

sie können es umbenennen oder mit Ihrer Datei tun, was Sie wollen. Es wird nicht zweimal geöffnet, wenn der MD5-Hash derselbe ist.

kann jemand vorschläge dazu haben? Ich weiß, dass es beantwortet wird, aber vielleicht sucht jemand nach einer Mutex-Alternative.

2
Thyrador