代码之家  ›  专栏  ›  技术社区  ›  Scott W

是否可以安装同一delphi服务应用程序的多个实例?

  •  8
  • Scott W  · 技术社区  · 17 年前

    我有一个在Delphi中构建的服务应用程序,效果非常好。它做的正是我想要它做的,一切都很快乐。在我想在一台机器上运行该服务的两个(或更多)实例之前,一切都很好。由于服务名称是硬编码到程序中的(通过服务的name属性),因此我只能在任何给定的计算机上安装一次服务。如果我试图在运行时修改Name属性,则除非Name属性设置为与设计时设置的相同的内容,否则服务不会响应。

    在我看来,这种方法是丑陋的,而且肯定是低效的。在两种情况下都可以,但是我们需要第三种和第四种,并且。。。

    是否有任何方法可以修改我的代码,使我只有一个Delphi项目,可以通过一些简单的运行时输入(例如,命令行标志)将自己作为多个服务实例安装和运行?

    5 回复  |  直到 17 年前
        1
  •  16
  •   Gerry Coll    17 年前

    您还没有明确说明您试图在TService子类中更改什么。

    比如:

    procedure TServiceMain.ServiceLoadInfo(Sender : TObject);// new method, not an override
    begin
      Name := ParamStr(2);
      DisplayName := ParamStr(3);
    end;
    
    procedure TServiceMain.ServiceBeforeInstall(Sender: TService);
    begin
      ServiceLoadInfo(Self);
    end;
    procedure TServiceMain.ServiceCreate(Sender: TObject);
    begin
      ServiceLoadInfo(Self);
    end;
    

    C:\>servicename /install MyService "My Service Description"
    
        2
  •  3
  •   Ken White    17 年前

    您可以在内部创建具有多个线程的服务,每个线程的行为都像它自己的服务版本/副本。您可以使用服务控制器API IIRC来控制它。

        3
  •  2
  •   Tim Jarvis    17 年前

    是的,可以安装同一服务的多个实例,您只需在安装时(而不是运行时)动态更改名称,但这并不意味着需要更改名称。(代码项目中有一些示例代码 http://www.codeproject.com/KB/dotnet/MultipleInstNetWinService.aspx )

        4
  •  1
  •   cja    16 年前

    上述公认的答案非常有用。

    我使用的代码:

    procedure TService1.ServiceAfterInstall(Sender: TService);
    begin
    //http://stackoverflow.com/questions/612587/is-it-possible-to-install-multiple-instances-of-the-same-delphi-service-applicati
    //http://www.c-sharpcorner.com/UploadFile/timosten/DynamicServiceInCSharp11262005062503AM/DynamicServiceInCSharp.aspx?ArticleID=4d5020e4-7317-425c-ab29-5bf37a1db421
    //http://support.microsoft.com/kb/137890
      SaveRegSetting('\SYSTEM\CurrentControlSet\Services\' + Name, 'ImagePath', ParamStr(0) + ' --name=' + Name, HKEY_LOCAL_MACHINE)
    end;
    
    procedure TService1.ServiceCreate(Sender: TObject);
    begin
      Name := Trim(FCommandLineOptions.Values['name']);
      DisplayName := Name;
    end;
    

    SaveRegSetting是我自己的过程,FCommandLineOptions是一个标记命令行参数的对象。

        5
  •  0
  •   Chapel    17 年前

    将所有代码包装到从TThread继承的类中。

    当您的服务启动时,它将从设置文件或注册表中读取一个数字,并创建大量的类实例。

    要更改正在运行的实例数,可以关闭服务,编辑设置(在文件或注册表中)并重新启动服务。

        6
  •  0
  •   Tim McKay    6 年前

    除了入侵注册表,我建议使用以下指南并使用Windows服务控制器(sc.exe)命令行界面:

    When creating a service with sc.exe how to pass in context parameters?

    (编辑:请使用建议的代码获取名称和显示名称属性,但不要使用服务可执行文件的/install开关安装服务。)

    推荐文章