国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

WinForm防止程序重復運行的方法分析

2019-10-29 21:10:15
字體:
來源:轉載
供稿:網友

本文實例講述了WinForm防止程序重復運行的方法。分享給大家供大家參考,具體如下:

需求:

1、點擊“關閉”按鈕時,程序最小化到托盤,并沒有退出,這時再次運行程序,不會重復運行,而是顯示已運行的程序;
2、支持不同目錄;
3、支持修改名稱。

代碼(不支持修改名稱,不支持不同目錄):

using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;using System.Windows.Forms;using Tool;using System.Diagnostics;using System.Reflection;using System.Runtime.InteropServices;namespace 計算器{  static class Program  {    [DllImport("user32.dll")]    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);    /// <summary>    /// 該函數設置由不同線程產生的窗口的顯示狀態。    /// </summary>    /// <param name="hWnd">窗口句柄</param>    /// <param name="cmdShow">指定窗口如何顯示。查看允許值列表,請查閱ShowWlndow函數的說明部分。</param>    /// <returns>如果函數原來可見,返回值為非零;如果函數原來被隱藏,返回值為零。</returns>    [DllImport("User32.dll")]    private static extern bool ShowWindow(IntPtr hWnd, int cmdShow);    /// <summary>    /// 該函數將創建指定窗口的線程設置到前臺,并且激活該窗口。鍵盤輸入轉向該窗口,并為用戶改各種可視的記號。系統給創建前臺窗口的線程分配的權限稍高于其他線程。    /// </summary>    /// <param name="hWnd">將被激活并被調入前臺的窗口句柄。</param>    /// <returns>如果窗口設入了前臺,返回值為非零;如果窗口未被設入前臺,返回值為零。</returns>    [DllImport("User32.dll")]    private static extern bool SetForegroundWindow(IntPtr hWnd);    private const int SW_SHOWNORMAL = 1;    /// <summary>    /// 應用程序的主入口點。    /// </summary>    [STAThread]    static void Main()    {      Application.EnableVisualStyles();      Application.SetCompatibleTextRenderingDefault(false);      Process processes = RunningInstance();      if (processes == null)      {        Application.Run(new Form1());      }      else      {        HandleRunningInstance(processes);      }    }    /// <summary>    /// 獲取正在運行的實例,沒有運行的實例返回null;    /// </summary>    public static Process RunningInstance()    {      Process current = Process.GetCurrentProcess();      Process[] processes = Process.GetProcessesByName(current.ProcessName);      foreach (Process process in processes)      {        if (process.Id != current.Id)        {          if (Assembly.GetExecutingAssembly().Location.Replace("/", "//") == current.MainModule.FileName)          {            return process;          }        }      }      return null;    }    /// <summary>    /// 顯示已運行的程序。    /// </summary>    public static void HandleRunningInstance(Process instance)    {      try      {        IntPtr formHwnd = FindWindow(null, "計算器");        ShowWindow(formHwnd, SW_SHOWNORMAL);  //顯示        SetForegroundWindow(formHwnd);     //放到前端      }      catch (Exception ex)      {        MessageBox.Show(ex.Message);      }    }  }}

代碼(支持修改名稱,支持不同目錄):

using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;using System.Windows.Forms;using Tool;using System.Diagnostics;using System.Reflection;using System.Runtime.InteropServices;namespace 計算器{  static class Program  {    [DllImport("user32.dll")]    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);    /// <summary>    /// 該函數設置由不同線程產生的窗口的顯示狀態。    /// </summary>    /// <param name="hWnd">窗口句柄</param>    /// <param name="cmdShow">指定窗口如何顯示。查看允許值列表,請查閱ShowWlndow函數的說明部分。</param>    /// <returns>如果函數原來可見,返回值為非零;如果函數原來被隱藏,返回值為零。</returns>    [DllImport("User32.dll")]    private static extern bool ShowWindow(IntPtr hWnd, int cmdShow);    /// <summary>    /// 該函數將創建指定窗口的線程設置到前臺,并且激活該窗口。鍵盤輸入轉向該窗口,并為用戶改各種可視的記號。系統給創建前臺窗口的線程分配的權限稍高于其他線程。    /// </summary>    /// <param name="hWnd">將被激活并被調入前臺的窗口句柄。</param>    /// <returns>如果窗口設入了前臺,返回值為非零;如果窗口未被設入前臺,返回值為零。</returns>    [DllImport("User32.dll")]    private static extern bool SetForegroundWindow(IntPtr hWnd);    private const int SW_SHOWNORMAL = 1;    /// <summary>    /// 應用程序的主入口點。    /// </summary>    [STAThread]    static void Main()    {      Common.AutoRegister();      Application.EnableVisualStyles();      Application.SetCompatibleTextRenderingDefault(false);      bool createNew;      using (System.Threading.Mutex m = new System.Threading.Mutex(true, Application.ProductName, out createNew))      {        if (createNew)        {          FileOperator.SetValue("ProcessId", Process.GetCurrentProcess().Id.ToString()); //進程ID寫入文件          Application.Run(new Form1());        }        else        {          try          {            string strProcessId = FileOperator.GetValue("ProcessId"); //從文件中獲取進程ID            int processId = Convert.ToInt32(strProcessId);            Process process = Process.GetProcessById(processId);            HandleRunningInstance(process);          }          catch          {            FileOperator.SetValue("ProcessId", Process.GetCurrentProcess().Id.ToString()); //進程ID寫入文件            Application.Run(new Form1());          }        }      }    }    /// <summary>    /// 顯示已運行的程序。    /// </summary>    public static void HandleRunningInstance(Process instance)    {      try      {        IntPtr formHwnd = FindWindow(null, "計算器");        ShowWindow(formHwnd, SW_SHOWNORMAL);  //顯示        SetForegroundWindow(formHwnd);     //放到前端      }      catch (Exception ex)      {        MessageBox.Show(ex.Message);      }    }  }}

其實,IntPtr formHwnd = FindWindow(null, "計算器"); 這段代碼是有BUG的,比如你打開一個名為“計算器”的文件夾,那么FindWindow找到的其實是這個文件夾,而不是計算器程序。我們可以在主窗體第一次顯示的時候,記下窗口句柄,代碼如下:

private void Form1_Shown(object sender, EventArgs e){  FileOperator.SetValue("hwnd", Process.GetCurrentProcess().MainWindowHandle.ToString());}

然后,顯示已運行的程序時,從文件中讀取之前記錄的窗口句柄,代碼如下:

/// <summary>/// 顯示已運行的程序/// </summary>public static void HandleRunningInstance(Process instance){  try  {    IntPtr hwnd = new IntPtr(Convert.ToInt32(FileOperator.GetValue("hwnd")));    ShowWindow(hwnd, SW_SHOWNORMAL); //顯示    SetForegroundWindow(hwnd); //放到前端  }  catch (Exception ex)  {    MessageBox.Show(ex.Message);  }}

綜上,再整理一下,就能得到完美的解決方案。

希望本文所述對大家C#程序設計有所幫助。


注:相關教程知識閱讀請移步到c#教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 辉县市| 四川省| 西畴县| 明星| 青阳县| 沙坪坝区| 阿鲁科尔沁旗| 荣成市| 丰宁| 宿州市| 江达县| 邯郸县| 绥芬河市| 门源| 舟曲县| 邢台县| 新龙县| 和顺县| 长兴县| 盱眙县| 乌拉特后旗| 岗巴县| 崇礼县| 永吉县| 广安市| 南京市| 德安县| 万州区| 兴海县| 象山县| 京山县| 遵义市| 应城市| 吉林市| 榆社县| 平顶山市| 中西区| 偃师市| 宁乡县| 麻江县| 筠连县|