工作上经常会遇到"程序只能启动一个实例"这样的需求. 我想,这样的需求应该很普遍,所以没打算去动脑筋,去找谷歌问下就得了,用下来发现,不是这里不爽就是那里不行.

  先说下我详细的几点需求(假设程序名为"A.exe")

  1.程序只能同时打开一个实例.

  2.在A.exe已经启动的情况下,双击A.exe,则把已经启动的A.exe激活,并呈现到最前.

  3.复制A.exe,命名为B.exe,在A.exe已经启动的情况下,双击B.exe,则把A.exe激活,并呈现到最前.

  好,现在就来看看网络上的解决方案

  1.互斥法

  bool createdNew; Mutex instance

  = new Mutex(true,"互斥名(保证在本机中唯一)", out

  createdNew);

  if

  (createdNew)

  {

  Application.EnableVisualStyles();

  Application.SetCompatibleTextRenderingDefault(false);

  Application.Run(new FormMain());

  instance.ReleaseMutex();

  }

  else

  {

  MessageBox.Show("已经启动了一个程序,请先退出!", "系统提示", MessageBoxButtons.OK,

  MessageBoxIcon.Error);

  Application.Exit();

  }

  评价:

  个人认为这种方法非常的好,能做出判断的准确,即使启动复制的执行文件,依然可以提示"已经启动一个程序,请先退出!".这样,它满足了上述需要中的第一条和第三条的前半部分.但是有一个不足:无法激活已经启动的程序(至少我不知道怎么实现 ,如果有谁知道用互斥可以实现以上三个要求,请留言告诉我,不胜感激!)

  2.Process法

  添加如下函数:

  public static Process RunningInstance()

  {

  Process current = Process.GetCurrentProcess();

  Process[] processes = Process.GetProcessesByName(current.ProcessName);

  //Loop through the running processes in with the same name

  foreach (Process process in processes)

  {

  //Ignore the current process

  if (process.Id != current.Id)

  {

  //Make sure that the process is running from the exe file.

  if (Assembly.GetExecutingAssembly().Location.Replace("/", "\") == current.MainModule.FileName)

  {

  //Return the other process instance.

  return process;

  }

  }

  }

  //No other instance was found, return null.

  return null;

  }

  修改系统Main函数,大致如下:

  if( RunningInstance() == null )

  Application.Run(new yourFormName());

  评价:速度比较慢,其次通过ProcessName去系统中查寻,有可能查出来的Process并不是我想要得,不过,稍做修改,便可以很实现需求的第二条(让程序只运行一次,如果程序已经运行,把它弹出并显示到最前面).但是它同样有一个很严重的问题,也就无法满足需求中的第三条,做一个复制,然后修改名字(程序名即为进程名),便可以启动多个实例.

  3.VB法(个人推荐的方法,谈不上原创,但是网络上很少见)

  不解释,直接看代码

  using

  Microsoft.VisualBasic.ApplicationServices;

  static void Main(string[] args)

  {

  App myApp = new App();

  myApp.Run(args);

  }

  class App : WindowsFormsApplicationBase

  {

  public App()

  {

  // 设置单例模式

  this.IsSingleInstance = true;

  // 设置可用于XP窗口样式

  this.EnableVisualStyles = true;

  // 窗口关闭时的操作

  this.ShutdownStyle = ShutdownMode.AfterMainFormCloses;

  }

  /// <summary>

  /// 重写OnCreateMainForm()函数

  /// </summary>

  protected override void OnCreateMainForm()

  {

  this.MainForm = new FormMain();

  }

  }

  }

  怎么样,也不是很复杂,代码量很少,轻松实现所有需求.当然,有些朋友还可能还有这样的需求

  程序第二次启动的时候,除了把程序激活前置,还要往程序里传递参数,并做处理.没有问题,这样也可以做到,但是可能稍微复杂一点,在VB法的基础上再做点修改就OK啦

C# 只启动一个实例完全解决方案的更多相关文章

  1. WinForm程序,实现只启动一个实例

    前言:在我们做的软件中,当点击图标运行时,正常的需求是只需要启动一个软件的实例,这是非常重要的一点,不然就显得我们的软件非常的山寨,笔者在工作中经常遇到同事没有注意这一点,看是不重要,实则非常的重要, ...

  2. windows下程序启动检查,只启动一个实例

    问题来源:http://bbs.csdn.net/topics/390998279?page=1#post-398983061 // Only_once.cpp : 定义控制台应用程序的入口点. // ...

  3. 37.QT-QTSingleApplication-程序只运行一个实例

    QTSingleApplication由Qt官方提供的,用于实现只启动一个实例,并在启动时可以向向另一个实例通信(依赖于QtNetwork模块) QTSingleApplication下载路径:链接: ...

  4. MFC 只启动一个程序实例

    问题描述: 我们开发过程中可能会经常遇到,只启动一个程序实例.即一个程序启动之后,如果再次执行该程序,将会恢复之前打开的程序,而不是打开一个新的程序. 实现原理:利用FindWindow/FindWi ...

  5. Linux编程之《只运行一个实例》

    概述 有些时候,我们要求一个程序在系统中只能启动一个实例.比如,Windows自带的播放软件Windows Medea Player在Windows里就只能启动一个实例.原因很简单,如果同时启动几个实 ...

  6. vc++高级班之窗口篇[4]---让程序只运行一个实例

      大家都看过或者使用过类似只运行一个实例的程序,比如:QQ游戏.部分浏览器 等等! 让一个程序只运行一个实例的方法有多种,但是原理都类似,也就是在程序创建后,有窗口的程序在窗口创建前, 检查系统中是 ...

  7. VC 实现程序只运行一个实例,并激活已运行的程序

    转载:http://blog.sina.com.cn/s/blog_4b44e1c00100bh69.html 进程的互斥运行:CreateMutex函数实现只运行一个程序实例 正常情况下,一个进程的 ...

  8. electron限制只启动一个应用

    electron限制只启动一个应用 // ========================================================== // 限制只可以打开一个应用,2.x的文 ...

  9. WinFrom 只启动一个exe,并且获得焦点

    只启动一个exe方法: using System; using System.Collections.Generic; using System.Runtime.InteropServices; us ...

随机推荐

  1. javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 解决方案

    这个是jdk导致的,jdk里面有一个jce的包,安全性机制导致的访问https会报错,官网上有替代的jar包,换掉就好了 目录 %JAVA_HOME%\jre\lib\security里的local_ ...

  2. 用Canvas写一个炫酷的时间更新动画玩玩

    正文必须要写点什么...   // '; var WINDOW_WIDTH = 913; var WINDOW_HEIGHT = 400; var RADIUS = 7; //球半径 var NUMB ...

  3. Python 目录操作

    知道两个文件的绝对目录,怎样计算出两个文件的相对目录,例如:知道 a = '/usr/share/pyshared/test/a.py' b = '/usr/lib/dist/test/a.py' 可 ...

  4. PHP查看SSL证书信息

    <? $str = file_get_contents('2.cer'); print_r(openssl_x509_parse($str)); ?> 证书需要使用base64编码的方式c ...

  5. 【linux】vim编辑器vim+taglist+ctags的配置

    很多linux软件开发实际上并不实在X window的情况下进行的,这时我们不可能启动基于X window的图形化窗口,在这一情况下我们所能使用的主要的编辑器是vim和emacs.(ps:emacs和 ...

  6. Android--Matrix图片变换处理

    前言 本篇博客主要讲解一下如何处理对一个Bitmap对象进行处理,包括:缩放.旋转.位移.倾斜等.在最后将以一个简单的Demo来演示图片特效的变换. 本篇博客的主要内容: Matrix Matrix缩 ...

  7. 基于Bootstrap的后台通用模板

    人总是比较刁的,世界的时尚趋势不断变化,对系统UI的审美也在不断疲劳中前进,之前觉得好好的UI,过了半年觉得平平无奇,不想再碰,需要寻求新的兴奋点. 下面这套UI就是半年前的(今日:2015-12), ...

  8. eclipse 运行报java.lang.OutOfMemoryError: PermGen space解决方法

    一.在window下eclipse里面Server挂的是tomcat6,一开始还是以为,tomcat配置的问题,后面发现,配置了tomcat里面的catalina.bat文件,加入 set JAVA_ ...

  9. Hadoop 生态系统

    1.概述 最近收到一些同学和朋友的邮件,说能不能整理一下 Hadoop 生态圈的相关内容,然后分享一些,我觉得这是一个不错的提议,于是,花了一些业余时间整理了 Hadoop 的生态系统,并将其进行了归 ...

  10. CSS - Select 标签在不同浏览器中的高度设置

    当使用Select标签时,在不同浏览器中显示的高度不同,如何解决此问题: 解决方法链接:http://stackoverflow.com/questions/20477823/select-html- ...