C# WinForm 程序如何只允许运行一个实例 ?

RT,C#WinForm程序如何只允许运行一个实例?高手指教!... RT,C# WinForm 程序如何只允许运行一个实例 ?
高手指教 !
展开
 我来答
bjddd192
2009-12-05 · TA获得超过416个赞
知道小有建树答主
回答量:496
采纳率:0%
帮助的人:435万
展开全部
C#禁止应用程序同时运行的方法
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace SingleProcessStart
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
//
//使用STAThread属性将程序的默认线程模型指定为单线程模型。
//注意,线程模型只影响使用COM interop的应用程序,将这个属性应用于不使用COM interop的程序将不会产生任何效果。
[STAThread]
//[MTAThreadAttribute]
static void Main()
{
////原始
//Application.EnableVisualStyles();
//Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(new Form1());

//方法一,使用线程互斥
//bool createdNew = false;
//System.Threading.Mutex mutex = new System.Threading.Mutex(true, "OnlyOnceTime", out createdNew);
//if (createdNew)
//{
// Application.EnableVisualStyles();
// Application.SetCompatibleTextRenderingDefault(false);
// Application.Run(new Form1());
//}
//else
//{
// MessageBox.Show("程序已经运行!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
//}

//方法二,使用API实现
/*
* 关于方法二的调试,需要注意的是要将项目--属性--调试,选择启用外部程序,选择到你的EXE文件,然后先开启你的EXE文件
* 否则在调试时.NET默认会使用vshost.exe的宿主进程(宿主进程随.NET启动而启动),而此宿主进程在外部无法启用,因此永远是唯一的
*/
System.Diagnostics.Process p = GetRunningInstance();
if (p != null) //已经有应用程序副本执行
{
HandleRunningInstance(p);
}
else //启动第一个应用程序
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}

//以下为方法二调用API代码
private const int WS_HIDE = 0;//窗口隐藏
private const int WS_SHOWNORMAL = 1;//窗口处于正常状态
private const int WS_SHOWMIN = 2;//窗口处于最小化状态
private const int WS_SHOWMAX = 3;//窗口处于最大化状态

/// <summary>
/// 显示窗口
/// </summary>
/// <param name="hWnd">句柄</param>
/// <param name="cmdShow">显示模式</param>
/// <returns></returns>
[System.Runtime.InteropServices.DllImport("User32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);

[System.Runtime.InteropServices.DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);

/// <summary>
/// 查找窗口的句柄
/// </summary>
/// <param name="className">指向包含了窗口类名的空中止(C语言)字串的指针;或设为零,表示接收任何类</param>
/// <param name="titleName">指向包含了窗口文本(或标签)的空中止(C语言)字串的指针;或设为零,表示接收任何窗口标题</param>
/// <returns>句柄</returns>
[System.Runtime.InteropServices.DllImport("User32.dll", EntryPoint = "FindWindow")]
public static extern int FindWindow(string className, string titleName);

/// <summary>
/// 获取应用程序进程实例,如果没有匹配进程,返回Null
/// </summary>
/// <returns>返回当前Process实例</returns>
public static System.Diagnostics.Process GetRunningInstance()
{
//获取当前进程
System.Diagnostics.Process currentProcess = System.Diagnostics.Process.GetCurrentProcess();

//获取当前运行程序完全限定名
string currentFileName = currentProcess.MainModule.FileName;

//获取进程名为ProcessName的Process数组。
System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName(currentProcess.ProcessName);

//遍历有相同进程名称正在运行的进程
foreach (System.Diagnostics.Process process in processes)
{
if (process.MainModule.FileName == currentFileName)
{
if (process.Id != currentProcess.Id)//根据进程ID排除当前进程
return process;//返回已运行的进程实例
}
}
return null;
}

/// <summary>
/// 获取应用程序句柄,设置应用程序前台运行,并返回bool值
/// </summary>
public static bool HandleRunningInstance(System.Diagnostics.Process instance)
{
IntPtr intPtr = new IntPtr(instance.MainWindowHandle.ToInt32() == 0 ?
FindWindow(null, "Form1") : instance.MainWindowHandle.ToInt32());

//使窗口最大化
ShowWindowAsync(intPtr, WS_SHOWMAX);

//设置前台进程为已运行的进程,而现有进程继续执行至进程结束(在这里跑完MAIN函数就结束掉了)
return SetForegroundWindow(instance.MainWindowHandle);
}

/// <summary>
/// 获取窗口句柄,设置应用程序前台运行,并返回bool值,重载方法
/// </summary>
/// <returns></returns>
public static bool HandleRunningInstance()
{
System.Diagnostics.Process p = GetRunningInstance();
if (p != null)
{
HandleRunningInstance(p);
return true;
}
return false;
}
}
}
百度网友4c7c04d
2009-12-07 · TA获得超过693个赞
知道小有建树答主
回答量:589
采纳率:0%
帮助的人:579万
展开全部
//我来补充注释啦
static void Main()
{
bool canCreateNew; //用来承接是否已经有一个实例在运行的布尔变量
//限制单例运行
Mutex m = new Mutex(
true //如果为 true,则给予调用线程已命名的系统互斥体的
//初始所属权(如果已命名的系统互斥体是通过此调用创建的);
//否则为 false。
, "AnyName" //Mutex 的名称。如果值为 null,
//则 Mutex 是未命名的。
, out canCreateNew //在此方法返回时,如果创建了局部互斥体
//(即,如果name为null或空字符串)或指定的命名系统互斥体,
//则包含布尔值 true;如果指定的命名系统互斥体已存在,
//则为 false。该参数未经初始化即被传递。
);
if (canCreateNew)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FormMain());
m.ReleaseMutex(); //必须
}
else
{
//
}
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
lcg1986
2009-12-04 · TA获得超过3374个赞
知道大有可为答主
回答量:1858
采纳率:90%
帮助的人:1612万
展开全部
楼上的不太好.还写死了"WindowsFormApplication1"

/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
ConfigManager.LoadConfiguration();//这里我是读了配置,是否允许多实例
if (Global.GlobalVariable.SingleInstance) //如果配置不允许多实例
{
Process pCurrent = Process.GetCurrentProcess();
Process[] pList = Process.GetProcessesByName(pCurrent.ProcessName);
if (pList.Length >= 2)
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new LoginForm());
}
本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
百度网友235ece7
2009-12-04
知道答主
回答量:21
采纳率:0%
帮助的人:29.1万
展开全部
lcg1986的方法好点 通过配置信息控制的话程序会灵活许多
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
sonichu
2009-12-04 · TA获得超过508个赞
知道小有建树答主
回答量:375
采纳率:100%
帮助的人:313万
展开全部
[STAThread]
static void Main()
{
bool CreateNew;
System.Threading.Mutex mutex = new System.Threading.Mutex(false, "WindowsFormsApplication1", out CreateNew);
if (!CreateNew)
{
System.Windows.Forms.MessageBox.Show("程序已运行");
Application.Exit();
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(3)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式