如何防止应用程序被多次运行
我希望程序只被实例化一次,如果用户第二次运行该程序,则将第一个实例提到最前面。在16位windows下问题不大,但32位下如何实现?
我知道这个问题设计到特定的Windows API,可能比较难。
问题点数:50、回复次数:13Top
1 楼netlib(河外孤星)回复于 2002-07-05 11:05:32 得分 2
你在程序起运行时
用findwindow找自己的主窗口,如果找到,发送消息给它,把它显示出来,
并把自己关闭。Top
2 楼cg1120(代码最优化-§惟坚韧者始能遂其志§)回复于 2002-07-05 11:07:26 得分 5
防止一个程序执行两次
implementation
var hnd: THandle;
initialization
hnd := CreateMutex(nil, True, 'irgendwaseinmaliges');
if GetLastError = ERROR_ALREADY_EXISTS then Halt;
finalization
if hnd <> 0 then CloseHandle(hnd);
end.Top
3 楼universe(孤帆)回复于 2002-07-05 11:20:46 得分 2
好像运行一个比较简单,要把它显示在最顶层比较困难,我以前试过findwindow一般情况下可以,但是对于自己的程序有多个窗口的情况下,比较麻烦,比如有showmodal的窗口,做不好这个窗口就埋在自己的主窗口下了,没法操作Top
4 楼luoweicaisd(笑三少)回复于 2002-07-05 11:20:53 得分 10
实现单实例运行的关键是判断前一实例是否存在,Win3.x中运行的程序能获知前一
实例的句柄,从而可以方便地进行判断,但 Windows 95 是抢先式多任务系统,其程序
的前一实例句柄恒为零,所以只有另寻其他办法。目前最有效的办法是通过查看是否有
相同窗口类名的例程存在来进行判断。下面介绍在Delphi中实现的方法。
1、对主窗口程序的改动:
在主窗口(即程序创建的第一个窗口)中interface节加入
const
CM_RESTORE = WM_USER + $1000; {自定义的“恢复”消息}
MYAPPNAME = "My Delphi Program";
并在Form的定义的public节中加入
procedure CreateParams(var Params: TCreateParams); override;
Procedure RestoreRequest(var message: TMessage); message CM_RESTORE;
在implementation节中加入
{指定窗口名称}
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.WinClassName := MYAPPNAME;
end;
{处理“恢复”消息}
procedure TForm1.RestoreRequest(var message: TMessage);
begin
if IsIconic(Application.Handle) = TRUE then
Application.Restore
else
Application.BringToFront;
end;
经过以上修改,程序的主窗口的类名已经被指定了,这是进行判断的基础。
一般在程序刚开始运行的时候进行判断,所以还要对DPR文件进行修改。
Top
5 楼wyb716(小刀)回复于 2002-07-05 11:27:24 得分 5
var hMutex: THandle;
hMutex := CreateMutex(nil, True, 'demomutex');
if hMutex <>0 then
if GetLastError = ERROR_ALREADY_EXISTS then
Halt;
end.
Top
6 楼butwhy(菜菜鸟)回复于 2002-07-05 11:35:39 得分 0
好像还不行。请说明在哪段程序中使用,以及原理。谢谢!Top
7 楼toto2wang(哎诤)回复于 2002-07-05 11:39:06 得分 5
在工程文件中使用如下:
CreateMutex(nil, true, 'Application name');
if GetLastError <> ERROR_ALREADY_EXISTS then
begin
Application.Initialize;
Application.CreateForm(TMainForm, MainForm);
Application.Run;
end;Top
8 楼butwhy(菜菜鸟)回复于 2002-07-05 11:42:07 得分 0
好像方法还挺多的,明天结贴,大家再发挥,分不够再加。
绝对不敢得罪高手。Top
9 楼IUPRG(给我点一首周截棍的“双杰伦”)回复于 2002-07-05 12:23:28 得分 10
我的处理办法:
program aj;
uses
Forms,
windows,
dialogs,
sysutils,
FZXYR in 'FZXYR.pas' {Afzsyr},
main in 'main.pas' {AMAIN},
dt_module in 'dt_module.pas' {DtMd: TDataModule},
PIC in 'PIC.pas' {APIC},
aSHR in 'aSHR.pas' {fSHR},
aj_main in 'aj_main.pas' {ajMAIN},
pwd in 'pwd.pas' {password},
aj_query in 'aj_query.pas' {aj_qry},
dt_comps in 'dt_comps.pas' {aj_compress},
pwd_chg in 'pwd_chg.pas' {pwd_change},
aj_del in 'aj_del.pas' {AJ_DELETE},
aj_init in 'aj_init.pas' {init},
aj_cfg in 'aj_cfg.pas' {config},
aj_dic in 'aj_dic.pas' {dic},
rpt_shr in 'rpt_shr.pas' {frm_rpt_shr},
rpt_aj in 'rpt_aj.pas' {frm_rpt_aj},
rpt_fzxyr1 in 'rpt_fzxyr1.pas' {frm_rpt_fzxyr1},
rpt_fzxyr in 'rpt_fzxyr.pas' {frm_rpt_fzxyr};
{$R *.RES}
Var
hMutex:HWND;
Ret:Integer;
begin
Application.Initialize;
Application.Title := 'xxx管理系统;
hMutex:=CreateMutex(nil,False,'xxx管理系统');
Ret:=GetLastError;
If Ret<>ERROR_ALREADY_EXISTS Then
Begin
Application.CreateForm(TajMAIN, ajMAIN);
Application.CreateForm(TAMAIN, AMAIN);
Application.CreateForm(TAfzsyr, Afzsyr);
Application.CreateForm(TDtMd, DtMd);
Application.CreateForm(TAPIC, APIC);
Application.CreateForm(TfSHR, fSHR);
Application.CreateForm(Taj_qry, aj_qry);
Application.CreateForm(Taj_compress, aj_compress);
Application.CreateForm(Tpwd_change, pwd_change);
Application.CreateForm(TAJ_DELETE, AJ_DELETE);
Application.CreateForm(Tinit, init);
Application.CreateForm(Tconfig, config);
Application.CreateForm(Tdic, dic);
Application.CreateForm(Tfrm_rpt_shr, frm_rpt_shr);
Application.CreateForm(Tfrm_rpt_aj, frm_rpt_aj);
Application.CreateForm(Tfrm_rpt_fzxyr1, frm_rpt_fzxyr1);
Application.CreateForm(Tfrm_rpt_fzxyr, frm_rpt_fzxyr);
Application.CreateForm(Tpassword, password);
Application.Run;
End
Else
Application.MessageBox('已经运行!','注意!',MB_OK);
ReleaseMutex(hMutex);
end.
Top
10 楼cpls(温柔菜刀)回复于 2002-07-05 13:16:36 得分 10
const
C_STR_GLOBAL_ID='XXXXXXXX管理';
var
glbAtom:ATOM;
begin
Application.Initialize;
if 0=GlobalFindAtom(C_STR_GLOBAL_ID) then //******
begin
glbAtom:=GlobalAddAtom(C_STR_GLOBAL_ID);//*********
Application.CreateForm(TfrmMain, frmMain);
Application.Run;
GlobalDeleteAtom(glbAtom);//*********
end
else
begin
MessageDlg(#13+'系统已经运行',mtInformation,[mbOK],0);
end;
end.
Top
11 楼cpls(温柔菜刀)回复于 2002-07-05 13:18:12 得分 1
注意,是在你的工程文件中修改Top
12 楼butwhy(菜菜鸟)回复于 2002-07-07 13:46:04 得分 0
方法真多,高手真多
给分了,谢谢大家!Top




