最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#編程中設(shè)置程序只可被運(yùn)行一次的方法

 更新時間:2015年11月19日 17:19:29   作者:jack_Meng  
這篇文章主要介紹了C#編程中設(shè)置程序只可被運(yùn)行一次的方法,包括一種讓程序自動重啟以限制第二次被運(yùn)行的方法,需要的朋友可以參考下

防止程序運(yùn)行多個實例的方法有多種,如:通過使用互斥量和進(jìn)程名等.而我想要實現(xiàn)的是:在程序運(yùn)行多個實例時激活的是第一個實例,使其獲得焦點(diǎn),并在前端顯示.

主要用到兩個API 函數(shù):

ShowWindowAsync 該函數(shù)設(shè)置由不同線程產(chǎn)生的窗口的顯示狀態(tài)。
SetForegroundWindow 該函數(shù)將創(chuàng)建指定窗口的線程設(shè)置到前臺,并且激活該窗口。鍵盤輸入轉(zhuǎn)向該窗口,并為用戶改各種可視的記號。系統(tǒng)給創(chuàng)建前臺窗口的線程分配的權(quán)限稍高于其他線程。
代碼如下:
引用以下命名空間:

using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Reflection;
//*****************************************************
 static class Program
  {
    /// <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 ShowWindowAsync(IntPtr hWnd, int cmdShow);
    /// <summary>
    /// 該函數(shù)將創(chuàng)建指定窗口的線程設(shè)置到前臺,并且激活該窗口。鍵盤輸入轉(zhuǎn)向該窗口,并為用戶改各種可視的記號。系統(tǒng)給創(chuàng)建前臺窗口的線程分配的權(quán)限稍高于其他線程。
    /// </summary>
    /// <param name="hWnd">將被激活并被調(diào)入前臺的窗口句柄。</param>
    /// <returns>如果窗口設(shè)入了前臺,返回值為非零;如果窗口未被設(shè)入前臺,返回值為零。</returns>
    [DllImport("User32.dll")]
    private static extern bool SetForegroundWindow(IntPtr hWnd);
    private const int WS_SHOWNORMAL = 1;

    /// <summary>
    /// 應(yīng)用程序的主入口點(diǎn)。
    /// </summary>
    [STAThread]
    static void Main()
    {
      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);
      Process instance = RunningInstance();
      if (instance == null)
      {
        Form1 frm = new Form1();
        Application.Run(new Form1());
      }
      else
      {
        HandleRunningInstance(instance);
      }

    }
    /// <summary>
    /// 獲取正在運(yùn)行的實例,沒有運(yùn)行的實例返回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)
    {
      ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL); //顯示,可以注釋掉
      SetForegroundWindow(instance.MainWindowHandle);      //放到前端
    }
  }

實現(xiàn)讓程序只能打開一個實例(其他方法)

