C# SetForegroundWindow无法工作。
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; } } } } } } }
问题的原因是忘记添加对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()。