如何防止一个程序运行两次?
第二次再次运行程序则提示已运行?

解决方案 »

  1.   

    防止程序重复运行 
    将下面的代码放到工程文件中
    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掉,从而达到只能运行一次的目的
     
      

  2.   

    简单点的:
    const classname='Tmainform'; {声明为主窗体的类名}
    var handle:integer;
    begin
      handle:=findwindow(classname,nil);{查找是否有此类的窗体}
    if handle<>0 then {不为0则程序已运行}
    begin
    messagebox(0,'系统已经在运行中!','提示',0);{提示程序已运行}
    halt; {退出程序}
      

  3.   

    Function CheckReEnter:Boolean ;//避免重复启动
    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;
      

  4.   

    将以下代码放在你的project文件(*.dpr)中,在程序启动时检查:var
      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中关闭,否则程序运行时会认为该程序已经运行。
      

  5.   

    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;还有一个方法在《Delphi5开发人员指南》书里,此方法比较好
      

  6.   

    用 Drate(鸟窝里的虫) 的方法
      

  7.   

    推荐用
    Drate(鸟窝里的虫) 这种查找共享内存的方法比查找窗口名字要严谨
    如果查找窗口名字很明显如果有同名窗口,你的程序就挂了
      

  8.   

    to Drate(鸟窝里的虫)
    我是初学者,请问'能代表程序特点的字符串'是什么意思? 谢谢!
      

  9.   

    Windows95的程序一般都可以重复执行,例如你按下WIN+E组合键即启动资源管理器,如果再按WIN+E组合键又会出现一个资源管理器,这两个程序互不干扰。有时候你可以需要制作这样一个程序:当该程序已经执行时,若用户企图再次执行该程序则只会激活那个已执行的程序,而不是又出现一个副本。
      完成这个目的的核心就是要在程序启动时查找该程序是否已经运行,我曾试过很多种方法,包括向“全局元素表”(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;