WPF实现单例运行 - 唯一实例运行

使用互斥量保持wpf程序唯一实例运行

public void CheckSingleInstanceAndStartMainApp(){
             bool singleInstance = false;
             System.Threading.Mutex singleInstanceMutex = new System.Threading.Mutex(true, "singleInstance", out singleInstance);
             if (!singleInstance) {
                 //程序已经运行直接return
                 return ;
             }

             //启动程序
             (new MainApp).Start();

             //保持互斥量不被垃圾回收器回收
             GC.KeepAlive(singleInstance); 
        }

在程序已经运行情况下,如何激活程序并置顶,通过API: SetForegroundWindow + ShowWindow + FindWindow

 public void ActiveAndShowToFront(string titleName) {
            //s1:通过WAPi:FindWindow获取运行实例的句柄
            //或者事先保存实例,传递过来
            IntPtr hWndPtr = FindWindow(null, titleName);

            //s2;显示窗体
            ShowWindow(hWndPtr);

            //s3: 置顶
            SetForegroundWindow(hWndPtr);
        }

单例运行 + 置顶,修改后的CheckSingleInstanceAndStartMainApp()方法 :

public void CheckSingleInstanceAndStartMainApp(){
             bool singleInstance = false;
             System.Threading.Mutex singleInstanceMutex = new System.Threading.Mutex(true, "singleInstance", out singleInstance);
             if (!singleInstance) {
                 //显示窗体
                 ActiveAndShowToFront();
                 //程序已经运行直接return
                 return ;
             }

             //启动程序
             (new MainApp).Start();

             //保持互斥量不被垃圾回收器回收
             GC.KeepAlive(singleInstance); 
        }


如果运行示例最小话到系统托盘,这个时候显示需要重写修复程序,可以处理WM_SHOWFIRSTINSTANCE消息,完整代码:

public static class OneInstance
	{
		private static class NativeMethods
		{
			[DllImport( "user32", CharSet = CharSet.Unicode)]
			private static extern int RegisterWindowMessage( string message );

			public static int RegisterWindowMessage( string format, params object[] args )
			{
				var message = String.Format( format, args );
				return RegisterWindowMessage( message );
			}

			public const int HwndBroadcast = 0xffff;

			[DllImport("user32", CharSet = CharSet.Unicode)]
			public static extern bool PostMessage( IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam );
		}

		private static class ProgramInfo
		{
			static public string AssemblyGuid
			{
				get
				{
					var attributes = Assembly.GetEntryAssembly().GetCustomAttributes( typeof( GuidAttribute ), false );
					return attributes.Length == 0 ?
						String.Empty :
						( (GuidAttribute)attributes[0] ).Value;
				}
			}
		}

		private static readonly int WmShowfirstinstance =
			NativeMethods.RegisterWindowMessage( "WM_SHOWFIRSTINSTANCE|{0}", ProgramInfo.AssemblyGuid );

		public static class MainWindow
		{
			private static Window owner;
			public static bool Init(Window ownerWindow)
			{
				owner = ownerWindow;
				owner.SourceInitialized += WindowInitialized;
				return App.CreatedNew;
			}

			private static void WindowInitialized( object sender, EventArgs eventArgs )
			{
				var source = HwndSource.FromHwnd( new WindowInteropHelper( owner ).Handle );
				source.AddHook( WindowProc );
			}

			private static IntPtr WindowProc( IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam, ref bool Handled )
			{
				if ( Msg == WmShowfirstinstance )
				{
					owner.Show();
					owner.WindowState = WindowState.Normal;
					owner.Activate();
					owner.Focus();
				}
				return IntPtr.Zero;
			}
		}

		public static class App
		{
			private static volatile Mutex mutex;
			private static bool createdNew;
			public static bool CreatedNew { get { return createdNew; } }
			public static event EventHandler AfterExit;

			[STAThread]
			private static void Exit( object sender, ExitEventArgs e )
			{
				if (createdNew)
				{
					mutex.Dispose();
				}
				if (AfterExit != null) AfterExit(Application.Current, null);
			}

			private static void Startup( object sender, StartupEventArgs e )
			{
				if (createdNew) return;
				NativeMethods.PostMessage(
					(IntPtr)NativeMethods.HwndBroadcast,
					WmShowfirstinstance,
					IntPtr.Zero,
					IntPtr.Zero );
				Application.Current.Shutdown( 0 );
			}

			[STAThread]
			public static void Init(Application app)
			{
				var mutexName = String.Format("Global\\{0}", ProgramInfo.AssemblyGuid);
				mutex = new Mutex(true, mutexName, out createdNew);
				if (!createdNew)
				{
					mutex.Dispose();
				}
				app.Startup += Startup;
				app.Exit += Exit;
			}
		}

	}



你可能感兴趣的:(代码片段)