扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:中国IT实验室 来源:中国IT实验室 2007年10月2日
关键字:
在本页阅读全文(共2页)
运行标志
使用应用程序运行标志简单来讲就是在程序初始化的时候设置一个标志表示程序已运行,在程序运行结束的时候删除该标志。
基本步骤如下,
1.应用程序初始化检查运行标志是否已经设置;
2.发现已经设置,说明已有应用程序实例运行,停止当前程序初始化,提示已有应用程序运行。 3.发现没有设置,说明没有应用程序实例运行,继续当前程序初始化。
4.退出应用程序时删除该运行标志。
对于标志存储载体可以使用注册表、数据库或外部文件等,这里的代码使用外部文件实现。对存放标志的文件目录选择C:\Documents and Settings\All Users\Application Data,也可以是C:\Program Files\Common Files。
声明类成员标志文件名称变量,
private static string runFlagFullname = null;
初始化程序运行标志,如果设置成功,返回true,已经设置返回false,设置失败将抛出异常,
public static bool InitRunFlag()
{
if (File.Exists(RunFlag))
{
return false;
}
using (FileStream fs = new FileStream(RunFlag, FileMode.Create))
{
}
return true;
}
释放初始化程序运行标志,如果释放失败将抛出异常,
public static void DisposeRunFlag()
{
if (File.Exists(RunFlag))
{
File.Delete(RunFlag);
}
}
获取或设置程序运行标志,必须符合Windows文件命名规范,
public static string RunFlag
{
get
{
if(runFlagFullname == null)
{
string assemblyFullName = Assembly.GetEntryAssembly().FullName;
string path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
runFlagFullname = Path.Combine(path, assemblyFullName);
}
return runFlagFullname;
}
set
{
runFlagFullname = value;
}
}
在Main函数中调用下面代码实现单一应用程序实例,
if (SingleInstance.InitRunFlag())
{
Application.Run(new MainForm());
SingleInstance.DisposeRunFlag();
}
else
{
MessageBox.Show("程序已经运行!");
}
可见,在上面的实现过程中,需要访问文件IO,因此有可能会出现异常,对异常需要进行具体处理。如果不同应用程序使用了相同的运行标志,也会出现进程互斥实现中存在的问题。由于运行标志存在外部载体中,如果笔者把启动的应用程序进程实例直接在Windows管理器进程列表中结束或使其产生异常,那设置的运行标志就不会销毁,应用程序就没法再次运行。
功能测试
这一节对上面的三个功能进行测试,以分析之间的区别。功能测试类别包括下面五类,
1.本地系统同一应用程序目录;
2.本地系统同一应用程序修改运行文件名称使两次运行名称不同;
3.本地系统两次运行程序目录不同,不修改文件名称;
4.本地系统不同会话用户登录启动应用程序;
5.远程计算机程序访问启动应用程序(一个程序在远程另一个在本地)。
根据代码实现细节不同,对测试的结果可能会有所不同,这里的测试结果以笔者上面几节中实现的代码为准。为了测试简单化,通过给应用程序传入测试参数,决定使用哪种方式,入口函数调用代码为,
[STAThread]
static void Main(string[] args)
{
if (args.Length == 0) //没有传送参数
{
Process p = SingleInstance.GetRunningInstance();
if (p != null) //已经有应用程序副本执行
SingleInstance.HandleRunningInstance(p);
else //启动第一个应用程序
Application.Run(new MainForm());
}
else //有多个参数
{
switch (args[0].ToLower())
{
case "-api":
if (SingleInstance.HandleRunningInstance() == false)
Application.Run(new MainForm());
break;
case "-mutex":
if (args.Length >= 2) //参数中传入互斥体名称
{
if ( SingleInstance.CreateMutex(args[1]) )
{
Application.Run(new MainForm());
SingleInstance.ReleaseMutex();
}
else
//调用SingleInstance.HandleRunningInstance()方法显示到前台。
MessageBox.Show("程序已经运行!");
}
else
{
if (SingleInstance.CreateMutex())
{
Application.Run(new MainForm());
SingleInstance.ReleaseMutex();
}
else
//调用SingleInstance.HandleRunningInstance()方法显示到前台。
MessageBox.Show("程序已经运行!");
}
break;
case "-flag"://使用该方式需要在程序退出时调用
if (args.Length >= 2) //参数中传入运行标志文件名称
SingleInstance.RunFlag = args[1];
try
{
if (SingleInstance.InitRunFlag())
{
Application.Run(new MainForm());
SingleInstance.DisposeRunFlag();
}
else
//调用SingleInstance.HandleRunningInstance()方法显示到前台。
MessageBox.Show("程序已经运行!");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
break;
default:
MessageBox.Show("应用程序参数设置失败。");
break;
}
}
}
运行CMD命令行,
第一种调用为, WindowsApplication1.exe ?api 或 WindowsApplication1.exe
第二种调用为, WindowsApplication1.exe ?mutex 或WindowsApplication1.exe ?mutex {F140AE26-626C-42f8-BD49-45025742205E}
第三种调用为, WindowsApplication1.exe ?flag 或WindowsApplication1.exe ?flag c:\blog.csdn.net.zhzuo
测试结果,
匹配/互斥/标志 | 1同一目录 | 2修改名称 | 3不同目录 | 4不同用户 | 5远程访问 |
1同一目录 | O/O/O | ||||
2修改名称 | X/O/O | ||||
3不同目录 | X/O/O | ||||
4不同用户 | #/X/O | ||||
5远程访问 | X/O/O |
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者