//=====創(chuàng)建互斥體法:=====
bool blnIsRunning;
Mutex mutexApp = new Mutex(false, Assembly.GetExecutingAssembly().FullName, out  blnIsRunning);
if (!blnIsRunning)
{
  MessageBox.Show("程序已經(jīng)運(yùn)行!", "提示",
  MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
  return;
}  



//保證同時只有一個客戶端在運(yùn)行  
System.Threading.Mutex mutexMyapplication = new System.Threading.Mutex(false, "OnePorcess.exe");
if (!mutexMyapplication.WaitOne(100, false))
{
  MessageBox.Show("程序" + Application.ProductName + "已經(jīng)運(yùn)行!", Application.ProductName,
  MessageBoxButtons.OK, MessageBoxIcon.Error);
  return;
}


//=====判斷進(jìn)程法:(修改程序名字后依然能執(zhí)行)=====
Process current = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName(current.ProcessName);
foreach (Process process in processes)
{
  if (process.Id != current.Id)
  {
    if (process.MainModule.FileName
    == current.MainModule.FileName)
    {
      MessageBox.Show("程序已經(jīng)運(yùn)行!", Application.ProductName,
      MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
      return;
    }
  }
}

實現(xiàn)程序自重啟
程序運(yùn)行過程中,不能有多個實例運(yùn)行,并且需要程序自己可以重啟(重新運(yùn)行),所以代碼如果下代碼:

static void Main() 
{ 
  bool createNew; 
  using (System.Threading.Mutex m = new System.Threading.Mutex(true, Application.ProductName, out createNew)) 
  { 
    if (createNew) 
    { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new Form1()); 
    } 
    else 
    { 
      MessageBox.Show("Only one instance of this application is allowed!"); 
    } 
  } 
}
Boolean createdNew; //返回是否賦予了使用線程的互斥體初始所屬權(quán)
System.Threading.Mutex instance = new System.Threading.Mutex(true, "MutexName", out createdNew); //同步基元變量
if (createdNew) //賦予了線程初始所屬權(quán),也就是首次使用互斥體
{
Application.Run(new Form1()); /s/這句是系統(tǒng)自動寫的
instance.ReleaseMutex();
}
else
{
MessageBox.Show("已經(jīng)啟動了一個程序,請先退出!","系統(tǒng)提示",MessageBoxButtons.OK,MessageBoxIcon.Error);
Application.Exit();
}

用以上代碼實現(xiàn)了禁止多重啟動的功能。
同時程序關(guān)閉重啟是通過下面的代碼實現(xiàn)的:

Process.Start(Process.GetCurrentProcess().ProcessName + ".exe");
Application.Exit();

這時就出現(xiàn)一個問題,程序自動關(guān)閉重啟的時候就會提示已經(jīng)啟動了一個程序了。
請問應(yīng)該怎么解決?
關(guān)閉之后過一會兒再啟動是沒問題的。
但是現(xiàn)在自動關(guān)閉,自動重啟有的時候能成功,有的時候就被禁止多重啟動的那個截住了。
那就必須手動重新啟動了。
比如,點(diǎn)【重新啟動】按鈕的時候執(zhí)行以下代碼:

Process.Start(Process.GetCurrentProcess().ProcessName + ".exe");
Application.Exit();

這時它是先啟動一個新的Process然后才退出當(dāng)前程序。
這時就會在Program.cs里遇到禁止多重啟動的那段代碼。就不能自動啟動了。
解決方案:
解決方法一:
一般程序:
因為進(jìn)程還沒有中止,還占在內(nèi)存中所以才會報錯.
出現(xiàn)這種原因的情況可能是:使用多線程,其中的線程沒有執(zhí)行結(jié)束,也沒有被置為后臺線程,所以雖然應(yīng)用程序關(guān)閉,但進(jìn)程仍駐留在內(nèi)存中.
可以使用Application.ExitThread();中止進(jìn)程中的所有線程.
也可以在進(jìn)程執(zhí)行中獲得進(jìn)程的ID,然后通過Process.GetProcessById()獲得這個進(jìn)程,然后將它Kill掉,再啟動新的進(jìn)程.

解決方法二:
要不就在用戶點(diǎn)[重新啟動]時,把mutex先釋放掉?可能需要把那個mutex變量做成一個global,這樣你在兩個地方都能訪問到。然后在程序退出時(Application.Run下面那一句),檢查一下如果mutex已經(jīng)被釋放了,就不要再釋放了。

解決方法三:
或者就在點(diǎn)[重新啟動]時再設(shè)另外一個不同的信號量,當(dāng)?shù)诙€程序重入時如果看到這個信號量說明是自動重啟的情況,就不報錯而直接正常往下走了。這個信號量可以在第一個程序[重新啟動]那里執(zhí)行完后再釋放,不過應(yīng)該也可以在整個程序退出時檢查一下如果存在就釋放。

