Hold := Application.Title;
  Application.Title := 开发系统'
     + IntToStr(HInstance); // 暂时修改窗口标题
  StrPCopy(ZAppName, Hold); // 原窗口标题
  Found := FindWindow(nil, ZAppName); // 查找窗口
  Application.Title := Hold; // 恢复窗口标题
  ShowMessage(IntToStr(Found));
  if Found>3 then begin
    // 若找到则激活已运行的程序并结束自身
    //ShowWindow(Found, SW_RESTORE);
    Application.MessageBox('程序已经启动,请不要重复运行!','集团',MB_OK+MB_ICONERROR);
    Application.Terminate;
    Close;
  end;上面代码可能限制程序只运行一次,但如何限制程序最多只能运行三次啊??

解决方案 »

  1.   

    如果就一个EXE文件的话,几乎不可能做到。
      

  2.   

    如果不通过写文件或注册表的方式可以不??
    另外可能只能通过写方便方式比较好。因为程序在一台服务器上,有很多用户连接到那服务器运行。。所以如果要读写文件的方式控制,如何读取当前用的TEMP目录?肯定要把文件写到每个用户的目录中,这样才不会冲突?
      

  3.   

    hMutex := CreateMutex(nil, False, '...');
    if GetLastError = ERROR_ALREADY_EXISTS then Exit;
    ...
    CloseHandle(hMutex);
      

  4.   

    获取TEMP目录用GetTempPath(用法看MSDN)也可以沿用你原来的方法,在程序标题上做文章,就是把计数写在标题里,"AppName_X",在标题最后记一个数字,下一个程序启动时检查这些窗口的标题(当然可能不只一个),把"X"位取出来,找到最大的数,看是否达到上限,如果达到则禁止启动,如果没有就允许启动,并X+1计数......
      

  5.   

    createmutex(nil,   false,   'aaaaa');//'aaaaa'可以为 任意字符
        if   getlasterror   =   error_already_exists   then
          begin
                //Application.MessageBox('软件已启动,如需要重新打开,'+char(13)+char(13)+'请先关闭先前打开的相应软件!'
               // ,'提示',MB_ICONINFORMATION+MB_OK);
              //已运行
                Exit;
          end   ;
      

  6.   

    在你工程文件.dpr中修改,如下
    program Project1;uses
      Windows,
      Forms,
      Unit1 in 'Unit1.pas' {Form1};{$R *.res}begin
        createmutex(nil,   false,   'aaaaa');//任意字符
        if   getlasterror   =   error_already_exists   then
          begin
                //Application.MessageBox('软件已启动,如需要重新打开,'+char(13)+char(13)+'请先关闭先前打开的相应软件!'
               // ,'提示',MB_ICONINFORMATION+MB_OK);
              //已运行
                Exit;
          end   ;
      Application.ShowMainForm := false ;
      Application.Initialize;
      Application.CreateForm(TForm1, Form1);
      Application.Run;
    end.
      

  7.   

    不可完成的任务mission impossible
      

  8.   

    不会吧 不可能完成的任务? JPEXE 的想法我也想过,估计不写文件可能只能通过这个方法来实现了。。有没哪个大哥告诉我取得当前用户临时目录的方法呀??如果上面方面实现不了就考虑用写文件方式了
      

  9.   

    以下函数能够获取到当前用户的桌面目录,即"X:\Documents and Settings\<user name>\Desktop\",
    至于当前用户的临时目录则是"X:\Documents and Settings\<user name>\Local Settings\Temp\",
    只需再做一个简单的字符串处理,把"\Desktop\"替换成"\Local Settings\Temp\"就行,自己搞定吧.uses
      ShlObj;function GetUserDesktopDir: string;
    var
      PIIDL: PItemIDList;
      pszPath: PChar;
    begin
      if Succeeded(SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, PIIDL)) then begin
        pszPath := StrAlloc(MAX_PATH);
        SHGetPathFromIDList(PIIDL, pszPath);
        Result := StrPas(pszPath);
        StrDispose(pszPath);
      end else
        Result := '';
    end;
      

  10.   

    稍微会点逆向的人都可以搞定这种限制
    另外,就算不会逆向,ghost还原裸系统以后,你的软件可以继续使用……现在楼猪感觉限制使用次数还有意思吗?
      

  11.   

    上面一大堆, 只有 
    begin
        createmutex(nil,  false,  'aaaaa');//任意字符
        if  getlasterror  =  error_already_exists  then
          begin
                //Application.MessageBox('软件已启动,如需要重新打开,'+char(13)+char(13)+'请先关闭先前打开的相应软件!'
              // ,'提示',MB_ICONINFORMATION+MB_OK);
              //已运行
                Exit;
          end  ;
      Application.ShowMainForm := false ;
      Application.Initialize;
      Application.CreateForm(TForm1, Form1);
      Application.Run;
    end.这个是接近的, 用 Mutex 只能实现开一个, 但 Semphore 可以实现多个, 所以, 这里改一下var
      HSEM: THandle;
    begin
      // 建立一个信号量, 初始为 3 个, 最大为 3 个
      HSEM := CreateSemphore(nil, 3, 3, Application.Title{任意标识});
      // 已存在就尝试打开信号量
      if HSEM = 0 then
        OpenSemphore(SEMAPHORE_ALL_ACCESS, false, Application.Title{上面用于CreateSemphore的标识});  // WaitFor 如果成功, 信号量就减 1, 返回 WAIT_OBJECT_0
      // 不成功就会进入阻塞状态到集号量被释放, 这里不想等, 所以 TIMEOUT 设 1ms, 超时说明信号用完
      if WaitForSingleObject(HSEM, 1) = WAIT_TIMEOUT then
        Halt;  Application.ShowMainForm := false ;
      Application.Initialize;
      Application.CreateForm(TForm1, Form1);
      Application.Run;  // 释放一个信号量, 这样始终都是可以开 3 个程序
      ReleaseSemphore(HSEM);
      CloseHandle(HSEM);
    end.
      

  12.   

    上面有点错, 下面是测试代码 copy 过来的use 部分加上 Windows;var
      HSEM: THandle;
    const
      // 这里比较郁闷, delphi 没定义这个常量
      SEMAPHORE_ALL_ACCESS = $1F0003;
      AppId = 'test';begin
      HSEM := CreateSemaphore(nil, 3, 3, Pchar(AppId));
      if HSEM = 0 then
        HSEM := OpenSemaphore(SEMAPHORE_ALL_ACCESS, false, Pchar(AppId));  if WaitForSingleObject(HSEM, 1) = WAIT_TIMEOUT then
        Exit;  Application.Initialize;
      Application.CreateForm(TForm1, Form1);
      Application.Run;  ReleaseSemaphore(HSEM, 1, nil);
      CloseHandle(HSEM);
    end.
      

  13.   

    另外取得 windows 临时目录的主法有很多, 
    GetEnvironmentVariable 取得环境变量是最简单的NAME 指明为 'TEMP'
      

  14.   

    信号量方式不行的
    同一个程序我启动三次,顺序分别是A、B、C,然后我关闭A,然后就又可以启动三次了,那就可能有B、C、D、E、F五个程序运行了。
      

  15.   


    program Project1;uses
      Forms,
      windows,
      Unit1 in 'Unit1.pas' {Form1};const
      myatom1='myatom1';
      myatom2='myatom2';
      myatom3='myatom3';{$R *.res}begin
      if globalfindatom(myatom1)=0 then
      begin
        globaladdatom(myatom1);
        Application.Initialize;
        Application.CreateForm(TForm1, Form1);
        Application.Run;
        globaldeleteatom(globalfindatom(myatom1));
      end
      else
      begin
        if globalfindatom(myatom2)=0 then
        begin
          globaladdatom(myatom2);
          Application.Initialize;
          Application.CreateForm(TForm1, Form1);
          Application.Run;
          globaldeleteatom(globalfindatom(myatom2));
        end
        else
          if globalfindatom(myatom3)=0 then
          begin
            globaladdatom(myatom3);
            Application.Initialize;
            Application.CreateForm(TForm1, Form1);
            Application.Run;
            globaldeleteatom(globalfindatom(myatom3));
          end
      end;
    end.
      

  16.   

    楼主的表述有问题呀,这哪里是限制程序运行次数呀!你是希望一个EXE不能有多于3个实例同时运行.
      

  17.   

    InHandle := CreateSemaphore(nil, 3, 3, PChar('program'));
      iRun := WaitForSingleObject(InstanceHandle, 0);  if iRun <> 0 then
      begin
          TMsgBox.Warning('您已经运行了 ' + IntToStr(3) + '个实例,没有剩余的实例可以运行!');
        Application.Terminate;
          end;
      

  18.   

    谢谢 comanche 这方法可以解决。。另外我想问啊 通过DELPHI 如何控制其他程序只运行三次?就是说A程序,是要通过DELPHI去运行的
    先运行DELPHI程序然后有个按钮运行A 程序,如何去控制A程序只运行三次??就是说进入A程序的方法就只能先运行我做的DELPHI程序,如何做到?
      

  19.   

    A程序的写法,
    先检查你的程序是否运行,不运行推出var
      hwnd:Thandle;
    begin
      hwnd:=findwindow(nil,'你的窗口标题');
      if hwnd<>0 then
      begin
        Application.Initialize;
        Application.CreateForm(TForm1, Form1);
        Application.Run;
      end;
    end;
      

  20.   


    比如我的A程序就是WINDOWS的计算器,通过我编的DELPHI按钮点的只能运行三次
    如何控制?另外 假设计算器窗体名会改变该如何操作
      

  21.   

    借助注册表或者其他ini dat等外部文件才能实现