编译出来的exe,在经过用户多次点击的情况下可以一个程序运行多次,因此也打开了不少exe,然而有可能用户是不知道的。那么请问如何限制本程序只开一次呢?即用户只要双击exe第一次,程序运行后,无论用户再点击多少次都只运行一个这样的程序,直到本程序被退出为止。

解决方案 »

  1.   

    很多种办法,给你个代码比较少的,比较容易理解的。
    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;
      

  2.   

    program Project1;uses
      Forms,
      Windows,
      Unit1 in 'Unit1.pas' {Form1};{$R *.res}
    var
        hMutex:hWnd;
    begin
      Application.Initialize;
      Application.Title:='test';
      hMutex:=CreateMutex(nil,false,'test');
      if GetLastError<>Error_Already_Exists then
      begin
        Application.CreateForm(TForm1, Form1);
        Application.Run;
      end
      else
      begin
        Application.MessageBox('本程序只允许同时运行一个','Error');
        ReleaseMutex(hMutex);
      end;
    end.
      

  3.   

    原理就是这样,在程序启动时,利用某个在系统中已经存在的,并且唯一表示此程序的标志来判断程序是否启动,然后进行操作。除了上面利用FindWindow之外,你还可以在注册表中写上程序启动的标志,然后启动的时候先读取这个标志判断,(当然,这就是一个思路,不一定要这么做,有点舍本逐末),还可以利用原子表。
      

  4.   

    再给你一给利用原子表实现的
    procedure TForm1.FormCreate(Sender: TObject);
    var
      Atom : TAtom;
    begin
    if  GlobalFindAtom('wudi_1982') <> 0 then//在系统原子表中找原子,wudi_1982代表这个程序的标识
    begin
        showmessage('程序已经运行一个实例');
          Application.Terminate;
    end;
    GlobalAddAtom('wudi_1982');//增加原子end;
      

  5.   

    关于上面使用原子表的例子,只是介绍一个概念,如果要用原子表实现,那么上面的代码中少了点,就是在程序结束的时候使用GlobalDeleteAtom删除原子
      

  6.   

    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;這是最經典的方法