一、通过系统事件

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#:只运行一个程序的更多相关文章

  1. 如何让Windows程序只运行一个程序实例?

    要实现VC++或者MFC只运行一个程序实例,一般采用互斥量来实现,即首先用互斥量封装一个只运行一个程序实例的函数接口: HANDLE hMutex = NULL; void MainDlg::RunS ...

  2. VC只运行一个程序实例

    方法有很多,以下只是提供一种用的多的 一. 单文档程序 在程序App类的InitInstance中添加如下代码 BOOL CDDZApp::InitInstance() { /*只运行一个实例*/ / ...

  3. 进程的互斥运行:CreateMutex函数实现只运行一个程序实例

    HANDLE hMutex=CreateMutex(NULL,TRUE,"HDZBUkeyDoctorTool"); if(hMutex) { if(ERROR_ALREADY_E ...

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

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

  5. C# JabLib系列之如何保证只运行一个应用程序的实现

    保证只运行一个应用程序的C#实现: using System;using System.Collections.Generic;using System.Linq;using System.Windo ...

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

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

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

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

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

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

  9. WinForm一次只打开一个程序

    WinForm如果我们希望一次只打开一个程序,那么我们在程序每次运行的时候都需要检测线程是否存在该程序,如果存在就呼出之前的窗体,C#代码如下: using System; using System. ...

随机推荐

  1. Java Set操作

    Set:无顺序,不包含重复的元素 HashSet:为快速查找设计的Set.存入HashSet的对象必须定义hashCode(). TreeSet: 保存次序的Set, 底层为树结构.使用它可以从Set ...

  2. iOS 在一个应用程序中调另一个应用程序

    在A应用程序中调用B应用程序 1. 首先在B应用程序中生成URL 1)点击targets文件 2)点击Info 3)生成URL ①在Info.plist文件中点击+(新添加一项) ②在Info.pli ...

  3. Using Amazon API Gateway with microservices deployed on Amazon ECS

    One convenient way to run microservices is to deploy them as Docker containers. Docker containers ar ...

  4. C# 统计程序执行时间

    随便写写,小马哥勿怪 最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷.     话说马云年轻的时候也是屌丝一枚,有图为证 现 ...

  5. leetcode 116- Populating Next Right Pointers in Each Node

    题目: Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode ...

  6. leetcode-5 最长回文子串(动态规划)

    题目要求: * 给定字符串,求解最长回文子串 * 字符串最长为1000 * 存在独一无二的最长回文字符串 求解思路: * 回文字符串的子串也是回文,比如P[i,j](表示以i开始以j结束的子串)是回文 ...

  7. IOS 加载Xib 后 如何 动态修改xib中的控件frame

    看看xib里view是不是设置了自动布局 use auto layout.取消掉就可以了.

  8. PostgreSQL Replication之第十章 配置Slony(6)

    10.6 执行故障切换 一旦您学会了如何复制表并将它们添加到集合中,是时候学习故障转移了.基本上,我们可以在两个两种类型的故障转移之间做出区分: • 计划内故障转移 • 计划外故障转移和崩溃 在本节, ...

  9. CentOS 7 安装Dukto(局域网通信工具)

    rmp包 http://download.opensuse.org/repositories/home:/colomboem/CentOS_7/x86_64/dukto-6.0-13.1.x86_64 ...

  10. ACdream 1157 Segments(CDQ分治)

    题目链接:http://acdream.info/problem?pid=1157 Problem Description 由3钟类型操作:1)D L R(1 <= L <= R < ...