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

时间:2011-03-24 07:32:20

标签: windows-services inno-setup

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

我使用了以下代码

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

我不确定这是否正确

(我添加了提醒重启的代码,但我想知道是否可以在没有重启pc的情况下立即运行服务。)

[Setup]
AlwaysRestart=yes

欢迎任何评论。

3 个答案:

答案 0 :(得分:12)

  1. 使用sc.exe,这很简单,唯一的缺点就是你可能需要拦截和解析输出才能知道出了什么问题,如果有的话。
  2. 使用我的Inno设置service library。它是SCM API上的Pascal脚本包装器,让您可以完全控制服务。使用起来有点复杂,但它允许完整的错误检查和处理。有一些更高级别的功能用于在标准的可抑制Inno设置对话框中显示错误。
  3. PS:不要在任何Windows系统文件夹中安装您的服务。它们应被视为Windows私人文件夹。除非你有非常好的理由在那里写(即驱动程序),否则你永远不应该在那里安装软件。将其安装在您的应用程序文件夹中。

答案 1 :(得分:2)

除了接受的答案之外,我还想让人们更容易使用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;

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

不幸的是我无法弄清楚是否有办法在[Code]部分中使用{# VarName} emit语法,这就是为什么我将服务名称等声明为常量以及 #define位于文件顶部。答案here非常有用如果您想要的常量是[设置]部分的设置之一,但是因为您无法随意添加内容到此部分对于你可能想要为其定义常数的所有事情都不起作用。

如果您要为服务设置说明,那么服务库不支持该服务,但使用 [注册表] 部分可以轻松完成例如:

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

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

答案 2 :(得分:1)

使用Service Functions来自Silvio Iaccarino的Inno Setup