我有一个程序A,用信号量控制只能启动一次,平时双击打开确实只能启动一次。我写了一个服务程序,在服务里启动程序A,然后再双击程序A,竟然能打开第二个。请问是什么原因?谢谢!

解决方案 »

  1.   

    本帖最后由 bdmh 于 2012-06-06 09:42:59 编辑
      

  2.   

    楼主可以在工程中加入如下“红色代码”即可program Project1;uses
      Windows, Forms,
      Unit1 in 'Unit1.pas' {Form1};{$R *.RES}begin
      Application.Initialize;  Application.Title:='我的测试程序';
      CreateMutex(nil,False,'我的测试程序');
        if   (GetLastError()=ERROR_ALREADY_EXISTS)  then
         begin
           Application.MessageBox(PChar('当前程序只能且只有一个实例运行'), '错误信息:', MB_ICONERROR);
           exit;
         end;

      Application.CreateForm(TForm1, Form1);
      Application.Run;
    end.
      

  3.   

    Application.Title
    的标题信息,可能修改成你想要“信息”
    不过
    CreateMutex(nil,False,'信息');
    必须与上样一致的
      

  4.   

    to bdmh:
    是这样吗?可结果还是一样,OpenNum返回的是0
    const
      NameMutex = 'Global\\SingleApp';  OpenNum := OpenMutex(MUTEX_ALL_ACCESS, False, NameMutex);
    to sgzhou12345:
    这个方法不行,如果只双击打开应该是没问题,不过先用服务打开,再双击还是能打开的。感谢大家的回复!
    我觉得应该是服务的问题,我用winexec和createprocess方法都试过,都不行!
      

  5.   

    问题出在CreateMutex的第一个参数上。Service的进程的Token是Service的登录帐户的,而你的客户端程序一般是运行在另一个帐户的。Mutex是有自已的访问权限的,也就是有自已的DACL,就象NTFS文件系统的权限设置一样。而你的Service的客户程序没有存取Service产生的Mutex的权限。你必须在Service的CreateMutext的第一个参数上指定这个DACL,呵呵,很麻烦的,你要生成一个指定哪些帐户能访问的DACL,不过指定一个nil   DACL就可以允许Everyone访问,不过这是很不安全的。况且,Service是做为后台程序运行的,用Mutex迫使它阻塞会造成其他Service客户不能访问服务。另外,SCM对每个ControlService请求的响应时间是有要求的
      

  6.   

    to aqtata:A程序只能打开一次,是在A程序中做的互斥。
    服务只是调用winexec或者createprocess方法启动A程序,这样也与CreateMutex的第一个参数有关吗?
      

  7.   


    因为没有源码,不过9楼说的也是有可能的,如果是这样原因,那么解决办法是很简单的:
    h := OpenMutex(READ_CONTROL, FALSE, pansichar('mymutex')); //注意一定要使用READ_CONTROL
    if h <> 0 then
       程序的另外一个示例已经打开了,直接退出
    else
      createMultex(...)