C#:只运行一个程序
一、通过系统事件
1、实现如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices; namespace Example
{
public class SinglonProgram
{ #region 字段 //显示的主窗体
private Form mainForm; //线程同步事件
private static EventWaitHandle programWaitHandle; #endregion #region 属性 #endregion #region 构造函数 public SinglonProgram(Form showForm)
{
this.mainForm = showForm; //注册一个等待WaitHandle的委托
ThreadPool.RegisterWaitForSingleObject(programWaitHandle, (obj, timeOut) =>
{
ShowForm();
},
null, -, false); } #endregion #region 私有函数 显示窗体、等 /// <summary>
/// 显示窗体
/// </summary>
private void ShowForm()
{
//在拥有mainForm窗体的线程上执行无参委托(Action)
this.mainForm.Invoke(new Action(() =>
{
this.mainForm.Visible = true;
if(this.mainForm.WindowState == FormWindowState.Minimized)
{
this.mainForm.WindowState = FormWindowState.Normal;
}
this.mainForm.Show(); bool isForeground = SetForegroundWindow(this.mainForm.Handle);
MessageBox.Show(isForeground.ToString());
}
));
} #endregion #region 公共函数 只有一个程序运行 /// <summary>
/// 是否创建了已命名的系统事件
/// </summary>
/// <returns></returns>
public static bool isNamedSystemEvent()
{
bool createdNew;
programWaitHandle = new EventWaitHandle(true, EventResetMode.AutoReset, Application.ProductName, out createdNew);
return !createdNew;
} /// <summary>
/// 确保只有一个程序运行
/// </summary>
public static void Confirm()
{
// 如果该命名事件已命名(运行实例已经存在),则发事件通知并退出
if (isNamedSystemEvent())
{
programWaitHandle.Set(); //将事件状态设置为终止状态,允许一个或多个等待线程继续
Environment.Exit();
}
} #endregion #region 接口函数 激活窗体且前端显示等 /// <summary>
/// 前端显示且激活窗体
/// </summary>
/// <param name="hWnd">窗体句柄</param>
/// <returns></returns>
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd); #endregion #region 虚函数 #endregion
}
}
2、调用如下:
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
SinglonProgram.Confirm();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new frmMain());
}
}
二、通过查询线程
具体如下:(测试时发现,不调试和调试区别下会产生两个程序)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Reflection; namespace Test
{
static class Program
{
/// <summary>
/// 该函数设置由不同线程产生的窗口的显示状态。
/// </summary>
/// <param name="hWnd">窗口句柄</param>
/// <param name="cmdShow">指定窗口如何显示。查看允许值列表,请查阅ShowWlndow函数的说明部分。</param>
/// <returns>如果函数原来可见,返回值为非零;如果函数原来被隐藏,返回值为零。</returns>
[DllImport("User32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
/// <summary>
/// 该函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号。系统给创建前台窗口的线程分配的权限稍高于其他线程。
/// </summary>
/// <param name="hWnd">将被激活并被调入前台的窗口句柄。</param>
/// <returns>如果窗口设入了前台,返回值为非零;如果窗口未被设入前台,返回值为零。</returns>
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
private const int WS_SHOWNORMAL = ; /// <summary>
/// 应用程序的主入口点。
/// </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>
/// 获取正在运行的实例,没有运行的实例返回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>
/// 显示已运行的程序。
/// </summary>
public static void HandleRunningInstance(Process instance)
{
ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL); //显示,可以注释掉
SetForegroundWindow(instance.MainWindowHandle); //放到前端
} }
}
三、互斥体
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Process instance = RunningInstance(); bool blnIsRunning;
Mutex mutexApp = new Mutex(false, Assembly.GetExecutingAssembly().FullName, out blnIsRunning);
if (!blnIsRunning)
{
MessageBox.Show("程序已经运行!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
} Application.Run(new Form1()); }
四、额外
public void A()
{
//=====创建互斥体法:=====
bool blnIsRunning;
Mutex mutexApp = new Mutex(false, Assembly.GetExecutingAssembly().FullName, out blnIsRunning);
if (!blnIsRunning)
{
MessageBox.Show("程序已经运行!", "提示",MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
} public void B()
{
//保证同时只有一个客户端在运行
System.Threading.Mutex mutexMyapplication = new System.Threading.Mutex(false, "OnePorcess.exe");
if (!mutexMyapplication.WaitOne(, false))
{
MessageBox.Show("程序" + Application.ProductName + "已经运行!", Application.ProductName,
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
} public void c()
{
//=====判断进程法:(修改程序名字后依然能执行)=====
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("程序已经运行!", Application.ProductName,
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
}
}
}
C#:只运行一个程序的更多相关文章
- 如何让Windows程序只运行一个程序实例?
要实现VC++或者MFC只运行一个程序实例,一般采用互斥量来实现,即首先用互斥量封装一个只运行一个程序实例的函数接口: HANDLE hMutex = NULL; void MainDlg::RunS ...
- VC只运行一个程序实例
方法有很多,以下只是提供一种用的多的 一. 单文档程序 在程序App类的InitInstance中添加如下代码 BOOL CDDZApp::InitInstance() { /*只运行一个实例*/ / ...
- 进程的互斥运行:CreateMutex函数实现只运行一个程序实例
HANDLE hMutex=CreateMutex(NULL,TRUE,"HDZBUkeyDoctorTool"); if(hMutex) { if(ERROR_ALREADY_E ...
- VC 实现程序只运行一个实例,并激活已运行的程序
转载:http://blog.sina.com.cn/s/blog_4b44e1c00100bh69.html 进程的互斥运行:CreateMutex函数实现只运行一个程序实例 正常情况下,一个进程的 ...
- C# JabLib系列之如何保证只运行一个应用程序的实现
保证只运行一个应用程序的C#实现: using System;using System.Collections.Generic;using System.Linq;using System.Windo ...
- vc++高级班之窗口篇[4]---让程序只运行一个实例
大家都看过或者使用过类似只运行一个实例的程序,比如:QQ游戏.部分浏览器 等等! 让一个程序只运行一个实例的方法有多种,但是原理都类似,也就是在程序创建后,有窗口的程序在窗口创建前, 检查系统中是 ...
- Linux编程之《只运行一个实例》
概述 有些时候,我们要求一个程序在系统中只能启动一个实例.比如,Windows自带的播放软件Windows Medea Player在Windows里就只能启动一个实例.原因很简单,如果同时启动几个实 ...
- MFC 只启动一个程序实例
问题描述: 我们开发过程中可能会经常遇到,只启动一个程序实例.即一个程序启动之后,如果再次执行该程序,将会恢复之前打开的程序,而不是打开一个新的程序. 实现原理:利用FindWindow/FindWi ...
- WinForm一次只打开一个程序
WinForm如果我们希望一次只打开一个程序,那么我们在程序每次运行的时候都需要检测线程是否存在该程序,如果存在就呼出之前的窗体,C#代码如下: using System; using System. ...
随机推荐
- 作业一直"执行"
背景:一个作业有7个步骤,前面的步骤成功/失败都转到下一步,直至最后退出,作业计划是每天早上8点执行.步骤中的语句是例行检查脚本,之前的历史记录都是一分钟内完成.此次重启数据库服务器后,检查发现此作业 ...
- Visual Studio Online
删除Visual Studio Online的项目http://taslimi.me/how-to-delete-a-team-project-from-tfs-online-tfs.visualst ...
- ios-XML文档解析之SAX解析
首先SAX解析xml *xml文档的格式特点是节点,大体思路是把每个最小的子节点作为对象的属性,每个最小子节点的'父'节点作为对象,将节点转化为对象,输出. 每个节点都是成对存在的,有开始有结束.有始 ...
- my ambition
学好java基础,不用学swing.学完java之后学my circle,之后学jsp,装好linux系统,天天打代码,在当寒假之前一定要学完并熟练运用java.java scrip,straw pu ...
- mysql慢查日志分析工具 percona-toolkit
备忘自: http://blog.csdn.net/seteor/article/details/24017913 1. 工具简介 pt-query-digest是用于分析mysql慢查询的一个工具, ...
- 使用duplicate target database ... from active database复制数据库
使用duplicate target database ... from active database复制数据库 source db:ora11auxiliary db:dupdb 1.修改监听文件 ...
- 操作系统:进程管理和IO控制
一.进程管理 进程管理包括进程控制,进程调度,进程同步与通信,死锁控制四个内容. (一)进程控制 进程是操作系统中运行的基本单位,包括程序段,数据段和进程控制段.操作系统通过进程控制块(PCB)管理进 ...
- 设置UISegmentedControl中字体大小
[segmentedControl setTitleTextAttributes:@{NSFontAttributeName : DYBoldFont(20)} forState:UIControl ...
- JAVA-面向对象-多态
多态 1.方法重载 2.方法重写 3.对象转型 4.抽象(可以定义类和方法) (关键字 abstract) ( 如: public abstract class robot )(不能修饰 ...
- 使用Navicat for Oracle新建表空间、用户及权限赋予---来自烂泥
Navicat for Oracle是有关Oracle数据库的客户端工具.通过这个客户端,我们可以图形方式对Oracle数据库进行操作. 说 明我们此次试验的Oracle数据库版本是Oracle 10 ...