如何防止一个程序运行两次?
第二次再次运行程序则提示已运行?
第二次再次运行程序则提示已运行?
解决方案 »
- 大家有没有RealOA Messenger这个得资料啊
- 请问我怎么知道我在主体窗口中要用到的函数或过程来自哪个类?
- WebBrowser中网页调用js方法时,能不能得到这个方法名?
- 我开发了一个MODEM拨号程序
- 请教大虾们视频的对比度、亮度等参数胡信息保存在哪个结构体里,怎样初始化设置它们??
- 如何不用Delphi的控件进行录音?
- 刚用delphi 假如我不想在程序有错时,跳出来该死的对话框,我要怎么甚至delphi?
- delphi做一个登录的窗体,同时要有登录者的登录记录,本人新手,请大神赐教!
- 有什么变量可以实现MEMO控件的作用?
- Help!!!ODBC驱动有错吗,VFP库中的照片字段始终无法在DBImage里显示
- intraweb是什么?在DELPHI7对应哪些页签的控件?
- 关于节点选择的问题,解决马上给分!!
将下面的代码放到工程文件中
uses windows;
...
var MutexHandle:Thandle;
begin
Mutexhandle:=windows.CreateMutex(nil,true,'能代表程序特点的字符串');
if Mutexhandle<>0 then
begin
if getlasterror=windows.ERROR_ALREADY_EXISTS then
begin
closehandle(Mutexhandle);
halt;
end;
end;Application.Initialize;
Application.CreateForm(Tfmmain, fmmain);
Application.Run;
end.说明:使用了信号灯来进行互斥操作.windows.CreateMutex创建出一个信号量,当同样的信号量被创建的时候,会产生错误:window.ERROR_ALREADY_EXISTS,程序被Halt掉,从而达到只能运行一次的目的
const classname='Tmainform'; {声明为主窗体的类名}
var handle:integer;
begin
handle:=findwindow(classname,nil);{查找是否有此类的窗体}
if handle<>0 then {不为0则程序已运行}
begin
messagebox(0,'系统已经在运行中!','提示',0);{提示程序已运行}
halt; {退出程序}
var
hMap : THandle;
temp:string;
begin
Result := False;
temp:= ExtractFileName(Application.ExeName);
hMap := CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,2,PChar(ExtractFileName(Application.ExeName)));
if ((hMap <> 0) and (GetLastError() = ERROR_ALREADY_EXISTS)) then
begin
CloseHandle(hMap);
hMap := 0;
Result := True;
end;
end;
H: THandle;
... // 查找指定类名的窗体是否存在
H := FindWindow('主窗体的类名', '主窗体的标题');
// 如果存在,则...
if H <> 0 then
// 此处为重新显示该程序,可以换成你希望的行为
SendMessage(H, MM_SHOW, 1, 0)
// 如果不存在,则...
else
begin
// 创建程序其它窗体
Application.CreateForm(TFrmSplash, FrmSplash);
Application.CreateForm(TFrmMain, FrmMain);
...
Application.Run;
end;不过,运行程序时,需将主窗体从Delphi中关闭,否则程序运行时会认为该程序已经运行。
var
ZAppName : array[0..127] of Char;
Hold : String;
Found : HWND;
begin
Hold := Application.Title; 查找窗体的方法
Application.Title :='OnlyOne'+IntToStr(HInstance);暂时修改窗口标题
StrPCopy(ZAppName,Hold); 原窗口标题
Found := FindWindow(nil,ZAppName); 查找窗口
Application.Title := Hold; 恢复窗口标题
if Found <> 0 then 若找到则激活已运行的程序并结束自身
begin
ShowWindow(Found,SW_RESTORE);
Application.Terminate;
end;
end;还有一个方法在《Delphi5开发人员指南》书里,此方法比较好
Drate(鸟窝里的虫) 这种查找共享内存的方法比查找窗口名字要严谨
如果查找窗口名字很明显如果有同名窗口,你的程序就挂了
我是初学者,请问'能代表程序特点的字符串'是什么意思? 谢谢!
完成这个目的的核心就是要在程序启动时查找该程序是否已经运行,我曾试过很多种方法,包括向“全局元素表”(Global ATOM Table)写特定字符串等等,但最简单的方法还是下面这个: 在程序启动时将Application的Title特性字段的值暂时改变。 利用Windows API函数FindWindows()查找窗口
恢复Application的Title值
上述步骤一般在主Form的OnCreate事件中实现,示例如下:procedure TForm1.FormCreate(Sender: TObject);
var
ZAppName: array[0..127] of char;
Hold: String;
Found: HWND;
begin
Hold := Application.Title;
Application.Title := 'OnlyOne'
+ IntToStr(HInstance); // 暂时修改窗口标题
StrPCopy(ZAppName, Hold); // 原窗口标题
Found := FindWindow(nil, ZAppName); // 查找窗口
Application.Title := Hold; // 恢复窗口标题
if Found<>0 then begin
// 若找到则激活已运行的程序并结束自身 ShowWindow(Found, SW_RESTORE);
Application.Terminate;
end;
end;