Windows services 使用Inno安装程序在Windows(Vista/XP/7)上安装服务
安装应用程序时,我需要安装并运行服务(installer.exe是使用Inno Setup创建的) 我使用下面的代码Windows services 使用Inno安装程序在Windows(Vista/XP/7)上安装服务,windows-services,inno-setup,Windows Services,Inno Setup,安装应用程序时,我需要安装并运行服务(installer.exe是使用Inno Setup创建的) 我使用下面的代码 [Run] Filename:"{sys}\myservice.exe "; Parameters: "-install" 我不确定这是否正确 (我为提醒重新启动添加了代码,但我想知道是否可以在安装后立即运行该服务,而无需重新启动电脑。) 欢迎评论。使用Silvio Iacarino的Inno设置 使用sc.exe,它很简单,唯一的缺点是您可能必须截取和解析输出,以了解出了什么
[Run]
Filename:"{sys}\myservice.exe "; Parameters: "-install"
我不确定这是否正确
(我为提醒重新启动添加了代码,但我想知道是否可以在安装后立即运行该服务,而无需重新启动电脑。)
欢迎评论。使用Silvio Iacarino的Inno设置
注意:不要在任何Windows系统文件夹中安装您的服务。它们应被视为Windows专用文件夹。除非您有非常非常好的理由在那里编写(即驱动程序),否则您不应该在那里安装软件。将其安装在应用程序文件夹中。除了公认的答案之外,我只想让人们更容易使用Luigi Sandon的服务库(非常感谢!)。下载脚本后,您需要在安装脚本中添加类似于以下内容的[Code]部分:
[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
。如果您想要的常量是[Setup]部分的设置之一,则答案非常有用,但由于您不能随意向该部分添加内容,因此这并不适用于您可能想要为其定义常量的所有内容
如果要为服务设置说明,则服务库不支持该功能,但使用[Registry]部分很容易,例如:
[Registry]
; set the service description
Root: HKLM; Subkey: "System\CurrentControlSet\Services\{#ServiceName}"; ValueType: string; ValueName: "Description"; ValueData: "{#ServiceDescription}"; Flags: deletevalue uninsdeletekey
最后,我可以确认这也适用于Windows 10。一项服务安装后可以立即运行,我一直都这样做。尽管在您的情况下,如果安装程序必须替换正在使用的文件,则可能需要重新启动。如果我记得,安装服务的建议不是使用服务的自安装,而是直接从安装程序写入所有注册表项。您应该使用SCM(服务控制管理器)API来安装服务,无法访问注册表。@David Heffernan:一件事是写入HKLM\Software,另一件事是写入HKLM\System。SCM API是一个定义良好且已发布的API。我知道写入注册表比使用API容易,但API IMHO是处理服务注册最安全的方法-我找不到任何使用该API不能做的事情,并且需要直接进行注册表操作。什么是“特定于服务的设置”?如果它们不是Windows服务设置,而是特定于应用程序的代码设置,则应在HKLM\软件下编写,而不是在HKLM\系统下编写。当然,SCM不能处理特定于应用程序的设置。无论如何,并非所有服务都需要以LocalSystem权限启动(如果可能的话,也不应该),因此访问注册表的需要应该仔细评估,并正确设置。但是如果您使用的是Unicode版本的Inno setup,那么这些脚本将无法工作。请参阅@ldsandon的答案,并注意他“服务库”页面底部的链接。+1尼斯库,我将用以下内容替换我自己开发的函数服务:)+1很棒的库(不仅仅是尼斯库)。到目前为止,在Unicode版本中没有发现任何问题代码>
[Registry]
; set the service description
Root: HKLM; Subkey: "System\CurrentControlSet\Services\{#ServiceName}"; ValueType: string; ValueName: "Description"; ValueData: "{#ServiceDescription}"; Flags: deletevalue uninsdeletekey