2012-08-12 50 views
3

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

static bool ok; 
    static Mutex mutex = new Mutex(true, "{123Newsoft-Cleaner Portable Program123}",out ok); 

    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [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); 

     } 

// ----------------的主要形式

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; 

    } 

回答

8

这早已由.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(); 
     } 
    } 
} 
+0

感谢:)我使用.net 3.5这不工作:Microsoft.VisualBasic.ApplicationServices; – pepero 2012-08-12 17:40:44

+1

这适用于3.5。看看评论,使用Project +添加引用。 – 2012-08-12 17:42:22

+0

mersi.its work.unorable有老问题。当运行一个应用程序时,同时显示:( – pepero 2012-08-13 02:23:30

1

要添加到什么汉斯帕桑特写的,我补充说,处理恢复窗口,并激活它在主窗体上一个额外的方法。这是为了包装表单的调用所需条件。

所以在窗体上添加方法是:

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

然后在汉斯的方法,我改变了超越简单:

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

哪里formClassName是形式的类名。

+0

如果你需要这个,那么你正在做的事情**非常* *错误。在某些需要[此类调试]的下雨天将会挂起您的应用程序的错误类型(https://blogs.msdn.microsoft.com/dsui_team/2012/10/31/debugging-windows- *从不*在工作线程上显示UI,SystemEvents类会吃掉你的肝脏 – 2016-08-16 19:26:36

+0

我想我错过了一些东西 - 我添加了InvokeRequired测试来确保窗口被恢复在正确的t hread。我哪里弄错了? – 2016-08-16 19:50:41

相关问题