广州暨华电脑学校
咨询热线:020-85566216

诚        毅        精      勤

当前位置:所在位置: 广州电脑培训 >> 电脑技术 >> net >> 正文

C# 只启动一个实例完全解决方案

发布时间:2018/2/28 17:59:04 内容来源::广州暨华电脑学校 点击:0

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

  先说下我详细的几点需求(假设程序名为"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;

  }

  ///

  /// 重写OnCreateMainForm()函数

  ///

  protected override void OnCreateMainForm()

  {

  this.MainForm = new FormMain();

  }

  }

  }

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

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

  当我们生成一个exe执行文件时,如果再双击一次时,它会再开一个新的程序,这样子是不合适的。下面有一个办法:

  staticvoid Main(){

  Application.EnableVisualStyles();

  Application.SetCompatibleTextRenderingDefault(false);

  //檢測系統是否有“XXXXX.vshost.exe”這一進程存在,如果已有,則不允許再打開。

  if(System.Diagnostics.Process.GetProcessesByName(System.Diagnostics.Process.GetCurrentProcess().ProcessName).Length > 1)

  {

  MessageBox.Show("已有另一個提醒器在運行!","提示信息");

  }

  else

  {

  Application.Run(new frmTraceMold());

  }

  }

  • 上一篇电脑技术:
  • 下一篇电脑技术: 没有了
  • 学校简介 |专业课程 | 学生就业 | 校园风光

    学校地址:广州天河区五山路金华园区C座3楼307(华南理工大学南门旁)/p>

    学校名称:广州暨华教育Java培训学校:www.020bdqn.com.cn 联系电话:020-85566215

    ? 2002-2018 广州青大教育信息咨询有限公司 版权所有 备案/许可证编号为:粤ICP备11083420号-4