【问题标题】:run single instance desktop app that minimized to system tray运行最小化到系统托盘的单实例桌面应用程序
【发布时间】:2021-05-17 08:01:06
【问题描述】:

我有一个带有 c# 和框架 4.6 的 Windows 桌面应用程序 该应用程序在系统托盘中运行,并且桌面上有一个快捷方式图标 当用户单击图标运行它如果应用程序已经运行不运行新实例,只显示(带到前面)现有应用程序

public sealed class SingleInstance
{
    private const int SW_HIDE = 0;
    private const int SW_SHOW = 5;

    public static bool AlreadyRunning()
    {
        bool running = false;
        try
        {
            // Getting collection of process  
            Process currentProcess = Process.GetCurrentProcess();

            // Check with other process already running   
            foreach (var p in Process.GetProcesses())
            {
                if (p.Id != currentProcess.Id) // Check running process   
                {
                    if (p.ProcessName.Equals(currentProcess.ProcessName) == true)
                    {
                        running = true;
                        IntPtr hFound = p.MainWindowHandle;
                        if (User32API.IsIconic(hFound)) // If application is in ICONIC mode then  
                            User32API.ShowWindow(hFound, User32API.SW_RESTORE);
                        User32API.SetForegroundWindow(hFound); // Activate the window, if process is already running  
                        break;
                    }
                }
            }
        }
        catch { }

        return running;
    }
}

public class User32API
{
    [DllImport("User32.dll")]
    public static extern bool IsIconic(IntPtr hWnd);

    [DllImport("User32.dll")]
    public static extern bool SetForegroundWindow(IntPtr hWnd);

    [DllImport("User32.dll")]
    public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    public const int SW_SHOW = 5;
    public const int SW_RESTORE = 9;
}

如果应用程序在它可以显示的任何窗口后运行(带到前面)但它在系统托盘中无法显示

编辑: 最小化到托盘

private void Form1_Resize(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                Hide();
            }
        }

打开

 private void notifyIcon1_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
            this.Show();
            this.WindowState = FormWindowState.Normal;
        }

【问题讨论】:

  • VisualBasic dll 对此有一个有用的功能,请参阅docs.microsoft.com/en-us/dotnet/visual-basic/developing-apps/… 但本质上我记得您导入了 VB dll,使用其应用程序库而不是默认应用程序库,将应用程序设置为单一实例,向 StartupNextInstance 添加一个处理程序,并且任何启动另一个实例的 atttenpts 都会导致事件处理程序触发。我认为它甚至将命令行参数传递给正在运行的实例
  • 最小化到托盘时,你是怎么做的?
  • private void Form1_Resize(object sender, EventArgs e) { if (this.WindowState == FormWindowState.Minimized) { Hide(); } } private void notifyIcon1_Click(object sender, EventArgs e) { this.WindowState = FormWindowState.Minimized; this.Show(); this.WindowState = FormWindowState.Normal; }

标签: c# windows desktop-application


【解决方案1】:

您可以实现 Mutex 以确保只有一个应用程序实例在运行。您还可以使用它在实例之间进行通信,以便第二个实例可以通知第一个实例用户再次尝试启动您的应用程序。

这里已经有一个很好的答案:https://stackoverflow.com/a/522874/14877741

它比我更好地解释了 Mutex 概念,它甚至还有一个将应用程序窗口带回前台的示例。

【讨论】:

  • 感谢它有效,但我更改了 Show 方法以将表单放在前面 this.WindowState = FormWindowState.Minimized; this.Show(); this.WindowState = FormWindowState.Normal;
  • protected override void WndProc(ref Message m) 仅在以管理员模式运行时有效
  • 但我无法以管理员模式运行该应用程序,因为它在启动时工作,在启动时它要求运行程序
猜你喜欢
  • 2011-11-29
  • 2019-10-30
  • 1970-01-01
  • 1970-01-01
  • 2017-11-15
  • 2010-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多