c#防止多次运行代码收集分享
程序员文章站
2024-02-18 12:57:22
方法一
class program
{
[stathread]
static void main(string[] args)...
方法一
class program { [stathread] static void main(string[] args) { //防止程序多次运行 if (!oneinstance.isfirst("mytest")) { console.writeline("警告:程序正在运行中! 请不要重复打开程序!可在右下角系统栏找到!"); return; } console.writeline("正在运行中"); console.readline(); } } public static class oneinstance { ///<summary> ///判断程序是否正在运行 ///</summary> ///<param name="appid">程序名称</param> ///<returns>如果程序是第一次运行返回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; //返回不具有扩展名的制定路径字符串的文件名 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()); }
方法三
原文如下()
经常我们会有这样的需求,只让应用程序运行一个实体。通常我们的情况是,双击一个exe文件,就运行一个程序的实体,再双击一次这个exe文件,又 运行这个应用程序的另一个实体。就拿qq游戏来说吧,一台电脑上一般只能运行一个qq游戏大厅(不过以前听说过有双开的外挂)。
那我们的程序也能像qq游戏那里禁止多次启动吗,答案是可以的,下面介绍下一个简单的实现方法,那就是mutex(互斥)。
mutex(mutual exclusion,互斥)是.net framework中提供跨多个线程同步访问的一个类。它非常类似了monitor类,因为他们都只有一个线程能拥有锁定。而操作系统能够识别有名称的互 斥,我们可以给互斥一个唯一的名称,在程序启动之前加一个这样的互斥。这样每次程序启动之前,都会检查这个命名的互斥是否存在。如果存在,应用程序就退 出。
static class program { /// <summary> /// the main entry point for the application. /// </summary> [stathread] static void main() { bool creatednew; //系统能够识别有名称的互斥,因此可以使用它禁止应用程序启动两次 //第二个参数可以设置为产品的名称:application.productname //每次启动应用程序,都会验证名称为singletonwinappmutex的互斥是否存在 mutex mutex = new mutex(false, "singletonwinappmutex", out creatednew); //如果已运行,则在前端显示 //creatednew == false,说明程序已运行 if (!creatednew) { process instance = getexistprocess(); if (instance != null) { setforegroud(instance); application.exit(); return; } } application.enablevisualstyles(); application.setcompatibletextrenderingdefault(false); application.run(new mainform()); } /// <summary> /// 查看程序是否已经运行 /// </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); }
经过我的测试,还比较好用,但是有个问题,如果不注销,用另一个用户进入,则程序不能判断出已运行。所以只限于用在单用户环境,还是不太完美。
class program { [stathread] static void main(string[] args) { //防止程序多次运行 if (!oneinstance.isfirst("mytest")) { console.writeline("警告:程序正在运行中! 请不要重复打开程序!可在右下角系统栏找到!"); return; } console.writeline("正在运行中"); console.readline(); } } public static class oneinstance { ///<summary> ///判断程序是否正在运行 ///</summary> ///<param name="appid">程序名称</param> ///<returns>如果程序是第一次运行返回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 ); }