c#防止多次運(yùn)行代碼收集分享
方法一
class Program
{
[STAThread]
static void Main(string[] args)
{
//防止程序多次運(yùn)行
if (!OneInstance.IsFirst("MyTest"))
{
Console.WriteLine("警告:程序正在運(yùn)行中! 請(qǐng)不要重復(fù)打開程序!可在右下角系統(tǒng)欄找到!");
return;
}
Console.WriteLine("正在運(yùn)行中");
Console.ReadLine();
}
}
public static class OneInstance
{
///<summary>
///判斷程序是否正在運(yùn)行
///</summary>
///<param name="appId">程序名稱</param>
///<returns>如果程序是第一次運(yùn)行返回True,否則返回False</returns>
public static bool IsFirst(string appId)
{
bool ret = false;
if (OpenMutex(0x1F0001, 0, appId) == IntPtr.Zero)
{
CreateMutex(IntPtr.Zero, 0, appId);
ret = true;
}
return ret;
}
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr OpenMutex(
uint dwDesiredAccess, // access
int bInheritHandle, // inheritance option
string lpName // object name
);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr CreateMutex(
IntPtr lpMutexAttributes, // SD
int bInitialOwner, // initial owner
string lpName // object name
);
}方法二
string MnName = Process.GetCurrentProcess().MainModule.ModuleName;
//返回不具有擴(kuò)展名的制定路徑字符串的文件名
String Pname = Path.GetFileNameWithoutExtension(MnName);
Process[] myprocess = Process.GetProcessesByName(Pname);
if (myprocess.Length > 1)
{
MessageBox.Show("yici", "tishi", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
//Application.EnableVisualStyles();
////Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(new Form1());
}方法三
原文如下(//www.dhdzp.com/article/41179.htm)
經(jīng)常我們會(huì)有這樣的需求,只讓應(yīng)用程序運(yùn)行一個(gè)實(shí)體。通常我們的情況是,雙擊一個(gè)exe文件,就運(yùn)行一個(gè)程序的實(shí)體,再雙擊一次這個(gè)exe文件,又 運(yùn)行這個(gè)應(yīng)用程序的另一個(gè)實(shí)體。就拿QQ游戲來(lái)說(shuō)吧,一臺(tái)電腦上一般只能運(yùn)行一個(gè)QQ游戲大廳。
那我們的程序也能像QQ游戲那里禁止多次啟動(dòng)嗎,答案是可以的,下面介紹下一個(gè)簡(jiǎn)單的實(shí)現(xiàn)方法,那就是Mutex(互斥)。
Mutex(mutual exclusion,互斥)是.Net Framework中提供跨多個(gè)線程同步訪問的一個(gè)類。它非常類似了Monitor類,因?yàn)樗麄兌贾挥幸粋€(gè)線程能擁有鎖定。而操作系統(tǒng)能夠識(shí)別有名稱的互 斥,我們可以給互斥一個(gè)唯一的名稱,在程序啟動(dòng)之前加一個(gè)這樣的互斥。這樣每次程序啟動(dòng)之前,都會(huì)檢查這個(gè)命名的互斥是否存在。如果存在,應(yīng)用程序就退 出。
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
bool createdNew;
//系統(tǒng)能夠識(shí)別有名稱的互斥,因此可以使用它禁止應(yīng)用程序啟動(dòng)兩次
//第二個(gè)參數(shù)可以設(shè)置為產(chǎn)品的名稱:Application.ProductName
//每次啟動(dòng)應(yīng)用程序,都會(huì)驗(yàn)證名稱為SingletonWinAppMutex的互斥是否存在
Mutex mutex = new Mutex(false, "SingletonWinAppMutex", out createdNew);
//如果已運(yùn)行,則在前端顯示
//createdNew == false,說(shuō)明程序已運(yùn)行
if (!createdNew)
{
Process instance = GetExistProcess();
if (instance != null)
{
SetForegroud(instance);
Application.Exit();
return;
}
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
/// <summary>
/// 查看程序是否已經(jīng)運(yùn)行
/// </summary>
/// <returns></returns>
private static Process GetExistProcess()
{
Process currentProcess = Process.GetCurrentProcess();
foreach (Process process in Process.GetProcessesByName(currentProcess.ProcessName))
{
if ((process.Id != currentProcess.Id) &&
(Assembly.GetExecutingAssembly().Location == currentProcess.MainModule.FileName))
{
return process;
}
}
return null;
}
/// <summary>
/// 使程序前端顯示
/// </summary>
/// <param name="instance"></param>
private static void SetForegroud(Process instance)
{
IntPtr mainFormHandle = instance.MainWindowHandle;
if (mainFormHandle != IntPtr.Zero)
{
ShowWindowAsync(mainFormHandle, 1);
SetForegroundWindow(mainFormHandle);
}
}
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("User32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
}
經(jīng)過(guò)我的測(cè)試,還比較好用,但是有個(gè)問題,如果不注銷,用另一個(gè)用戶進(jìn)入,則程序不能判斷出已運(yùn)行。所以只限于用在單用戶環(huán)境,還是不太完美。
class Program
{
[STAThread]
static void Main(string[] args)
{
//防止程序多次運(yùn)行
if (!OneInstance.IsFirst("MyTest"))
{
Console.WriteLine("警告:程序正在運(yùn)行中! 請(qǐng)不要重復(fù)打開程序!可在右下角系統(tǒng)欄找到!");
return;
}
Console.WriteLine("正在運(yùn)行中");
Console.ReadLine();
}
}
public static class OneInstance
{
///<summary>
///判斷程序是否正在運(yùn)行
///</summary>
///<param name="appId">程序名稱</param>
///<returns>如果程序是第一次運(yùn)行返回True,否則返回False</returns>
public static bool IsFirst(string appId)
{
bool ret = false;
if (OpenMutex(0x1F0001, 0, appId) == IntPtr.Zero)
{
CreateMutex(IntPtr.Zero, 0, appId);
ret = true;
}
return ret;
}
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr OpenMutex(
uint dwDesiredAccess, // access
int bInheritHandle, // inheritance option
string lpName // object name
);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr CreateMutex(
IntPtr lpMutexAttributes, // SD
int bInitialOwner, // initial owner
string lpName // object name
);
}相關(guān)文章
C#網(wǎng)頁(yè)跳轉(zhuǎn)方法總結(jié)
這篇文章主要介紹了C#網(wǎng)頁(yè)跳轉(zhuǎn)方法總結(jié)的相關(guān)資料,需要的朋友可以參考下2015-12-12
WPF/Silverlight實(shí)現(xiàn)圖片局部放大的方法分析
這篇文章主要介紹了WPF/Silverlight實(shí)現(xiàn)圖片局部放大的方法,結(jié)合實(shí)例形式分析了WPF/Silverlight針對(duì)圖片屬性操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-03-03
C# WebApi+Webrtc局域網(wǎng)音視頻通話實(shí)例
這篇文章主要為大家詳細(xì)介紹了C# WebApi+Webrtc局域網(wǎng)音視頻通話實(shí)例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07
輕松學(xué)習(xí)C#的結(jié)構(gòu)和類
輕松學(xué)習(xí)C#的結(jié)構(gòu)和類,對(duì)C#的結(jié)構(gòu)和類感興趣的朋友可以參考本篇文章,幫助大家更靈活的運(yùn)用C#的結(jié)構(gòu)和類2015-11-11
c#棧變化規(guī)則圖解示例(棧的生長(zhǎng)與消亡)
多數(shù)情況下我們不需要關(guān)心棧的變化,下文會(huì)給出一個(gè)具體的示例。另外,理解棧的變化對(duì)于理解作用域也有一定的好處,因?yàn)镃#的局部變量作用域是基于棧的。2013-11-11
C#四種計(jì)時(shí)器Timer的區(qū)別和用法
這篇文章介紹了C#四種計(jì)時(shí)器Timer的區(qū)別和用法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05

