C# 带有最小化到托盘的单实例Windows窗体应用程序

C# 带有最小化到托盘的单实例Windows窗体应用程序,c#,.net,winforms,C#,.net,Winforms,我有一个名为“Restoring.exe”的WinForm应用程序示例。在最小化窗口的同时,它将移动到系统托盘并隐藏在任务栏中。如果单击系统托盘中的通知图标,窗口将出现在前面 public void notifyicon_MouseClick(object sender, System.EventArgs e) { notifyicon.Visible = false; Show(); Activate(); TopMost = true; BringTo

我有一个名为“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());
    }
}
public void Restore()
{
    notifyicon.Visible = false;
    Show();
    Activate();
    TopMost = true;
    BringToFront();
    this.WindowState = FormWindowState.Normal;
} 
Form1.cs:

static void Main()
{
    if (IsServiceManagerAlreadyRunning())
    {
        Form1 form1 = new Form1();
        form1.Restore();
    }
    else
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}
public void Restore()
{
    notifyicon.Visible = false;
    Show();
    Activate();
    TopMost = true;
    BringToFront();
    this.WindowState = FormWindowState.Normal;
} 
我的实际问题是,如果应用程序已经在运行,则“还原”方法正在运行,其中列出的所有操作都在运行,并且窗口显示在前面但在完成这些操作后,该窗口再次转到系统托盘。没有坐在前面。


有人能提供一个解决方案吗

我认为这是您所需要的:-

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();
            }
        }

    }

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

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

您可以尝试按窗口标题或更复杂的解决方案查找窗口。在谷歌搜索“windows应用程序单实例”时,返回了大量文章。

制作单实例 将对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
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [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());
        }
    }
}

@KathirSubramaniam不客气:),它在这里工作正常,如果您有任何问题,请告诉我。@KathirSubramaniam是的,您可以访问outlook.com上的r.aghaei。我仔细检查了代码和示例,它工作正常。也许你做错了什么,你唯一需要更改的是你的主窗体的名称。@KathirSubramaniam嗨,Kathir,我检查了你的代码,正如我所说的,你在执行一些错误的操作。您正在将互斥解决方案与此应用程序控制器解决方案混合使用,这将不起作用。使用此应用程序控制器生成单个应用程序时,您应该做的唯一一件事是在program.cs中只放入我的代码,并在我的代码中使用
new Form1()
,而不是
new YourMainForm()
。@KathirSubramaniam,而且我认为您也应该使用NotifyIcon阅读我答案的一部分。我强烈推荐我编写代码的方式。