C# SetForegroundWindow无法工作。

9 浏览
0 Comments

C# SetForegroundWindow无法工作。

我使用这个问题How to force C# .net app to run only one instance in Windows?将我的C#Windows应用程序限制为一次只能运行一个实例。

它工作得很好,并且不允许同时运行多个应用程序实例。

问题在于,如果用户尝试打开第二个应用程序实例,我希望当前活动的实例能够前置显示。

我所使用的问题似乎解决了这个问题,但对我来说并不起作用。

我认为这是因为我的应用程序未满足允许方法:SetForegroundWindow工作的条件。

我的问题是,我该如何实现这一点。我的代码如下:

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace RTRFIDListener_Client
{
    static class Program
    {
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool SetForegroundWindow(IntPtr hWnd);
        /// 
        /// The main entry point for the application.
        /// 
        [STAThread]
        static void Main()
        {
            bool createdNew = true;
            using (Mutex mutex = new Mutex(true, "RTRFIDListener_Client", out createdNew))
            {
                if (createdNew)
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new frm_Main());
                }
                else
                {
                    Process current = Process.GetCurrentProcess();
                    foreach (Process process in Process.GetProcessesByName(current.ProcessName))
                    {
                        if (process.Id != current.Id)
                        {
                            SetForegroundWindow(process.MainWindowHandle);
                            break;
                        }
                    }
                }
            }
        }
    }
}

0
0 Comments

问题的原因是忘记添加对Microsoft.VisualBasic的引用。解决方法是在Program.cs文件中添加对Microsoft.VisualBasic.ApplicationServices的引用,并在OnStartupNextInstance事件处理程序中设置eventArgs.BringToForeground = true。以下是整理后的文章:

在编写单实例应用程序时,自己编写代码可能是一个错误,因为.NET Framework已经提供了强大且稳定的支持。它具有您需要的功能,即在用户再次启动应用程序时触发StartupNextInstance事件。只需添加对Microsoft.VisualBasic的引用,并将Program.cs文件修改如下:

using System;
using System.Windows.Forms;
using Microsoft.VisualBasic.ApplicationServices;
namespace WhatEverYouUse {
    class Program : WindowsFormsApplicationBase {
        [STAThread]
        static void Main(string[] args) {
            Application.SetCompatibleTextRenderingDefault(false);
            new Program().Start(args);
        }
        void Start(string[] args) {
            this.EnableVisualStyles = true;
            this.IsSingleInstance = true;
            this.MainForm = new Form1();
            this.Run(args);
        }
        protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs) {
            eventArgs.BringToForeground = true;
            base.OnStartupNextInstance(eventArgs);
        }
    }
}

如果您需要使用启动第二个实例时使用的命令行参数,例如使用文件关联时,可以在事件处理程序中使用eventArgs.CommandLine。如果遇到了“类型或命名空间'Microsoft.VisualBasic.ApplicationServices;'不存在”的错误,请仔细按照指示操作,您可能忘记了添加引用。

有人问道是否在OnStartupNextInstance中设置eventArgs.BringToForeground = true会更好。这样做也可以,但是记得在之后调用base.StartupNextInstance()。

0
0 Comments

问题原因:C#中的SetForegroundWindow函数无法正常工作。

解决方法:尝试使用以下代码来解决问题。

System.Threading.Tasks.Task.Factory.StartNew(() => { SetForegroundWindow(this.Handle); });

这段代码可以解决问题的原因和如何解决问题,请在回答中添加一些解释。只有代码的回答不适合在SO上使用。请为你的回答添加一些上下文。只有代码的回答在SO上不被认为是好的风格。为什么这个解决方法能够解决问题?

0