用C#给程序加启动画面并只允许一个应用程序实例运行
2024-07-21 02:18:44
供稿:网友
涉及类:
1、 启动画面类:
public class splashform : system.windows.forms.form
{
private system.windows.forms.picturebox picturebox1;
private system.windows.forms.label label1;
private system.windows.forms.label lbl_version;
/// <summary>
/// 必需的设计器变量。
/// </summary>
private system.componentmodel.container components = null;
public splashform()
{
//
// windows 窗体设计器支持所必需的
//
initializecomponent();
lbl_version.text = "版本:" + application.productversion;
//
// todo: 在 initializecomponent 调用后添加任何构造函数代码
//
}
//以下省略
2、 应用程序加载类:
using system;
using system.drawing;
using system.collections;
using system.componentmodel;
using system.windows.forms;
using system.data;
using system.runtime.interopservices;
using system.diagnostics;
using system.reflection;
using system.io;
namespace heroic.tempanalyse.tempgui
{
/// <summary>
/// apploader 的摘要说明。
/// </summary>
public class apploader
{
private static applicationcontext context;
private static splashform sform = new splashform();
private static mainwindow mform = null;
//0不可见但仍然运行,1居中,2最小化,3最大化
private const int ws_shownormal = 3;
[stathread]
static void main(string[] args)
{
// [8/12/2004]用于更新该程序。
doupdata();
// [7/19/2004] 改变顺序,目的使得开始加载速度加快
//得到正在运行的例程
process instance = runninginstance();
if(instance == null)
{
sform.show();
mform = new mainwindow();
context = new applicationcontext();
application.idle += new eventhandler(onappidle);
application.run(context);
}
else
{
//处理发现的例程
handlerunninginstance(instance);
//messagebox.show("当前程序已经运行了!");
}
}
//在线更新用,不再本文范围
private static void doupdata()
{
system.diagnostics.process.start([email protected]"/update.exe",[email protected]"/heroic.tempanalyse.tempgui.exe 0");//
}
private static void onappidle(object sender, eventargs e)
{
if(context.mainform == null)
{
application.idle -= new eventhandler(onappidle);
mform.preload();
context.mainform = mform;
context.mainform.show();
sform.close();
sform = null;
}
}
//不允许有两个程序同时启动
public static process runninginstance()
{
process current = process.getcurrentprocess();
process[] processes = process.getprocessesbyname (current.processname);
//遍历正在有相同名字运行的例程
foreach (process process in processes)
{
//忽略现有的例程
if (process.id != current.id)
{
//确保例程从exe文件运行
if (assembly.getexecutingassembly().location.replace("/", "//") ==
current.mainmodule.filename)
{
//返回另一个例程实例
return process;
}
}
}
//没有其它的例程,返回null
return null;
}
public static void handlerunninginstance(process instance)
{
//确保窗口没有被最小化或最大化
showwindowasync (instance.mainwindowhandle , ws_shownormal);
//设置真实例程为foreground window
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);
}
}
3、 加载完毕正式运行后的类:
public void preload()
{
// 如果已经加载毕,则返回
if (_loaded)
return;
// 把机器生成的代码放到这里
initcustomcontrol();
_loaded = true;
}
// 是否加载完毕
private bool _loaded = false;
protected override void onload(eventargs e)
{
// 确保 preload()函数已经调用
if (!_loaded)
throw new invalidoperationexception("must call preload before calling this function.");
}