C# 如何从可执行文件打开应用程序主界面,而不是在c中的任务栏图标上#

C# 如何从可执行文件打开应用程序主界面,而不是在c中的任务栏图标上#,c#,forms,show,tray,C#,Forms,Show,Tray,这是一个场景,我打开了我的应用程序,然后托盘图标显示,如果我双击托盘图标,将显示主界面。如果我再次打开我的应用程序,主界面应该得到关注,或者如果它还没有显示,那么应该显示它,而不是打开我的应用程序的另一个实例 下面是我的代码的样子: //Program.cs ..... if(myAppIsNotRunningYet) //the program has not been open yet { MyTray = new MyTray(); Application.Run(); } else

这是一个场景,我打开了我的应用程序,然后托盘图标显示,如果我双击托盘图标,将显示主界面。如果我再次打开我的应用程序,主界面应该得到关注,或者如果它还没有显示,那么应该显示它,而不是打开我的应用程序的另一个实例

下面是我的代码的样子:

//Program.cs
.....

if(myAppIsNotRunningYet) //the program has not been open yet
{
MyTray = new MyTray();
Application.Run();
}

else //the program is already on the tray
{
//the code to give focus to the mainForm or open it up if not yet open
}

//MyTray.cs
.....
public MyTray()
{
notifyIcon = new NotifyIcon();
....
notifyIcon.Visible = true;
}

private void notifyIcon_DoubleClick(object sender, EventArgs e)
{
MainForm mainForm = new MainForm();
mainForm.ShowDialog();
}

编辑:好的,似乎要正确覆盖WndProc,您必须使用可见/已可见的表单。下面是一个不同的解决方案。这确实有效,所以希望你能从这里开始

 internal sealed class Program
 { 
  /// <summary>
  /// Program entry point.
  /// </summary>
  [STAThread]
  public static void Main(string[] args)
  {
    bool newMutex;
    System.Threading.Mutex mutex = new System.Threading.Mutex(true, "{9F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}", out newMutex);

     // Attempt aquire the mutex
     if(newMutex)
     {
      // If we are able to aquire the mutex, it means the application is not running.
         Application.EnableVisualStyles();
         Application.SetCompatibleTextRenderingDefault(false);

         // Create the new tray icon
         MyTray myTray = new MyTray();

         Application.AddMessageFilter(myTray);
         Application.Run();

         // Release the mutex on exit
         mutex.ReleaseMutex();
     }
     else
     {
        // If the aquire attempt fails, the application is already running
        // so we broadcast a windows message to tell it to wake up.
         NativeMethods.PostMessage((IntPtr)NativeMethods.HWND_BROADCAST, NativeMethods.WM_SHOWME, IntPtr.Zero, IntPtr.Zero);
     }
     }
 }
}

internal class NativeMethods
 {
     public const int HWND_BROADCAST = 0xffff;
     public static readonly int WM_SHOWME = RegisterWindowMessage("WM_SHOWME");

     [DllImport("user32")]
     public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);

     [DllImport("user32")]     
     public static extern int RegisterWindowMessage(string message);
 }

 public class MyTray : IMessageFilter
 {
  private NotifyIcon notifyIcon = new NotifyIcon();
  private Form myForm = new Form();

  public MyTray()
  {
     this.notifyIcon.Icon = System.Drawing.Icon.FromHandle(new System.Drawing.Bitmap(16,16).GetHicon());
     this.notifyIcon.Visible = true;
     this.notifyIcon.DoubleClick += delegate(object sender, EventArgs e) { ShowForm(); };
  }

     void ShowForm()
     {
        this.notifyIcon.Visible = false;            
        this.myForm.ShowDialog();   
        this.notifyIcon.Visible = true;
      }

    public bool PreFilterMessage(ref Message m)
    {
       // If the message is the 'show me' message, then hide the icon and show the form.
       if(m.Msg == NativeMethods.WM_SHOWME)
       {
            if (!this.myForm.Visible)
            {
                ShowForm();
                return true; // Filter the message
            }
       }

       return false; // Forward the message
    }
 }
内部密封类程序
{ 
/// 
///程序入口点。
/// 
[状态线程]
公共静态void Main(字符串[]args)
{
布尔新互斥;
System.Threading.Mutex Mutex=new System.Threading.Mutex(true,{9F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F},out newMutex);
//尝试获取互斥
if(newMutex)
{
//如果我们能够获得互斥,这意味着应用程序没有运行。
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//创建新的托盘图标
MyTray MyTray=新建MyTray();
Application.AddMessageFilter(myTray);
Application.Run();
//退出时释放互斥锁
mutex.ReleaseMutex();
}
其他的
{
//如果获取尝试失败,则应用程序已在运行
//所以我们播放了一条windows消息,让它醒来。
NativeMethods.PostMessage((IntPtr)NativeMethods.HWND_广播,NativeMethods.WM_SHOWME,IntPtr.Zero,IntPtr.Zero);
}
}
}
}
内部类NativeMethods
{
公共常数int HWND_广播=0xffff;
公共静态只读int WM_SHOWME=RegisterWindowMessage(“WM_SHOWME”);
[DllImport(“user32”)]
公共静态外部bool PostMessage(IntPtr hwnd、int msg、IntPtr wparam、IntPtr lparam);
[DllImport(“user32”)]
公共静态外部int RegisterWindowMessage(字符串消息);
}
公共类MyTray:IMessageFilter
{
私有NotifyIcon NotifyIcon=新NotifyIcon();
私有表单myForm=新表单();
公共MyTray()
{
this.notifyIcon.Icon=System.Drawing.Icon.FromHandle(新的System.Drawing.Bitmap(16,16).GetHicon());
this.notifyIcon.Visible=true;
this.notifyIcon.DoubleClick+=委托(对象发送者,事件参数e){ShowForm();};
}
void ShowForm()
{
this.notifyIcon.Visible=false;
这个.myForm.ShowDialog();
this.notifyIcon.Visible=true;
}
公共bool预过滤器消息(参考消息m)
{
//如果消息是“显示我”消息,则隐藏图标并显示表单。
if(m.Msg==NativeMethods.WM_SHOWME)
{
如果(!this.myForm.Visible)
{
ShowForm();
return true;//过滤消息
}
}
return false;//转发消息
}
}

