使用Inno Setup在Windows(Vista/XP/7)上安装服务

mon*_*bre 4 windows-services inno-setup

我需要在安装应用程序时安装并运行服务(使用Inno Setup创建installer.exe)

我使用下面的代码

[Run]
Filename:"{sys}\myservice.exe "; Parameters: "-install"
Run Code Online (Sandbox Code Playgroud)

我不确定这是否正确

(我添加代码以提醒重启但我想知道是否可以在安装后立即运行服务而无需重启pc.)

[Setup]
AlwaysRestart=yes
Run Code Online (Sandbox Code Playgroud)

欢迎任何评论.

小智 12

  1. 使用sc.exe,这很简单,唯一的缺点就是你可能需要拦截和解析输出才能知道出了什么问题,如果有的话.
  2. 使用我的Inno Setup 服务库.它是SCM API上的Pascal脚本包装器,让您可以完全控制服务.使用起来有点复杂,但它允许完整的错误检查和处理.有一些更高级别的功能用于在标准的可抑制Inno设置对话框中显示错误.

PS:不要在任何Windows系统文件夹中安装您的服务.它们应被视为Windows私人文件夹.除非你有非常好的理由在那里写(即驱动程序),否则你永远不应该在那里安装软件.将其安装在应用程序文件夹中.


bsz*_*zom 5

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

[Code]
// source: /sf/answers/379172111/ 
#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;
Run Code Online (Sandbox Code Playgroud)

这不是防弹的,但应该可以很好地处理绝大多数情况。

不幸的是,我无法弄清楚是否有一种方法可以{# VarName}在 [Code] 部分使用发出语法,这就是为什么我将服务名称等声明为常量,以及 #define文件顶部的 's 。如果您想要的常量是 [Setup] 部分的设置之一,则此处的答案很有用,但由于您不能随意向该部分添加内容,因此这不适用于您可能想要为其定义常量的所有内容。

如果你想为你的服务设置一个描述,那么服务库不支持,但使用[Registry]部分很容易,例如:

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

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