winforms 如何显示现有的(但隐藏的)WinForm?

mkshixfv  于 2022-11-17  发布在  其他
关注(0)|答案(1)|浏览(169)

我正在创建一个WinForm应用程序(.Net-5,.Net Core)。我的WinForm示例可能被最小化/隐藏。每当我启动应用程序时,我都需要检查是否有该应用程序的现有示例正在运行。如果已经有一个现有示例,我需要显示其WinForm,而不是创建新示例。
在下面的代码中,我总是检查是否存在现有的进程。如果是,我如何显示打开的表单/GUI?

/// <summary>
    ///  The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        var runningProcess = System.Diagnostics.Process.GetProcessesByName(System.IO.Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location));
       
        if (runningProcess.Length>1) // Already running processes
        {
            //Get our previous instance
            Process myProcess = runningProcess[0];

            //How to SHOW the already exisitng (but minimized) instance of the Form?
            //--?
            //--?

        }
        else
        {
            Application.SetHighDpiMode(HighDpiMode.SystemAware);
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MyGUI());
        }
    }
fnvucqvd

fnvucqvd1#

不再支援.NET 5。如需详细信息,请参阅here。您可以考虑将项目移至.NET 6。
下面显示了一种确保只有一个Windows窗体应用示例在运行的方法。如果该示例处于最小化或隐藏状态,则会显示该示例。该代码已在Windows 10上使用新的Windows Forms App项目(.NET 6)进行了测试。
在下面的代码中,当窗体隐藏时,p.MainWindowHandle为IntPtr. Zero。因此,我使用了FindWindowA,它使用窗口标题查找所需的窗口,如here所述。Form1是创建新的Windows窗体项目时存在的默认窗体-窗体的窗口文本“Form 1”应更改为所需的窗口标题。

程序.cs

using System.Runtime.InteropServices;
using System.Diagnostics;

namespace TestAllowSingleInstance
{
    internal static class Program
    {
        /// <summary>
        ///  The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            [DllImport("user32.dll", SetLastError = true)]
            static extern IntPtr FindWindowA(string? lpClassName, string lpWindowName);

            [DllImport("user32.dll")]
            static extern bool IsIconic(IntPtr hWnd);

            [DllImport("user32.dll")]
            static extern IntPtr SetFocus(IntPtr hWnd);

            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            static extern bool SetForegroundWindow(IntPtr hWnd);

            //sets window's show state - doesn't wait for operation to complete
            [DllImport("user32.dll")]
            static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);

            using (Process curProcess = Process.GetCurrentProcess())
            {
                foreach (Process p in Process.GetProcessesByName(curProcess.ProcessName))
                {
                    if (p.Id != curProcess.Id && p.MainModule?.FileName == curProcess.MainModule?.FileName)
                    {
                        //set as foreground (ie: show on top of other windows)
                        SetForegroundWindow(p.MainWindowHandle);

                        if (IsIconic(p.MainWindowHandle))
                        {
                            //minimized
                            ShowWindowAsync(p.MainWindowHandle, 9); //SW_RESTORE = 9
                        }
                        else
                        {
                            IntPtr hwnd = p.MainWindowHandle;

                            //when the window is hidden, the MainWindowHandle = IntPtr.Zero
                            if (p.MainWindowHandle == IntPtr.Zero)
                            {
                                //window is hidden, find it by the title

                                //"Form1" is the title that is displayed on the Window
                                hwnd = FindWindowA(null, "Form1");
                            }

                            ShowWindowAsync(hwnd, 1); //SW_SHOWNORMAL = 1; SW_SHOWMAXIMIZED = 3
                        }

                        //set focus
                        SetFocus(p.MainWindowHandle);

                        Environment.Exit(0);
                    }
                }
            }

            // To customize application configuration such as set high DPI settings or default font,
            // see https://aka.ms/applicationconfiguration.
            ApplicationConfiguration.Initialize();
            Application.Run(new Form1());
        }
    }
}

资源

相关问题