运行一个程序实例

我有一个问题吗?! 我用这种方式只运行一个程序实例。 它做得非常好。但是当我在其他应用程序中使用这种方式时。 当我通过桌面快捷方式运行其中一个程序时,两个程序都会在桌面上调用和显示。 注意:两个程序都在windows系统中运行试试。

static bool ok; static Mutex mutex = new Mutex(true, "{123Newsoft-Cleaner Portable Program123}",out ok); ///  /// The main entry point for the application. ///  [STAThread] static void Main() { //Application.EnableVisualStyles(); //Application.SetCompatibleTextRenderingDefault(false); //Application.Run(new Form1()); if (mutex.WaitOne(TimeSpan.Zero, true)) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); var mainForm = new Form1c(); try { mainForm.Visible = false; mainForm.WindowState = FormWindowState.Normal; } catch (Exception ex) { MessageBox.Show(ex.Message, "error", MessageBoxButtons.OK, MessageBoxIcon.Error); } Application.Run(mainForm); } else { NativeMethods.PostMessage((IntPtr)NativeMethods.HWND_BROADCAST, NativeMethods.WM_SHOWME, IntPtr.Zero, IntPtr.Zero); } 

// —————-主要forms

  protected override void WndProc(ref Message M_C) { if (M_C.Msg == NativeMethods.WM_SHOWME) { ShowMe(); } base.WndProc(ref M_C); } //************* private void ShowMe() { if (WindowState == FormWindowState.Minimized) { Show(); WindowState = FormWindowState.Normal; } // get our current "TopMost" value (ours will always be false though) bool top = TopMost; // make our form jump to the top of everything TopMost = true; // set it back to whatever it was TopMost = top; } 

这已得到.NET Framework的良好支持。 您想要使用WindowsFormsApplicationBase类。 将IsSingleInstance属性设置为true。 您可以覆盖OnStartupNextInstance方法,以便在另一个实例启动时执行您喜欢的任何操作。 就像恢复第一个实例的窗口一样。 将Program.cs文件重写为如下所示:

 using System; using System.Windows.Forms; using Microsoft.VisualBasic.ApplicationServices; // Add reference to Microsoft.VisualBasic namespace WindowsFormsApplication1 { class Program : WindowsFormsApplicationBase { [STAThread] static void Main(string[] args) { var app = new Program(); app.Run(args); } public Program() { this.IsSingleInstance = true; this.EnableVisualStyles = true; this.MainForm = new Form1(); } protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs) { if (this.MainForm.WindowState == FormWindowState.Minimized) this.MainForm.WindowState = FormWindowState.Normal; this.MainForm.Activate(); } } } 

为了添加Hans Passant写的内容,我在主窗体上添加了一个额外的方法来处理恢复窗口并激活窗口。 这是为了包装表单的调用所需条件。

所以表单上添加的方法是:

 ///  /// Recovers this instance of the form. ///  public void RestoreFromTray() { if(this.InvokeRequired) { this.Invoke(new Action(RestoreFromTray) ); return; } this.Visible = true; this.WindowState = FormWindowState.Normal; this.Activate(); } 

然后在Hans的方法中,我将覆盖更改为:

 protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs) { ((formClassName)this.MainForm).RestoreFromTray(); } 

其中formClassName是表单的类名。