C#下,如何防止被实例化winForm程序运行两个实例

C#winform程序 如何避免开两个
[问题点数:30分,结帖人u]
C#winform程序 如何避免开两个
[问题点数:30分,结帖人u]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
匿名用户不能发表回复!|解决C#程序只允许运行一个实例的几种方法详解
转载 &更新时间:日 10:41:25 & 作者:
本篇文章是对C#中程序只允许运行一个实例的几种方法进行了详细的分析介绍,需要的朋友参考下
本文和大家讲一下如何使用C#来创建系统中只能有该程序的一个实例运行。要实现程序的互斥,通常有下面几种方式,下面用 C# 语言来实现:方法一:使用线程互斥变量. 通过定义互斥变量来判断是否已运行实例.把program.cs文件里的Main()函数改为如下代码: 代码如下:using Susing System.Windows.Fusing System.Runtime.InteropSnamespace NetTools{&&& static class Program&&& {&&&&&&& [DllImport("user32.dll")]&&&&&&& private static extern bool FlashWindow(IntPtr hWnd, bool bInvert);&&&&&&& [DllImport("user32.dll")]&&&&&&& private static extern bool FlashWindowEx(int pfwi);&&&&&&& /// &summary&&&&&&&& /// 应用程序的主入口点。&&&&&&& /// &/summary&&&&&&&& [STAThread]&&&&&&& static void Main()&&&&&&& {&&&&&&&&&&&&&&&&&&&&&& System.Threading.Mutex run = new System.Threading.Mutex(true, "single_test", out runone);&&&&&&&&&&& if (runone)&&&&&&&&&&& {&&&&&&&&&&&&&&& run.ReleaseMutex();&&&&&&&&&&&&&&& Application.EnableVisualStyles();&&&&&&&&&&&&&&& Application.SetCompatibleTextRenderingDefault(false);&&&&&&&&&&&&&&& FrmRemote frm = new FrmRemote();&&&&&&&&&&&&&&& int hdc = frm.Handle.ToInt32(); // write to ...&&&&&&&&&&&&&&& Application.Run(frm);&&&&&&&&&&&&&&& IntPtr a = new IntPtr(hdc);&&&&&&&&&&& }&&&&&&&&&&& else&&&&&&&&&&& {&&&&&&&&&&&&&&& MessageBox.Show("已经运行了一个实例了。");&&&&&&&&&&&&&&& //IntPtr hdc = new IntPtr(1312810); // read from...&&&&&&&&&&&&&&& //bool flash = FlashWindow(hdc, true);&&&&&&&&&&& }&&&&&&& }&&& }}说明:程序中通过语句 System.Threading.Mutex run = new System.Threading.Mutex(true, "single_test", out runone);来创建一个互斥体变量run,其中"single_test"为互斥体名,在此方法返回时,如果创建了局部互斥体或指定的命名系统互斥体,则布尔值runone为true;如果指定的命名系统互斥体已存在,则为 false。已命名的互斥体是系统范围的。方法二:采用判断进程的方式,我们在运行程序前,查找进程中是否有同名的进程,同时运行位置也相同程,如是没有运行该程序,如果有就就不运行.在C#中应用System.Diagnostics名字空间中的Process类来实现,主要代码如下: 1,在program.cs文件中添加函数如下: 代码如下:public static System.Diagnostics.Process RunningInstance() { System.Diagnostics.Process current = System.Diagnostics.Process.GetCurrentProcess(); System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcesses(); foreach (System.Diagnostics.Process process in processes) //查找相同名称的进程 { if (process.Id != current.Id) //忽略当前进程 { //确认相同进程的程序运行位置是否一样. if (System.Reflection.Assembly.GetExecutingAssembly().Location.Replace("/", @"/") == current.MainModule.FileName) & { //Return the other process instance. && & } } } //No other instance was found, return null.
} 2,把Main ()函数改为如下代码: 代码如下:static void Main() { if(RunningInstance()==null) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } else { MessageBox.Show("已经运行了一个实例了。"); } } 方法三:全局原子法,创建程序前,先检查全局原子表中看是否存在特定原子A(创建时添加的),存在时停止创建,说明该程序已运行了一个实例;不存在则运行程序并想全局原子表中添加特定原子A;退出程序时要记得释放特定的原子A哦,不然要到关机才会释放。C#实现如下: 1.申明WinAPI函数接口 代码如下:[System.Runtime.InteropServices.DllImport("kernel32.dll")] public static extern UInt32 GlobalAddAtom(String lpString); //添加原子 [System.Runtime.InteropServices.DllImport("kernel32.dll")] public static extern UInt32 GlobalFindAtom(String lpString); //查找原子 [System.Runtime.InteropServices.DllImport("kernel32.dll")] public static extern UInt32 GlobalDeleteAtom(UInt32 nAtom); //删除原子2.修改Main()函数如下: 代码如下:static void Main() { if (GlobalFindAtom("jiaao_test") == ) //没找到原子"jiaao_test" { GlobalAddAtom("jiaao_test"); //添加原子"jiaao_test" Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } else { MessageBox.Show("已经运行了一个实例了。"); } } 3.在FormClosed事件中添加如下代码: GlobalDeleteAtom(GlobalFindAtom("jiaao_test"));//删除原子"jiaao_test" --------------------------------------*-------*--------*-----------------------------------------------以上为创建互斥程序的基本通用的思想,个人认为,第一种方法最简单。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具C#限制程序只能运行一個实例 (防多开) - 快乐家++ - 博客园
posts - 244, comments - 167, trackbacks - 0, articles - 14
//方法一:只禁止多个进程运行
using System.Collections.G
using System.Windows.F
namespace DuoYeMianIE
static class Program
/// &summary&
/// 应用程序的主入口点。
/// &/summary&
[STAThread]
static void Main()
System.Threading.Mutex mutex = new System.Threading.Mutex(true, Application.ProductName, out ret);
System.Windows.Forms.Application.EnableVisualStyles();
//这两行实现
System.Windows.Forms.Application.DoEvents();
//这两行实现
System.Windows.Forms.Application.Run(new LamBrowser());
为你程序的主窗体,如果是控制台程序不用这句
mutex.ReleaseMutex();
MessageBox.Show(null, "有一个和本程序相同的应用程序已经在运行,请不要同时运行多个本程序。\n\n这个程序即将退出。", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
提示信息,可以删除。
Application.Exit();//退出程序
//方法二:禁止多个进程运行,并当重复运行时激活以前的进程
using System.Collections.G
using System.Windows.F
using System.D
using System.Runtime.InteropS
using System.R
namespace DuoYeMianIE
static class Program
/// &summary&
/// 应用程序的主入口点。
/// &/summary&
[STAThread]
static void Main()
Process instance = RunningInstance();
if (instance == null)
{ System.Windows.Forms.Application.EnableVisualStyles();
//这两行实现
System.Windows.Forms.Application.DoEvents();
System.Windows.Forms.Application.Run(new LamBrowser());
HandleRunningInstance(instance);
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 null;
public static void HandleRunningInstance(Process instance)
ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL);
foreground
SetForegroundWindow(instance.MainWindowHandle);
[DllImport("User32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
private const int WS_SHOWNORMAL = 1;没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!托盘程序的制作:
1.把NotifyIcon控件拉一个到窗体上,并设置NotifyIcon的Icon(很重要!否则运行后看不到效果)2.窗体关闭时,将程序最小化到系统托盘上
private&void&Form1_FormClosing(object&sender,&FormClosingEventArgs&e)&{&&&&//MessageBox.Show("程序将最小化到系统托盘区");&&&&e.Cancel&=&true;&//&取消关闭窗体&&&&&this.Hide();&&&&this.ShowInTaskbar&=&false;//取消窗体在任务栏的显示&&&&&this.notifyIcon1.Visible&=&true;//显示托盘图标&}&
3.放一个上下文菜单,添加几个基本项,"显示主窗体","退出" ,将这个菜单挂到NotifyIcon上
private&void&menuShow_Click(object&sender,&EventArgs&e)&{&&&&&&&&this.Show();&&&&this.ShowInTaskbar&=&true;&&&&this.notifyIcon1.Visible&=&false;}private&void&menuExit_Click(object&sender,&EventArgs&e)&{&&&&this.Dispose(true);&&&&Application.ExitThread();}&
4.左键单击托盘图标时,显示主窗体,右击时当然是弹出上面设置的菜单
private&void&notifyIcon1_MouseClick(object&sender,&MouseEventArgs&e)&{&&&&if&(e.Button&==&MouseButtons.Left)&&{&&&&&&&&this.Show();&&&&&&&&this.ShowInTaskbar&=&true;&&&&&&&&this.notifyIcon1.Visible&=&false;&&&&}}
防止这个程序同时运行多个
using&Susing&System.Collections.Gusing&System.Windows.Fusing&System.Tnamespace&LuceneTest&{&&&&static&class&Program&&&&&{&&&&&&&&&///&&summary&&&&&&&&&///&应用程序的主入口点。&&&&&&&&///&&/summary&&&&&&&&&[STAThread]&&&&&&&&static&void&Main()&&&&&&&&&{&&&&&&&&&&&&bool&bCreatedN&&&&&&&&&&&&Mutex&m&=&new&Mutex(false,&"Product_Index_Cntvs",&out&bCreatedNew);&&&&&&&&&&&&if&(bCreatedNew)&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&Application.EnableVisualStyles();&&&&&&&&&&&&&&&&Application.SetCompatibleTextRenderingDefault(false);&&&&&&&&&&&&&&&&Application.Run(new&Form1());&&&&&&&&&&&&}&&&&&&&&}&&&&}}
一. 托盘程序的主要步骤及解决方法:
  为什么说用VisualC#可以十分方便的做一个托盘程序,主要的原因是在.Net框架的软件开发包( .Net FrameWork SDK)中的WinForm组件中定义了一个专门用来开发托盘程序的组件--NotifyIcon组件。下面就来介绍一下这个组件的具体用法和程序设计中的主要的技巧。
  (1).如何在程序运行后隐藏窗体:
  我们知道托盘程序运行后是无法看见主窗体的,他只会显示在工具栏上。在用VisualC#设计此类程序的时候,可以用二种方法使得程序运行后不显示主窗体。其中一种方法是重载主窗体中的OnActivated()事件,OnActivated( )事件是在窗体激活的时候才触发的。通过重载此事件可以达到隐藏主窗体的目的。具体程序代码如下:
protected override void OnActivated ( EventArgs e )&{&this.Hide ( ) ;&}
  另外一种方法是在初始化主窗体的时候完成的,通过设定主窗体的属性来达到不显示的目的。具体的程序代码如下:
this.MaximizeBox =&this.MinimizeBox =&this.WindowState = System.Windows.Forms.FormWindowState.M
  在本文介绍的程序中,使用了第二种方法。&(2).如何为托盘程序设定显示图标:
  在NotifyIcon组件中有一个属性icon就是来设定托盘图标的,由于Visual C#是一个完全的OOP(面向对象)语言,在VisualC#中任何东西都可以作为对象来处理。当然对应一个icon来说,也可以用对象的方法来处理他。我们通过下列语句来得到一个icon对象:
private Icon mNetTrayIcon = new Icon ( "Tray.ico" ) ;
  请注意:在编译好的程序中,必须要在同一个目录中有一个Tray.ico图标文件,否则程序运行时候会出错的。
  通过下列语句把此icon对象付给NotifyIcon组件中的icon属性,此时如果程序正确编译,则此icon就会显示在工具栏中了。
TrayIcon.Icon = mNetTrayI
  (3).设定当鼠标停留在托盘程序上显示的文本内容:
  NotifyIcon组件中有一个属性Text。设定这个属性的内容,就是鼠标停留在托盘图标上显示的内容了。具体语句如下:
TrayIcon.Text = "用Visual C#做托盘程序" + "\n" + "作者:毛泳皓于";
  (4).如何在托盘程序加入菜单:
  在NotifyIcon组件中有一个对象叫ContextMenu,在托盘程序中显示出的菜单就是通过设定此对象来实现的。以下的程序代码是为托盘程序加入菜单项:
notifyiconMnu = new ContextMenu ( mnuItms ) ;&TrayIcon.ContextMenu = notifyiconM&//为托盘程序设定菜单
  (5).如何设定ContextMenu对象的内容:
  ContextMenu对象是托盘程序的菜单的结构,所以如何设定此对象,在本程序中是比较关键的。在程序中,是通过定义一个菜单项数组,并对这个数组设定不同的值(这当中包括菜单的一些属性和事件),然后把这个数组同时赋值给ContextMenu对象,来实现对ContextMenu对象的设置过程的。以下是程序中具体代码:
//定义一个MenuItem数组,并把此数组同时赋值给ContextMenu对象&MenuItem [ ] mnuItms = new MenuItem [ 3 ] ;&mnuItms [ 0 ] = new MenuItem ( ) ;&mnuItms [ 0 ] .Text = "用Visual C#做托盘程序!" ;&mnuItms [ 0 ] .Click += new System.EventHandler ( this.showmessage ) ;
mnuItms [ 1 ] = new MenuItem ( "-" ) ;&mnuItms [ 2 ] = new MenuItem ( ) ;&mnuItms [ 2 ] .Text = "退出系统" ;&mnuItms [ 2 ] .Click += new System.EventHandler ( this.ExitSelect ) ;&mnuItms [ 2 ] .DefaultItem =
notifyiconMnu = new ContextMenu ( mnuItms ) ;&TrayIcon.ContextMenu = notifyiconM&//为托盘程序加入设定好的ContextMenu对象
  当成功加入了ContextMenu对象后,在程序编译完成运行时,当鼠标右键点击托盘图标,程序会自动弹出ContextMenu对象封装好的菜单。
  二. 本文介绍的程序源代码( Tray.cs ):&Tray.cs源程序代码:
using S&using System.D&using System.C&using System.ComponentM&using System.Windows.F&using System.D&//导入在程序中使用到的名称空间&public class Tray : Form&{& private System.ComponentModel.Container components =& private Icon mNetTrayIcon = new Icon ("Tray.ico" ) ;& private NotifyIcon TrayI& private ContextMenu notifyiconM
 publicTray()& {&  //初始化窗体中使用到的组件&  InitializeComponent ( ) ;&  //初始化托盘程序的各个要素&  Initializenotifyicon ( ) ;& }
private void Initializenotifyicon ( )&{& //设定托盘程序的各个属性& TrayIcon = new NotifyIcon ( ) ;& TrayIcon.Icon = mNetTrayI& TrayIcon.Text = "用VisualC#做托盘程序" + "\n" + "作者:马金虎于" ;& TrayIcon.Visible =& TrayIcon.Click += new System.EventHandler ( this.click) ;
 //定义一个MenuItem数组,并把此数组同时赋值给ContextMenu对象& MenuItem [ ] mnuItms = new MenuItem [ 3 ] ;& mnuItms [ 0 ] = new MenuItem ( ) ;& mnuItms [ 0 ] .Text = "用VisualC#做托盘程序!" ;& mnuItms [ 0 ] .Click += new System.EventHandler (this.showmessage ) ;
 mnuItms[ 1 ] = new MenuItem ( "-" ) ;
 mnuItms[ 2 ] = new MenuItem ( ) ;& mnuItms [ 2 ] .Text = "退出系统" ;& mnuItms [ 2 ] .Click += new System.EventHandler (this.ExitSelect ) ;& mnuItms [ 2 ] .DefaultItem =
 notifyiconMnu= new ContextMenu ( mnuItms ) ;& TrayIcon.ContextMenu = notifyiconM& //为托盘程序加入设定好的ContextMenu对象&}&public void click ( object sender , System.EventArgs e )&{& MessageBox.Show ( "Visual C#编写托盘程序中的事件响应" ) ;&}
public void showmessage ( object sender , System.EventArgs e )&{& MessageBox.Show ( "你点击了菜单的第一个选项" ) ;&}
public void ExitSelect ( object sender , System.EventArgs e )&{& //隐藏托盘程序中的图标& TrayIcon.Visible =& //关闭系统& this.Close ( ) ;&}&//清除程序中使用过的资源&public override void Dispose ( )&{& base.Dispose ( ) ;& if ( components != null )&  components.Dispose ( ) ;&}&软件开发网&www.mscto.com
private void InitializeComponent ( )&{& this.SuspendLayout ( ) ;& this.AutoScaleBaseSize = new System.Drawing.Size ( 5 ,13 ) ;& this.ClientSize = new System.Drawing.Size ( 320 , 56 );& this.ControlBox =& this.MaximizeBox =& this.MinimizeBox =& this.WindowState = System.Windows.Forms.FormWindowState.M
 this.Name= "tray" ;& this.ShowInTaskbar =& this.Text = "用Visual C#做托盘程序!" ;& this.ResumeLayout ( false ) ;
}&static void Main ( )&{& Application.Run ( new Tray ( ) ) ;&}&}
  三. 总结:
  通过以上介绍,可以看出用Visual C#做一个托盘程序并不是一件复杂的事情,而是一件比较轻松的事情。同样也可使我们明白,VisualC#虽然是一种功能强大的程序设计语言,但它只是一个打开.NetFrameWorkSDK的钥匙,正是这个内容丰富的软件包,才使得各个.Net程序开发语言有了施展自身功能更广阔的舞台。
C#如何制作托盘程序&&
&以QQ界面为例子,通常使用QQ时都会发现有一个托盘程序,当QQ界面隐藏时双击托盘图标就可以还原程序。这是怎么实现的呢?为了实现这个功能我该怎么做呢?
用C#实现托盘程序相当简单,只需要一个插件协助。如果使用Java实现托盘程序则相对复杂,需要手动编写大量代码。C#实现步骤如下:
1.创建一个新窗体Form1,拖动控件NotifyIcon到窗体中
2.创建三个PictureBox,并将它们分别插入图片&&
3.然后修改NotifyIcon的对象notifyIcon1属性this.notifyIcon1.Text =&"双击恢复"&;this.notifyIcon1.Icon =&图标路径建立一个托盘图标鼠标双击事件&&&&&&& /// &summary&&&&&&&& ///&双击托盘事件&&&&&&& /// &/summary&&&&&&&& /// &param name="sender"&&/param&&&&&&&& /// &param name="e"&&/param&&&&&&&&&private void&notifyIcon1_MouseDoubleClick(object&sender,&MouseEventArgs&e)&&&&&&& {&&&&&&&&&&&&this.Visible =&true;&&&&&&&&&&&&this.notifyIcon1.Visible =&false;&&&&&&& }
4.在三个PictureBox中分别写入单击事件&&&&&&&&/// &summary&&&&&&&& ///&退出按钮事件&&&&&&& /// &/summary&&&&&&&& /// &param name="sender"&&/param&&&&&&&& /// &param name="e"&&/param&&&&&&&&&private void&pictureBox_close_Click(object&sender,&EventArgs&e)&&&&&&& {&&&&&&&&&&&&if&(MessageBox.Show("确定退出?", "提示",&MessageBoxButtons.YesNo,&MessageBoxIcon.Question,MessageBoxDefaultButton.Button2) ==&DialogResult.Yes)&&&&&&&&&&& {&&&&&&&&&&&&&&&&Application.Exit();&&&&&&&&&&& }&&&&&&& }
&&&&&&&&/// &summary&&&&&&&& ///&最小化窗口按钮事件&&&&&&& /// &/summary&&&&&&&& /// &param name="sender"&&/param&&&&&&&& /// &param name="e"&&/param&&&&&&&&&private void&pictureBox_min_Click(object&sender,&EventArgs&e)&&&&&&& {&&&&&&&&&&&&this.WindowState = System.Windows.Forms.FormWindowState.M&&&&&&& }
&&&&&&&&/// &summary&&&&&&&& ///&最小化到托盘事件&&&&&&& /// &/summary&&&&&&&& /// &param name="sender"&&/param&&&&&&&& /// &param name="e"&&/param&&&&&&&&&private void&pictureBox_hide_Click(object&sender,&EventArgs&e)&&&&&&& {&&&&&&&&&&&&this.Visible =&false;&&&&&&&&&&&&this.notifyIcon1.Visible =&true&;&&&&&&& }
&完成以上步骤后,托盘程序就做好了。点击&就隐藏窗体出现托盘,双击托盘还原窗体隐藏托盘图标
阅读(...) 评论()

我要回帖

更多关于 java程序运行 的文章

 

随机推荐