相關(guān)文章

  • C#圖像識別 微信跳一跳機(jī)器人

    C#圖像識別 微信跳一跳機(jī)器人

    這篇文章主要為大家詳細(xì)介紹了C#圖像識別,微信跳一跳機(jī)器人,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • 使用mutex實現(xiàn)應(yīng)用程序單實例運(yùn)行代碼分享

    使用mutex實現(xiàn)應(yīng)用程序單實例運(yùn)行代碼分享

    本文主要介紹了使用Mutex實現(xiàn)應(yīng)用程序單實例運(yùn)行的方法,實現(xiàn)原理是在程序啟動時,請求一個互斥體,如果能獲取對指定互斥的訪問權(quán),就繼續(xù)運(yùn)行程序,否則就退出程序
    2014-01-01
  • C#返回多少分鐘之前或多少分鐘之后時間的方法

    C#返回多少分鐘之前或多少分鐘之后時間的方法

    這篇文章主要介紹了C#返回多少分鐘之前或多少分鐘之后時間的方法,涉及C#時間操作的相關(guān)技巧,需要的朋友可以參考下
    2015-05-05
  • C# SqlSugar批量執(zhí)行SQL語句及批量更新實體對象的操作方法

    C# SqlSugar批量執(zhí)行SQL語句及批量更新實體對象的操作方法

    SqlSugar 是一款 老牌 .NET開源ORM框架,由果糖大數(shù)據(jù)科技團(tuán)隊維護(hù)和更新 ,開箱即用最易上手的ORM,這篇文章主要介紹了C# SqlSugar批量執(zhí)行SQL語句以及批量更新實體對象,需要的朋友可以參考下
    2024-07-07
  • C#給多線程傳參的幾種方式小結(jié)

    C#給多線程傳參的幾種方式小結(jié)

    本文詳細(xì)探討了如何在C#中進(jìn)行線程傳參,包括啟動線程時如何將參數(shù)傳遞給線程函數(shù),以及在多線程環(huán)境下正確使用參數(shù)的方法,對于理解和實踐C#線程編程具有重要意義,需要的朋友可以參考下
    2024-10-10
  • Unity實現(xiàn)繞任意軸任意角度旋轉(zhuǎn)向量

    Unity實現(xiàn)繞任意軸任意角度旋轉(zhuǎn)向量

    這篇文章主要為大家詳細(xì)介紹了Unity實現(xiàn)繞任意軸任意角度旋轉(zhuǎn)向量,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-01-01
  • SuperSocket封裝成C#類庫的步驟

    SuperSocket封裝成C#類庫的步驟

    這篇文章主要介紹了SuperSocket封裝成C#類庫的步驟,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下
    2021-01-01
  • C# FileStream復(fù)制大文件

    C# FileStream復(fù)制大文件

    這篇文章主要為大家詳細(xì)介紹了C# FileStream復(fù)制大文件的相關(guān)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • OpenXml讀取word內(nèi)容的實例

    OpenXml讀取word內(nèi)容的實例

    下面小編就為大家分享一篇OpenXml讀取word內(nèi)容的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • C#使用TimeSpan時間計算的簡單實現(xiàn)

    C#使用TimeSpan時間計算的簡單實現(xiàn)

    這篇文章主要給大家介紹了關(guān)于C#使用TimeSpan時間計算的相關(guān)資料,以及通過一個實例代碼給大家介紹了C#使用timespan和timer完成一個簡單的倒計時器的方法,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-06-06

最新評論

土默特右旗| 大冶市| 宜宾市| 弋阳县| 苗栗市| 桑日县| 乌鲁木齐县| 柞水县| 垦利县| 平塘县| 临城县| 广灵县| 漠河县| 孝感市| 湘潭县| 郧西县| 德州市| 即墨市| 曲周县| 磴口县| 班戈县| 紫云| 临汾市| 乌拉特后旗| 太谷县| 环江| 木里| 荔波县| 崇左市| 赣榆县| 卢湾区| 闵行区| 湘阴县| 金平| 屯门区| 获嘉县| 景东| 永善县| 黄山市| 大方县| 花莲县|