1. 程式人生 > >.net 桌面端程式 保證只啟動一個程序例項

.net 桌面端程式 保證只啟動一個程序例項

1 建立wcf程序服務

        public static IOperateSevice GetSevice()
        {
            NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
            binding.MaxReceivedMessageSize = 2147483647;
            binding.CloseTimeout = TimeSpan.FromMinutes(3);
            binding.OpenTimeout = TimeSpan.FromMinutes(3);
            binding.ReceiveTimeout = TimeSpan.FromMinutes(3);
            binding.SendTimeout = TimeSpan.FromMinutes(3);
            EndpointAddress addr = new EndpointAddress("net.pipe://localhost/Client/WCFSevice");
//   建立一個指定型別的通道,該通道用於將訊息傳送到用指定繫結進行配置的服務終結點。
            ChannelFactory<IOperateSevice> cf = new ChannelFactory<IOperateSevice>(binding, addr); 
            return cf.CreateChannel();
        }

2  程序啟動後儲存當前視窗控制代碼

  WcfServer.GetSevice().SaveIEBarHandle(this.Handle);

3 獲取當前程序的名稱

 string strProcessName = System.Diagnostics.Process.GetCurrentProcess().ProcessName;

4 查詢當前電腦所有此名稱的程序

   System.Diagnostics.Process[] ps = System.Diagnostics.Process.GetProcessesByName(strProcessName);

5 判斷是否大於1個,大於1個,殺死多餘執行緒,或者顯示之前關閉的視窗

 if (ps.Length > 1)
            {
 
            }

6 判斷wcf服務是否含有視窗控制代碼,已經含有就展示之前程序的視窗

 IntPtr handle = WcfServer.GetSevice().GetClientHandle();
                    if (handle != IntPtr.Zero)
                    {
                        WindowsApi.ShowWindow(handle, 1);
                        return;
                    }

7 否則殺死多餘程序

  foreach (var p in ps)
                        {
                            if (p.Id != System.Diagnostics.Process.GetCurrentProcess().Id)
                                p.Kill();
                        }

8 通過控制代碼展示視窗方法


        [DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)]         //顯示視窗
        public static extern IntPtr ShowWindow(IntPtr hwnd, int nCmdShow);

完整程式碼

    /// <summary>
        /// 應用程式的主入口點。
        /// </summary>
        [STAThread]
        static void Main(string[] Args)
        {
            //檢查是否在執行,保證每次只執行一個例項
            string strProcessName = System.Diagnostics.Process.GetCurrentProcess().ProcessName;
            System.Diagnostics.Process[] ps = System.Diagnostics.Process.GetProcessesByName(strProcessName);
          
            if (ps.Length > 1)
            {
                try
                {
                    IntPtr handle = WcfServer.GetSevice().GetHandle();
                    if (handle != IntPtr.Zero)
                    {
                        WindowsApi.ShowWindow(handle, 1);
                        return;
                    }
                    else
                    {
                        foreach (var p in ps)
                        {
                            if (p.Id != System.Diagnostics.Process.GetCurrentProcess().Id)
                                p.Kill();
                        }
                    }
                }
                catch
                {
                    foreach (var p in ps)
                    {
                        if (p.Id != System.Diagnostics.Process.GetCurrentProcess().Id)
                            p.Kill();
                    }
                }
            }
 
            Application.Run(new Login()); 

        }