一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - C# - WinForm防止程序重復(fù)運(yùn)行的方法分析

WinForm防止程序重復(fù)運(yùn)行的方法分析

2022-01-06 13:00何問(wèn)起 C#

這篇文章主要介紹了WinForm防止程序重復(fù)運(yùn)行的方法,通過(guò)記錄窗口句柄實(shí)現(xiàn)防止WinForm程序重復(fù)運(yùn)行的功能,需要的朋友可以參考下

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

需求:

1、點(diǎn)擊“關(guān)閉”按鈕時(shí),程序最小化到托盤,并沒(méi)有退出,這時(shí)再次運(yùn)行程序,不會(huì)重復(fù)運(yùn)行,而是顯示已運(yùn)行的程序;
2、支持不同目錄;
3、支持修改名稱。

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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 計(jì)算器
{
  static class Program
  {
    [DllImport("user32.dll")]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    /// <summary>
    /// 該函數(shù)設(shè)置由不同線程產(chǎn)生的窗口的顯示狀態(tài)。
    /// </summary>
    /// <param name="hWnd">窗口句柄</param>
    /// <param name="cmdShow">指定窗口如何顯示。查看允許值列表,請(qǐng)查閱ShowWlndow函數(shù)的說(shuō)明部分。</param>
    /// <returns>如果函數(shù)原來(lái)可見(jiàn),返回值為非零;如果函數(shù)原來(lái)被隱藏,返回值為零。</returns>
    [DllImport("User32.dll")]
    private static extern bool ShowWindow(IntPtr hWnd, int cmdShow);
    /// <summary>
    /// 該函數(shù)將創(chuàng)建指定窗口的線程設(shè)置到前臺(tái),并且激活該窗口。鍵盤輸入轉(zhuǎn)向該窗口,并為用戶改各種可視的記號(hào)。系統(tǒng)給創(chuàng)建前臺(tái)窗口的線程分配的權(quán)限稍高于其他線程。
    /// </summary>
    /// <param name="hWnd">將被激活并被調(diào)入前臺(tái)的窗口句柄。</param>
    /// <returns>如果窗口設(shè)入了前臺(tái),返回值為非零;如果窗口未被設(shè)入前臺(tái),返回值為零。</returns>
    [DllImport("User32.dll")]
    private static extern bool SetForegroundWindow(IntPtr hWnd);
    private const int SW_SHOWNORMAL = 1;
    /// <summary>
    /// 應(yīng)用程序的主入口點(diǎn)。
    /// </summary>
    [STAThread]
    static void Main()
    {
      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);
      Process processes = RunningInstance();
      if (processes == null)
      {
        Application.Run(new Form1());
      }
      else
      {
        HandleRunningInstance(processes);
      }
    }
    /// <summary>
    /// 獲取正在運(yùn)行的實(shí)例,沒(méi)有運(yùn)行的實(shí)例返回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>
    /// 顯示已運(yùn)行的程序。
    /// </summary>
    public static void HandleRunningInstance(Process instance)
    {
      try
      {
        IntPtr formHwnd = FindWindow(null, "計(jì)算器");
        ShowWindow(formHwnd, SW_SHOWNORMAL);  //顯示
        SetForegroundWindow(formHwnd);     //放到前端
      }
      catch (Exception ex)
      {
        MessageBox.Show(ex.Message);
      }
    }
  }
}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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 計(jì)算器
{
  static class Program
  {
    [DllImport("user32.dll")]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    /// <summary>
    /// 該函數(shù)設(shè)置由不同線程產(chǎn)生的窗口的顯示狀態(tài)。
    /// </summary>
    /// <param name="hWnd">窗口句柄</param>
    /// <param name="cmdShow">指定窗口如何顯示。查看允許值列表,請(qǐng)查閱ShowWlndow函數(shù)的說(shuō)明部分。</param>
    /// <returns>如果函數(shù)原來(lái)可見(jiàn),返回值為非零;如果函數(shù)原來(lái)被隱藏,返回值為零。</returns>
    [DllImport("User32.dll")]
    private static extern bool ShowWindow(IntPtr hWnd, int cmdShow);
    /// <summary>
    /// 該函數(shù)將創(chuàng)建指定窗口的線程設(shè)置到前臺(tái),并且激活該窗口。鍵盤輸入轉(zhuǎn)向該窗口,并為用戶改各種可視的記號(hào)。系統(tǒng)給創(chuàng)建前臺(tái)窗口的線程分配的權(quán)限稍高于其他線程。
    /// </summary>
    /// <param name="hWnd">將被激活并被調(diào)入前臺(tái)的窗口句柄。</param>
    /// <returns>如果窗口設(shè)入了前臺(tái),返回值為非零;如果窗口未被設(shè)入前臺(tái),返回值為零。</returns>
    [DllImport("User32.dll")]
    private static extern bool SetForegroundWindow(IntPtr hWnd);
    private const int SW_SHOWNORMAL = 1;
    /// <summary>
    /// 應(yīng)用程序的主入口點(diǎn)。
    /// </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()); //進(jìn)程ID寫入文件
          Application.Run(new Form1());
        }
        else
        {
          try
          {
            string strProcessId = FileOperator.GetValue("ProcessId"); //從文件中獲取進(jìn)程ID
            int processId = Convert.ToInt32(strProcessId);
            Process process = Process.GetProcessById(processId);
            HandleRunningInstance(process);
          }
          catch
          {
            FileOperator.SetValue("ProcessId", Process.GetCurrentProcess().Id.ToString()); //進(jìn)程ID寫入文件
            Application.Run(new Form1());
          }
        }
      }
    }
    /// <summary>
    /// 顯示已運(yùn)行的程序。
    /// </summary>
    public static void HandleRunningInstance(Process instance)
    {
      try
      {
        IntPtr formHwnd = FindWindow(null, "計(jì)算器");
        ShowWindow(formHwnd, SW_SHOWNORMAL);  //顯示
        SetForegroundWindow(formHwnd);     //放到前端
      }
      catch (Exception ex)
      {
        MessageBox.Show(ex.Message);
      }
    }
  }
}

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/// <summary>
/// 顯示已運(yùn)行的程序
/// </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);
  }
}

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

希望本文所述對(duì)大家C#程序設(shè)計(jì)有所幫助。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久草在在线免视频在线观看 | 1769最新资源站| 男人的影院 | 美女露全身永久免费网站 | 99热6这里只有精品 99欧美精品 | 国产日韩欧美视频 | 香蕉eeww99国产精品 | 无码乱人伦一区二区亚洲一 | 亚洲四虎影院 | 日本三级在丈面前被耍了 | 小早川怜子视频在线观看 | 美女gif趴跪式抽搐动态图 | 精品午夜寂寞影院在线观看 | 国产一区在线播放 | 五月天色网站 | 二区三区在线观看 | 亚洲国产成人精品无码区APP | 思敏1一5集国语版免费观看 | 色久天| 91噜噜噜在线观看 | 日本伊人色综合网 | 日本精品一区二区三区 | 亚洲+欧美+国产+综合 | 出a级黑粗大硬长爽猛视频 吃胸膜奶视频456 | 国产成人咱精品视频免费网站 | 免费精品视频在线 | 大伊香蕉在线精品不卡视频 | 和两个男人玩3p好爽视频 | 欧美日韩精品一区二区三区视频播放 | 精品日本一区二区 | heyzo在线播放 | 国产成人在线免费视频 | 青青热久免费精品视频精品 | 日本护士撒尿xxxx18 | 精品久久久久久久久久久 | 亚洲网站大全 | 欧美日韩在线观看精品 | 男人香蕉好大好爽视频 | 大吊操 | 亚洲精品一区二区三区在线看 | 天天色踪合|