2011-03-24 100 views
4

我需要安装和运行一个服务安装应用程序时(使用Inno Setup的创建Installer.exe的)在Windows上安装服务(VISTA/XP/7)使用Inno Setup的

我用下面

[Run] 
Filename:"{sys}\myservice.exe "; Parameters: "-install" 

我不知道这是否是正确的

(我添加代码,以提示重新启动,但我不知道是否有可能无需重新启动电脑在安装后立即运行服务。)

[Setup] 
AlwaysRestart=yes 

欢迎发表评论。

+1

服务可以在安装后立即运行,我一直这样做。尽管如果安装程序必须替换正在使用的文件,可能需要重新引导。 – 2011-03-24 07:46:22

+0

如果我记得,安装服务的建议不是使用服务的自行安装,而是直接从安装程序写入所有注册表项。 – 2011-03-24 07:55:22

+0

AFAIK您应该使用SCM(服务控制管理器)API来安装服务,而不是访问注册表。 – 2011-03-24 08:48:07

回答

11
  1. 使用SC.exe,这很简单,唯一的缺点是,你可能要拦截并解析输出到知道自己错在哪里,如果它没有。
  2. 使用我的Inno Setup service library。它是SCM API的Pascal脚本封装器,可让您完全控制服务。使用起来稍微复杂一点,但它允许进行全面的错误检查和处理。有一些更高级别的功能可以在标准的可压缩Inno Setup对话框中显示错误。

PS:不要将您的服务安装在任何Windows系统文件夹中。他们应该被视为Windows私人文件夹。除非你有非常充分的理由(例如驱动程序),否则你不应该在那里安装软件。将它安装在应用程序文件夹中。

+0

+1不错的图书馆,我会用这:)取代我的本土功能服务:) – jachguate 2011-03-24 15:03:31

+0

+1真棒图书馆(不只是很好)。到目前为止,在Unicode版本中没有发现任何问题。 – 2014-01-27 22:54:14

1

使用Service Functions的Inno Setup的从西尔维奥Iaccarino

+1

但是,如果您使用的是Unicode版本的Inno Setup,请小心,否则这些脚本将无法使用。查看@ldsandon的答案 - 并记下他的“服务库”页面底部的链接。 – shunty 2011-03-24 09:02:11

1

除了接受的答案,我只想让人们更容易使用Luigi Sandon的服务库(非常感谢!)。下载脚本后,您就需要添加一个[代码]类似于以下到你的安装脚本部分:

[Code] 
// source: https://stackoverflow.com/a/5416744 
#include "services_unicode.iss" 

const 
    SERVICE_NAME = 'MyService'; 
    SERVICE_DISPLAY_NAME = 'MyService'; 
    SERVICE_EXE = 'MyService.exe'; 

procedure CurStepChanged(CurStep: TSetupStep); 
begin 
    Log('CurStepChanged(' + IntToStr(Ord(CurStep)) + ') called'); 

    if CurStep = ssInstall then begin 
    if ServiceExists(SERVICE_NAME) then begin 
     if SimpleQueryService(SERVICE_NAME) = SERVICE_RUNNING then begin 
     SimpleStopService(SERVICE_NAME, True, False); 
     end; 
     SimpleDeleteService(SERVICE_NAME); 
    end; 
    end 
    else if CurStep = ssPostInstall then begin 
    SimpleCreateService(SERVICE_NAME, SERVICE_DISPLAY_NAME, ExpandConstant('{app}\' + SERVICE_EXE), SERVICE_AUTO_START, '', '', False, False); 
    SimpleStartService(SERVICE_NAME, True, False); 
    end; 
end; 

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); 
begin 
    Log('CurUninstallStepChanged(' + IntToStr(Ord(CurUninstallStep)) + ') called'); 

    if CurUninstallStep = usUninstall then begin 
    if ServiceExists(SERVICE_NAME) then begin 
     if SimpleQueryService(SERVICE_NAME) = SERVICE_RUNNING then begin 
     SimpleStopService(SERVICE_NAME, True, False); 
     end; 
     SimpleDeleteService(SERVICE_NAME); 
    end; 
    end; 
end; 

这不是防弹的,但应该处理绝大多数情况下就好了。

不幸的是我无法弄清楚是否有使用{# VarName}发出的[代码]部分的语法,这就是为什么我宣布服务名称等作为常量有以及#define的一种方式在文件的顶部。答案here很有用如果你想要的常数是[Setup]部分的设置之一,但是因为你不能随意添加东西到这个部分,所以你不想为所有的东西定义常量。

如果您想为您服务的描述,则服务库不支持,但是这是很容易使用[注册]部分做的,例如:

[Registry] 
; set the service description 
Root: HKLM; Subkey: "System\CurrentControlSet\Services\{#ServiceName}"; ValueType: string; ValueName: "Description"; ValueData: "{#ServiceDescription}"; Flags: deletevalue uninsdeletekey 

最后,我可以确认这也适用于Windows 10。