单实例Windows窗体应用程序,最小化托盘

我有一个名为“Restoring.exe”的示例WinForm应用程序。 在最小化窗口的同时,它将移动到系统托盘并隐藏在任务栏中。 如果单击系统托盘中的通知图标,则窗口将显示在前面。

public void notifyicon_MouseClick(object sender, System.EventArgs e) { notifyicon.Visible = false; Show(); Activate(); TopMost = true; BringToFront(); this.WindowState = FormWindowState.Normal; } 

但我的实际要求是,在第二次单击应用程序时,需要从系统托盘恢复应用程序。

为此,我尝试了下面的代码

Program.cs中:

 static void Main() { if (IsServiceManagerAlreadyRunning()) { Form1 form1 = new Form1(); form1.Restore(); } else { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } 

Form1.cs中:

 public void Restore() { notifyicon.Visible = false; Show(); Activate(); TopMost = true; BringToFront(); this.WindowState = FormWindowState.Normal; } 

我的实际问题是 ,如果应用程序已经运行,则“恢复”方法正在命中,并且其中列出的所有操作都在运行,并且窗口显示在前面。 但在完成这些操作后,窗口再次进入系统托盘。 不坐在前面。

有人可以为此提供解决方案吗?

制作单一实例

Microsoft.VisualBasic.dll的引用添加到项目中,并将此类添加到项目中:

 using System; using Microsoft.VisualBasic.ApplicationServices; using System.Windows.Forms; namespace Sample { public class ApplicationController : WindowsFormsApplicationBase { private Form mainForm; public ApplicationController(Form form) { //We keep a reference to main form //To run and also use it when we need to bring to front mainForm = form; this.IsSingleInstance = true; this.StartupNextInstance += this_StartupNextInstance; } void this_StartupNextInstance(object sender, StartupNextInstanceEventArgs e) { //Here we bring application to front e.BringToForeground = true; mainForm.ShowInTaskbar = true; mainForm.WindowState = FormWindowState.Minimized; mainForm.Show(); mainForm.WindowState = FormWindowState.Normal; } protected override void OnCreateMainForm() { this.MainForm = mainForm; } } } 

然后在Program.cs使用ApplicationController来运行程序:

 using System; using System.Windows.Forms; namespace Sample { static class Program { ///  /// The main entry point for the application. ///  [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); //create a controller and Pass an instance of your application main form var controller = new Sample.ApplicationController(new YourMainForm()); //Run application controller.Run(Environment.GetCommandLineArgs()); } } } 

现在您的应用程序是单实例,当您单击您的exe文件时,而不是运行另一个实例,将现有实例放在前面。

使用NotifyIcon

NotifyIcon放在主窗体上,然后在单击最小化按钮时隐藏窗口,并在单击通知图标时显示窗口,您可以处理这些事件:

 //When click on notify icon, we bring the form to front private void notifyIcon_Click(object sender, EventArgs e) { this.ShowInTaskbar = true; this.WindowState = FormWindowState.Minimized; this.Show(); this.WindowState = FormWindowState.Normal; } //here we check if the user minimized window, we hide the form private void ApplicationMainForm_Resize(object sender, EventArgs e) { if (this.WindowState == FormWindowState.Minimized) { this.ShowInTaskbar = false; this.Hide(); } } //when the form is hidden, we show notify icon and when the form is visible we hide it private void ApplicationMainForm_VisibleChanged(object sender, EventArgs e) { this.notifyIcon1.Visible = !this.Visible; } 

问题是main()中if块的两个分支都创建了一个新表单,因此您没有对已经运行的表单执行任何操作。

如果程序的某个实例已在运行( IsServiceManagerAlreadyRunning() == true?),则需要从第一个实例中找到该窗口并将其激活,而不是创建新的Form。

您可以尝试按窗口标题或更复杂的解决方案查找窗口。 在Google上搜索“Windows应用程序单实例”返回了一些文章。

我觉得这就像你需要的东西: –

 public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void notifyIcon1_Click(object sender, EventArgs e) { this.Show(); this.WindowState = FormWindowState.Normal; } private void Form1_ResizeBegin(object sender, EventArgs e) { if (WindowState == FormWindowState.Minimized) { this.Hide(); } } }