简体   繁体   中英

C# SetForegroundWindow not working

I have restricted my C# windows application to only allow one instance to be running at a time, using this question How to force C# .net app to run only one instance in Windows?

It works well and does not allow more than one instance of the application to run at the same time.

The problem is that if the user attempts to open a second instance of the application, I want the currently active one to come to the front.

The question I worked from seems to address this, but it is not working for me.

I think it is because my application is not meeting the criteria to allow the method : SetForegroundWindow to work.

My question is, how can I achieve this. My code is below:

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

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [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;
                        }
                    }
                }
            }
        }
    }
}

Spinning your own single-instance app is generally a mistake, the .NET Framework already supports it strongly and it is rock-solid, very hard to exploit. And has the feature you are looking for, a StartupNextInstance event that fires when the user starts your app again. Add a reference to Microsoft.VisualBasic and make your Program.cs file look like this:

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

If you have any use for the command line arguments that were used to start the 2nd instance, typical when you use a file association for example, then use eventArgs.CommandLine in your event handler.

尝试这个...

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM