欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2017年05月23日 10:49:16   作者:何問起  
這篇文章主要介紹了WinForm防止程序重復(fù)運(yùn)行的方法,通過記錄窗口句柄實(shí)現(xiàn)防止WinForm程序重復(fù)運(yùn)行的功能,需要的朋友可以參考下

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

需求:

1、點(diǎn)擊“關(guān)閉”按鈕時(shí),程序最小化到托盤,并沒有退出,這時(shí)再次運(yùn)行程序,不會(huì)重復(fù)運(yùn)行,而是顯示已運(yùn)行的程序;
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 計(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">指定窗口如何顯示。查看允許值列表,請查閱ShowWlndow函數(shù)的說明部分。</param>
    /// <returns>如果函數(shù)原來可見,返回值為非零;如果函數(shù)原來被隱藏,返回值為零。</returns>
    [DllImport("User32.dll")]
    private static extern bool ShowWindow(IntPtr hWnd, int cmdShow);
    /// <summary>
    /// 該函數(shù)將創(chuàng)建指定窗口的線程設(shè)置到前臺(tái),并且激活該窗口。鍵盤輸入轉(zhuǎn)向該窗口,并為用戶改各種可視的記號。系統(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í)例,沒有運(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);
      }
    }
  }
}

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

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">指定窗口如何顯示。查看允許值列表,請查閱ShowWlndow函數(shù)的說明部分。</param>
    /// <returns>如果函數(shù)原來可見,返回值為非零;如果函數(shù)原來被隱藏,返回值為零。</returns>
    [DllImport("User32.dll")]
    private static extern bool ShowWindow(IntPtr hWnd, int cmdShow);
    /// <summary>
    /// 該函數(shù)將創(chuàng)建指定窗口的線程設(shè)置到前臺(tái),并且激活該窗口。鍵盤輸入轉(zhuǎn)向該窗口,并為用戶改各種可視的記號。系統(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的,比如你打開一個(gè)名為“計(jì)算器”的文件夾,那么FindWindow找到的其實(shí)是這個(gè)文件夾,而不是計(jì)算器程序。我們可以在主窗體第一次顯示的時(shí)候,記下窗口句柄,代碼如下:

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

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

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

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

更多關(guān)于C#相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《WinForm控件用法總結(jié)》、《C#窗體操作技巧匯總》、《C#數(shù)據(jù)結(jié)構(gòu)與算法教程》、《C#常見控件用法教程》、《C#面向?qū)ο蟪绦蛟O(shè)計(jì)入門教程》及《C#程序設(shè)計(jì)之線程使用技巧總結(jié)

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

相關(guān)文章

  • C#調(diào)用Rar文件及獲取Rar返回值的方法

    C#調(diào)用Rar文件及獲取Rar返回值的方法

    這篇文章主要介紹了C#調(diào)用Rar文件及獲取Rar返回值的方法,實(shí)例分析了C#調(diào)用rar文件實(shí)現(xiàn)文件的壓縮與解壓相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • C#自動(dòng)判斷Excel版本使用不同的連接字符串

    C#自動(dòng)判斷Excel版本使用不同的連接字符串

    這篇文章主要介紹了C#自動(dòng)判斷Excel版本使用不同的連接字符串,本文重點(diǎn)在不同版本的連接字符串介紹,需要的朋友可以參考下
    2015-06-06
  • c# 連接池的設(shè)置與使用

    c# 連接池的設(shè)置與使用

    這篇文章主要介紹了c# 連接池的設(shè)置與使用,幫助大家更好的理解和學(xué)習(xí)c#,感興趣的朋友可以了解下
    2021-01-01
  • C#訪問及調(diào)用類中私有成員與方法示例代碼

    C#訪問及調(diào)用類中私有成員與方法示例代碼

    訪問一個(gè)類的私有成員不是什么好做法,大家也都知道私有成員在外部是不能被訪問的,這篇文章主要給大家介紹了關(guān)于C#訪問及調(diào)用類中私有成員與方法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-06-06
  • 詳解c# 并行計(jì)算

    詳解c# 并行計(jì)算

    本文主要介紹了并行計(jì)算的簡單使用,并行循環(huán)的中斷和跳出、并行循環(huán)中為數(shù)組/集合添加項(xiàng)、返回集合運(yùn)算結(jié)果/含有局部變量的并行循環(huán)、、PLinq(Linq的并行計(jì)算)等相關(guān)內(nèi)容。
    2020-12-12
  • C#實(shí)現(xiàn)的JS操作類實(shí)例

    C#實(shí)現(xiàn)的JS操作類實(shí)例

    這篇文章主要介紹了C#實(shí)現(xiàn)的JS操作類,封裝了C#關(guān)于javascript的彈出對話框、返回上一頁、跳轉(zhuǎn)等常用操作,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-03-03
  • C#獲取Excel文件所有文本數(shù)據(jù)內(nèi)容的示例代碼

    C#獲取Excel文件所有文本數(shù)據(jù)內(nèi)容的示例代碼

    獲取上傳的?EXCEL?文件的所有文本信息并存儲(chǔ)到數(shù)據(jù)庫里,可以進(jìn)一步實(shí)現(xiàn)對文件內(nèi)容資料關(guān)鍵字查詢的全文檢索,有助于我們定位相關(guān)文檔,本文詳細(xì)介紹了C#獲取Excel文件所有文本數(shù)據(jù)內(nèi)容實(shí)現(xiàn)步驟和代碼,需要的朋友可以參考下
    2024-07-07
  • C#編寫發(fā)送郵件組件

    C#編寫發(fā)送郵件組件

    本文給大家分享的是使用C#編寫的發(fā)送郵件的組件,非常的簡單實(shí)用,有需要的小伙伴可以參考下。
    2015-06-06
  • VS2019配置OpenCV4.1.0詳細(xì)教程與測試代碼(推薦)

    VS2019配置OpenCV4.1.0詳細(xì)教程與測試代碼(推薦)

    這篇文章主要介紹了VS2019配置OpenCV4.1.0詳細(xì)教程與測試代碼,本文通過截圖實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03
  • 基于TCP異步Socket模型的介紹

    基于TCP異步Socket模型的介紹

    本篇文章小編將為大家介紹,基于TCP異步Socket模型的介紹,需要的朋友參考下
    2013-04-04

最新評論