我的服务在安装期间自动启动...
<ServiceControl Id="StartService" Start="install" Stop="both" Remove="uninstall" Name="HeskaGateway" Wait="yes" />
如果我为服务提供有效的连接字符串,它可以正常工作。如果我提供了一个错误的连接字符串,服务会很快启动和停止...当我转到服务并进行手动启动时,我会看到这一点。根据MSI ServiceControl Table上的文档,等待值为&#34;是&#34;变成1意味着它应该等待30秒然后失败。需要4分7秒。为什么这么久?
MSI (s) (6C:78) [16:36:41:932]: Executing op: ServiceControl(,Name=HeskaGateway,Action=1,Wait=1,)
StartServices: Service: Heska Gateway
MSI (s) (6C:78) [16:40:48:862]: Note: 1: 2205 2: 3: Error
MSI (s) (6C:78) [16:40:48:862]: Note: 1: 2228 2: 3: Error 4: SELECT `Message` FROM `Error` WHERE `Error` = 1920
Error 1920. Service 'Heska Gateway' (HeskaGateway) failed to start. Verify that you have sufficient privileges to start system services.
编辑:我从来没有弄清楚我的真正问题是什么。我还有一个安装顺序错误,因为我的CustomAction(延迟)将编辑JSON文件中的连接字符串,这是在ServiceStart之后触发的。尝试在延迟的自定义操作之后移动ServiceStart非常糟糕。所以我从ServiceControl条目中删除了开始,然后添加了另一个自定义动作,它默默运行&#34; SC.EXE启动HeskaGateway&#34;。我将以下文件作为解决方案进行记录。
答案 0 :(得分:1)
安装程序有一个自定义UI,要求用户复制粘贴从支持部门提供给他们的连接字符串。安装程序使用延迟的CustomAction编辑app文件夹中的JSON文件。它被推迟,因为它需要在将文件写入磁盘之后,并且还需要具有提升的权限。这一切都很有效,直到我决定让服务从“安装结束”开始。我的第一次尝试是使用
<ServiceControl Id="StartService" Start="install" ...>
但这需要4分钟才能失败。疑难解答显示,在将连接字符串写入JSON文件的自定义操作之前,服务正在启动。我需要将服务开始延迟到自定义操作之后。我看着在自己的组件中添加第二个ServiceControl条目,可以在以后安排,但这让我感到不舒服,我打算打破卸载和修复安装。所以,我刚刚在JSON文件编辑后添加了另一个延迟的自定义动作。 该新操作执行“SC.EXE start MyServiceName”。 SC.EXE是一种非阻塞的启动服务的方式,因此成功或失败,它将很快完成。
我的最终解决方案:
<Component Id="MyCloudSync.exe" Guid="{generate-your-own-guid}">
<File Id="MyCloudSync.exe.file" KeyPath="yes" Source="$(var.RELEASEBINARIES)\MyCloudSync.exe" />
<ServiceInstall Id="MyCloudSync.exe"
Type="ownProcess"
Name="MyGateway"
DisplayName="My Gateway"
Description="Synchronizes laboratory data with Cloud"
Start="auto"
ErrorControl="normal" />
<!--Start is performed by a customer action that calls SC.EXE so it can be delayed after the custom action that writes the JSON file -->
<ServiceControl Id="StartService" Stop="both" Remove="uninstall" Name="MyGateway" Wait="yes" />
</Component>
您应该注意上面的ServiceControl条目没有“start =” GetConnectionString和SetConnectionString调用的DLL是我自己制作的。 Wix有自己的自定义操作,可以安静地运行命令行...... WixQuietExec
<CustomAction Id= "GetConnectionString"
BinaryKey="MyCustomActions"
DllEntry="GetConnectionString"
Execute="immediate"/>
<CustomAction Id= "SetConnectionString"
BinaryKey="MyCustomActions"
Impersonate="no"
DllEntry="SetConnectionString"
Execute="deferred"/>
<CustomAction Id="SetConnectionStringDeferredParams"
Property="SetConnectionString"
Value=""[INSTALLFOLDER]""[CONNECTIONSTRING]"" />
<Property Id="QtExecStartService" Value=""SC.EXE" start MyGateway"/>
<CustomAction Id="QtExecStartService"
BinaryKey="WixCA"
DllEntry="WixQuietExec"
Impersonate="no"
Execute="deferred"
Return="ignore"/>
启动服务只是一种便利,因此安装程序可以阻止运行Services.msc来执行启动或需要重新启动。所以我用了Return =“ignore”。此外,SC.EXE只是将服务置于“Start Pending”中,因此除非您的服务不存在,否则它可能无法返回大量错误。
注意: WixQuietExec记录在案here。确保引用EXE并为您的属性提供与使用WixQuietExec的CustomAction相同的ID。该信息属于“延期执行”,但我第一次尝试时仍然出错。
答案 1 :(得分:0)
错误1920 :此错误似乎表示缺少权限(logon as a service
)或访问权限,或者来自外部原因或者未运行提升的 MSI 程序包(我认为不太可能 - 那么您只能写入每用户路径)。
regular user account
运行此服务? (about the above service accounts)。 LogonAsService="yes"
(元素)设置User
。我相信这会为帐户添加权限(SeServiceLogonRight)。InstallPrivileges
)。JSON
格式,显然可以采用多种格式:XML
,registry
,INI
等...请参阅上面的OP评论了解更多信息的信息。 超时 :关于超时超时。我有时会看到安全软件(锁定整个设置以便服务超时仅在一些扫描延迟后运行),或者设置触发创建系统还原点首先安装开始之前(这是一些MSI安装在通常快速完成时突然需要很长时间的原因之一 - 可以prevent this restore point creation - MSIFASTINSTALL) 。此外,也许可以从serverfault和注册表值中检查此答案,以确定网络上是否存在更改默认服务启动超时的策略:How do I increase windows service startup timeout(ServicesPipeTimeout
)。坦率地说,我不确定MSI是否使用自己的超时或系统默认值 - 也许有人可以照亮?还可以推测您启动的数据库连接有自己的超时? (与您的交互式测试体验不符?)也许您可以检查您的代码和电话,并告诉我们? 您的服务是否依赖其他服务? (参见下面的赛门铁克链接)。对于 GAC 或 WinSxS 中安装的文件的依赖关系,如下面第一个链接中Chris所述?
<强> 链接 强>:
答案 2 :(得分:0)
服务本身可能正在做某事。服务控制协议包括从服务本身返回的服务状态,这告诉Windows正在进行什么。其中一项是等待提示。对服务一无所知,服务可能意识到它可能启动缓慢并且告诉Windows(等待提示)它应该等待更长时间。 30秒实际上是默认值,而不是固定值。这篇文章引用了托管代码服务的等待提示:
How to choose value for serviceStatus.dwWaitHint?
您没有显示用于安装服务的ServiceControl,但如果它在同一进程中与其他服务共享,则事情会变得复杂,因为进程本身无法终止#&# 39; s还托管另一项服务。