`
v5qqcom
  • 浏览: 1287186 次
文章分类
社区版块
存档分类
最新评论

C#创建单实例应用程序

 
阅读更多

先看原文,后面简单翻译一下:Creating a Single Instance Application in C#

Sometimes, it's desirable to ensure that there is only ever one instance of your application running at any given time. Take Windows Live Messenger for instance - if you try to launch it whilst it is already running, it will just bring itself to the foreground instead.

Unfortunately, a lot of people try to recreate this behavior by simply checking if a process with the same name is currently running. As K. Scott Allen explains, this is not a good idea. The correct way to implement a single instance application, is to use a named mutex.

The word mutex is short for mutual exclusion, and is a synchronisation object that can only be owned by a single thread at any given time. Specifying a name for the mutex is optional - an unnamed mutex is scoped to the current process, while a named one is associated with an operating system object and can thus be used for interprocess synchronisation. Quite simply then, we can launch our application like this:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->[STAThread]
staticvoidMain()
{
boolcreatedNew=true;
using(Mutexmutex=newMutex(true,"MyApplicationName",outcreatedNew))
{
if(createdNew)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(
false);
Application.Run(
newFrmMain());
}
}
}

That ensures that there's only a single instance of our application running. Now, the above code just 'does nothing' if the application is already running - it would be nice if it instead tried to give the main window focus. To do this, we need to find the process instance, and then pinvoke the SetForeGroundWindow method of the Win32 API. Our final Main method then looks like this:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->[DllImport("user32.dll")]
[
return:MarshalAs(UnmanagedType.Bool)]
privatestaticexternboolSetForegroundWindow(IntPtrhWnd);

///<summary>
///Themainentrypointfortheapplication.
///</summary>
[STAThread]
staticvoidMain()
{
boolcreatedNew=true;
using(Mutexmutex=newMutex(true,"MyApplicationName",outcreatedNew))
{
if(createdNew)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(
false);
Application.Run(
newFrmMain());
}
else
{
Processcurrent
=Process.GetCurrentProcess();
foreach(ProcessprocessinProcess.GetProcessesByName(current.ProcessName))
{
if(process.Id!=current.Id)
{
SetForegroundWindow(process.MainWindowHandle);
break;
}
}
}
}
}

这篇文章说,很多人通过简单地检查正在运行的进程名(通过for循环,请自行搜索其他文章,已有很多例子)来判断自己的程序是否在运行,这不是一个好办法。正确的做法是使用Mutex类,Mutex就是互斥的意思。

作者首先给出了互斥的代码(没有必要使用Mutex.WaitOne()方法) ,作者使用了using来释放资源。最后作者引入了Win32 API来让窗体重新获得焦点。

这个例子没有完全达到我们所预期的功能,当运行一个实例并最小化,再次运行这个实例时,窗口仅获得焦点,并不会恢复,在SetForegroundWindow(process.MainWindowHandle);后加入一行代码就可以搞定了,需要使用Win32 API,最终代码如下:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->usingSystem;
usingSystem.Runtime.InteropServices;
usingSystem.Threading;
usingSystem.Windows.Forms;
usingSystem.Diagnostics;

namespace WinApp
{
staticclassProgram
{
[DllImport(
"user32.dll")]
[
return:MarshalAs(UnmanagedType.Bool)]
privatestaticexternboolSetForegroundWindow(IntPtrhWnd);
[DllImport(
"user32.dll")]
privatestaticexternboolShowWindowAsync(IntPtrhWnd,intnCmdShow);
privateconstintSW_HIDE=0;//隐藏窗口,活动状态给令一个窗口
privateconstintSW_SHOWNORMAL=1;//用原来的大小和位置显示一个窗口,同时令其进入活动状态
privateconstintSW_SHOWMINIMIZED=2;//最小化窗口,并将其激活
privateconstintSW_SHOWMAXIMIZED=3;//最大化窗口,并将其激活
privateconstintSW_SHOWNOACTIVATE=4;//用最近的大小和位置显示一个窗口,同时不改变活动窗口
privateconstintSW_RESTORE=9;//用原来的大小和位置显示一个窗口,同时令其进入活动状态
privateconstintSW_SHOWDEFAULT=10;//根据默认创建窗口时的样式来显示

///<summary>
///应用程序的主入口点。
///</summary>
[STAThread]
staticvoidMain()
{
boolcreatedNew=true;
using(Mutexmutex=newMutex(true,"MyApplicationName",outcreatedNew))
{
if(createdNew)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(
false);
Application.Run(
newFrmMain());
}
else
{
Processcurrent
=Process.GetCurrentProcess();
foreach(ProcessprocessinProcess.GetProcessesByName(current.ProcessName))
{
if(process.Id!=current.Id)
{
SetForegroundWindow(process.MainWindowHandle);
ShowWindowAsync(process.MainWindowHandle,SW_RESTORE);
break;
}
}
}
}
}
}
}
分享到:
评论

相关推荐

    C#电话本 控制台应用程序 软件项目课程设计

    C#电话本 控制台应用程序 软件项目课程设计 1.文件破坏处理, 若文件破坏则重新初始化 2.管理员账号保存,一个电话簿文件中内置管理员账号,一一对应。删除电话簿必须正确输入管理员账号。//管理员为第【0】条记录 ...

    C#Web应用程序入门经典

    其中前两章讲述了WEB环境和web开发的基础切识,在随后的11章中从理论和实践两个方而讲解了web应用程序的创建、测试、调试和部署等环节,如服务器控件、数探访问、数据绑定、Asp.NET状态管理、XML与web开发、web应用...

    C#开发实例大全(基础卷).软件开发技术联盟(带详细书签) PDF 下载

    实例006 设置Windows应用程序启动窗体 9 实例007 统一窗体中控件的字体设置 10 实例008 通过“格式”菜单布局窗体 10 1.3 快速开发项目必备 11 实例009 为项目添加DLL文件引用 11 实例010 为项目添加已有类 12 实例...

    C# 多线程 应用程序 实例 程序 说明文件

    C#创建多线程应用程序.rar 第9章多线程技术.rar 多线程数据采集器源码(C#+2[1].0)+v1.rar 多线程笔记.rar

    如何创建应用程序快捷方式实例C#.net源代码编写

    如何创建应用程序快捷方式实例C#.net源代码编写

    Visual C# .NET精彩编程实例集锦

    第1章 控件操作 ---------------------------------- 实例1 如何使用错误提醒控件 实例2 如何使用信息提示...实例148 如何创建Web Services程序 实例149 如何打包Web Services程序 实例150 如何访问Web Services程序

    c#如何只运行一个实例

    c#应用程序如何只运行一个实例

    C#创建Web应用程序代码实例

    本文主要通过实例代码介绍了C#创建Web应用程序,需要的朋友可以参考下

    C#网络应用编程实验指导与开发实例-源程序

    实验1 创建简单的.NET应用程序 实验2 c#基本编程方法 ……

    C#Web应用程序入门经典电子书

    其中前两章讲述了Web环境和Web开发的基础知识,在随后的11章中从理论和实践两个方面讲解了Web应用程序的创建、测试、调试和部署等环节,如服务器控件、数据绑定、ASP.NET状态管理、XML与Web开发、Web应用程序中的Web...

    构建一个简单的HTTP服务器的C#程序实例Ky_HttpServer.rar

    构建一个简单的HTTP服务器的C#程序实例。实现响应GET、POST请求。在服务端创建一个tcp通信来负责监听客户端连接。每次客户端发出请求后,我们根据请问报文来判断客户端的请求类型,然后根据不同的请求类型进行相应的...

    Visual.C#.编程精彩百例

    实例31 创建C#组件与客户应用程序 实例32 用OpenFileDialog类浏览或打开文件 实例33 在C#程序中获得Win32 API 实例34 从C#中调用COM组件 实例35 在C#程序中修改HTML文件标题 实例36 下载Web页面 实例37 创建多...

    Visual C# 2005编程实例精粹 源码

    本书用200个独立实例程序重点展示Microsoft Visual C# 2005(Microsoft.NET Framework 2.0)编程技术精华。全书摒弃语法说教,通篇贯穿实例,主要内容包括:使用ADO.NET 2.0访问数据库技巧、使用ASP.NET 2.0设计网站...

    C#程序开发范例宝典

     实例183 获取应用程序所在目录 266  实例184 得到系统当前目录 266  实例185 在程序中改变当前路径 267  6.5 复制文件 268  实例186 移动正在使用的文件 268  实例187 批量复制文件 269  ...

    C#程序开发范例宝典(第2版).part08

    实例246 创建应用程序快捷方式 340 7.5 系统设置 340 实例247 设置桌面背景 341 实例248 设置系统时间 342 实例249 设置屏幕分辨率 343 7.6 系统监控 344 实例250 检测系统启动模式 344 实例251 内存使用状态...

    通过拖动窗体的工作区来移动应用程序窗体,C#源代码,MouseDown和MouseMove方法的应用实例。

    通过拖动窗体的工作区来移动应用程序窗体,C#源代码,MouseDown和MouseMove方法的应用实例。 VisualStudio2008创建

    visual C# 2005 实例

    第1章(\C01) 示例描述:本章讲解了如何使用C#开发第一个应用程序。 Web应用程序 用C#开发的第一个Web应用程序。 Windows应用程序 用C#开发的第一个Windows应用程序。 &lt;br&gt;第3章(\C03) 示例...

    C#窗体应用小例子

    C#窗体应用例子,有两个,一个是按上下左右键移动小球,第二个是委托的实例,创建一个发布者和两个接受者,在发布者的窗口里移动鼠标,接受者显示前十坐标的变化,还有一个接受者显示发布者的轨迹。

Global site tag (gtag.js) - Google Analytics