如何禁止程序的二次运行?(50分)

  • 主题发起人 主题发起人 johnnywong
  • 开始时间 开始时间
J

johnnywong

Unregistered / Unconfirmed
GUEST, unregistred user!
如何禁止程序的二次运行?
 
用互斥对象。
例子:
program Project1;

uses
Forms,
Windows,
Unit1 in 'Unit1.pas' {Form1};

{$R *.RES}

begin
if OpenMutex(MUTEX_ALL_ACCESS,True,'Projectabc')>0 then
begin
MessageBox(0,'程序已经在运行','错误',MB_OK);
end
else
begin
CreateMutex(nil,True,'Projectabc');
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
CloseHandle(OpenMutex(MUTEX_ALL_ACCESS,True,'Projectabc'));
end;
end.
 
写注册表,或者写个文件标志,都可以啊
 
互斥类或FINDWINDOW函数
 
我记得在陈宽达在delphi深度历险中有很详细的讨论,即使你使用的是FindWindow也是会出现
错误的,除了FindWindos还有一个方法就是判断project的title,你可以到我的主页看看我有
一个程序在上面,地址是yysq。126.com
 
if findwindow() then
application.Terminate;
 
program DTLY;

uses
Forms,
Windows,
SysUtils,
Dialogs,
inifiles,
shellapi,
DTluyin in 'DTluyin.pas' {LYMain},
LYThread in 'LYThread.pas',
AdvHint in 'advhint.pas',
LYprocess in 'LYprocess.pas',
......
{$R *.RES}

var
Handle: Integer;
Dummy: integer;
begin
handle := findwindow('TLYMain',nil);// 解决程序重入问题
if handle <> 0 then halt; //当然是善后工作了,搞定 Application.Initialize;
........
Application.Run;
end.
 
var
h: HWND;
begin
h := FindWindowEx(0, 0, 'TApplication', 'YourApplicationName');
if h <> 0 then Application.Terminate;
end;
 
[blue]var
h: HWND;
begin
h := FindWindowEx(0, 0, 'TApplication', 'YourApplicationName');
if h <> 0 then Application.Terminate;
end;[/blue]
 
另类解答——
在你的主form加如下语句:
var
hwnd:integer;
initialization
hwnd := CreateMutex(nil, True, '程序已运行');
if GetLastError = ERROR_ALREADY_EXISTS then
begin
showmessage('程序已运行');
Halt;
end;

finalization
if hwnd <> 0 then CloseHandle(hwnd);
 
[green]用API findwindow就如上各位所说的,可以防止程序二次运行,但是
如果想做得专业一点如(winmap) 不是显示一条‘你的程序已经运行’之类
的东东,而是让程序从任务条上自动跳出,应该怎么作呢,我用过showwindow
效果并不理想[/green]
 
我也像咪咪富翁想知道那個如何做!!
 
program Project1;//Project file

uses
Forms, Windows,
Unit1 in 'Unit1.pas' {Form1};
{$R *.RES}

begin
CreateMutex(nil, false, 'MyApp');
if GetLastError = ERROR_ALREADY_EXISTS then //if it failed then there is another instance
begin
SendMessage(HWND_BROADCAST,RegisterWindowMessage('MyApp'),0,0);
Halt(0);//Lets quit
end;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
 
以前都讨论过
二次运行,前次的跳出:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=550421
 
program Measure;

uses
Forms,
windows,
UnitStart in 'UnitStart.pas' {frmStart},
Unitmain in 'Unitmain.pas' {frmMain},
PComm in 'Pcomm.pas',
UnitData in 'UnitData.pas' {frmData},
UnitAbout in 'UnitAbout.pas' {frmAbout},
UnitWave in 'UnitWave.pas' {frmWave};

Var
HMeasure:HWND;
HRet:Integer;
{$R *.res}

begin
Application.Initialize;
frmStart:=TfrmStart.Create(Application);
frmStart.Show;
frmStart.Refresh;
sleep(2000);
Application.Title := '数据自动采集系统';
HMeasure:=CreateMutex(Nil,False,'数据自动采集系统');//防止程序重复运行
HRet:=GetLastError;
If HRet<>ERROR_ALREADY_EXISTS Then
Begin
Application.CreateForm(TfrmMain, frmMain);
Application.CreateForm(TfrmData, frmData);
frmStart.Close;
Application.Run;
End
Else
Begin
Application.MessageBox('警告:你执行的程序已经运行!'+#13+#13'系统将关闭此程序!','关闭程序',MB_OK);
ReleaseMutex(HMeasure);
end;
end.
 
最简单的办法
const
classname='TDMTForm'; //此处定义你的主窗体的名称
var
handle : integer;
begin
handle:=Findwindow(classname,nil); {查找是否有此类的窗体}
if handle<>0
then begin {不为0则程序已运行}
SetForegroundWindow(handle); //激活已经运行的程序
Halt; {退出程序}
end;
Application.Initialize; //为0 则正常执行程序
 
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
 
楼上说的大体都对.
注意包含Windows单元.
采用判读窗体类的Caption名称时,最好是在最后编译时加上.否则只要在delphi中打开的程序存在该窗体类,你的exe便
认为程序已经运行!
 
各位大侠不知是否试过在SDI下弹出一个Form,在Form里再ShowMessage,然后马上
去执行其它的程序,然后再去资源管理器中去双击你的程序看看效果如何

我认为这些只能用在MDI的程序中
 
有专门的控件使用TJUSTONE(www.vclxx.org),什么都不要管,
 
后退
顶部