编辑:我收集了一个更接近您的场景的示例:

 internal sealed class Program
 {
  static System.Threading.Mutex mutex = new System.Threading.Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");

  /// <summary>
  /// Program entry point.
  /// </summary>
  [STAThread]
  private static void Main(string[] args)
  {
   // Attempt aquire the mutex
         if(mutex.WaitOne(TimeSpan.Zero, true))
         {
          // If we are able to aquire the mutex, it means the application is not running.
             Application.EnableVisualStyles();
             Application.SetCompatibleTextRenderingDefault(false);

             // Create the new tray icon
             MyTray myTray = new MyTray();

             Application.Run();

             // Release the mutex on exit
             mutex.ReleaseMutex();
         }
         else
         {
            // If the aquire attempt fails, the application is already running
            // so we broadcast a windows message to tell it to wake up.
             NativeMethods.PostMessage((IntPtr)NativeMethods.HWND_BROADCAST, NativeMethods.WM_SHOWME, IntPtr.Zero, IntPtr.Zero);
         }
     }
 }

 internal class NativeMethods
 {
     public const int HWND_BROADCAST = 0xffff;
     public static readonly int WM_SHOWME = RegisterWindowMessage("WM_SHOWME");

     [DllImport("user32")]
     public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);

     [DllImport("user32")]     
     public static extern int RegisterWindowMessage(string message);
 }

 public class MyTray : Control
 {
  private NotifyIcon notifyIcon = new NotifyIcon();

  public MyTray()
  {
   this.notifyIcon.Visible = true;
  }

  /// <summary>
  /// This method listens to all windows messages either broadcast or sent to this control
  /// </summary>
  protected override void WndProc(ref Message m)
  {
   // If the message is the 'show me' message, then hide the icon and show the form.
   if(m.Msg == NativeMethods.WM_SHOWME)
   {
    this.notifyIcon.Visible = false;
    using (Form mainForm = new Form())
    {
     mainForm.ShowDialog();
     this.notifyIcon.Visible = true;
    }  
   }
   else
   {
    base.WndProc(ref m);    
   }   
  }
 }
内部密封类程序
{
static System.Threading.Mutex Mutex=new System.Threading.Mutex(true,{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F});
/// 
///程序入口点。
/// 
[状态线程]
私有静态void Main(字符串[]args)
{
//尝试获取互斥
if(mutex.WaitOne(TimeSpan.Zero,true))
{
//如果我们能够获得互斥,这意味着应用程序没有运行。
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//创建新的托盘图标
MyTray MyTray=新建MyTray();
Application.Run();
//退出时释放互斥锁
mutex.ReleaseMutex();
}
其他的
{
//如果获取尝试失败,则应用程序已在运行
//所以我们播放了一条windows消息,让它醒来。
NativeMethods.PostMessage((IntPtr)NativeMethods.HWND_广播,NativeMethods.WM_SHOWME,IntPtr.Zero,IntPtr.Zero);
}
}
}
内部类NativeMethods
{
公共常数int HWND_广播=0xffff;
公共静态只读int WM_SHOWME=RegisterWindowMessage(“WM_SHOWME”);
[DllImport(“user32”)]
公共静态外部bool PostMessage(IntPtr hwnd、int msg、IntPtr wparam、IntPtr lparam);
[DllImport(“user32”)]
公共静态外部int RegisterWindowMessage(字符串消息);
}
公共类MyTray:控件
{
私有NotifyIcon NotifyIcon=新NotifyIcon();
公共MyTray()
{
this.notifyIcon.Visible=true;
}
/// 
///此方法侦听广播或发送到此控件的所有windows消息
/// 
受保护的覆盖无效WndProc(参考消息m)
{
//如果消息是“显示我”消息,则隐藏图标并显示表单。
if(m.Msg==NativeMethods.WM_SHOWME)
{
this.notifyIcon.Visible=false;
使用(Form mainForm=new Form())
{
mainForm.ShowDialog();
this.notifyIcon.Visible=true;
}  
}
其他的
{
基准WndProc(参考m);
}   
}
}

编辑:我在C#中找到了一个结合互斥和windows消息的示例:



互斥可能是最好的方式。将此消息与应用程序侦听的自定义windows消息相结合,以使其成为焦点(请参阅)

查看此示例:

我认为您无法在其他应用程序的窗口上引发事件(即使它们是相同的可执行文件)


不过,我解决这个问题的方法是使用一些命令来告诉正在运行的实例打开主窗口。同样的IPC机制也可以用来确定另一个实例是否正在运行。

您也可以看看其中的乐趣