Wix - ServiceControl启动需要四分钟才能失败,应该是30秒

时间:2018-05-14 22:56:58

标签: wix windows-installer

我的服务在安装期间自动启动...

<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;。我将以下文件作为解决方案进行记录。

3 个答案:

答案 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="&quot;[INSTALLFOLDER]&quot;&quot;[CONNECTIONSTRING]&quot;" />
    <Property Id="QtExecStartService" Value="&quot;SC.EXE&quot; 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 程序包(我认为不太可能 - 那么您只能写入每用户路径)。

  • 您是否使用LocalSystem帐户或NetworkServiceLocalServiceregular user account运行此服务? (about the above service accounts)。
  • managed service accountsgroup managed service accounts或虚拟帐户step-by-step info的新概念(我不了解的概念)。
  • 如果您使用常规用户帐户,是否具有“登录即服务”权限集?
    • 如果您在WiX MSI中创建用户(或定义用户),则可以为相关的LogonAsService="yes"(元素)设置User。我相信这会为帐户添加权限(SeServiceLogonRight)。
    • 权限与访问权限(ACL)不同 - 对于记录:权限是对某种功能/功能的普遍系统范围访问 - 例如更改系统时间,启动/停止服务,作为服务登录等等......(see section 13 here for more)。
  • 您的测试盒上是否有安全软件/防病毒?它可能会干扰您的设置的API调用。如果是这样,请尝试在安装过程中禁用它(如果可能)。我也会提到防火墙
  • 您的 MSI 是否设置为提升? (Package Element =&gt; InstallPrivileges)。
  • 更新:只需添加问题原因是:使用提升权限运行所需的配置数据的自定义操作更新错误的服务配置数据结果导致了通用的1920错误消息。在这种情况下,配置采用JSON格式,显然可以采用多种格式:XMLregistryINI等...请参阅上面的OP评论了解更多信息的信息。

超时 :关于超时超时。我有时会看到安全软件(锁定整个设置以便服务超时仅在一些扫描延迟后运行),或者设置触发创建系统还原点首先安装开始之前(这是一些MSI安装在通常快速完成时突然需要很长时间的原因之一 - 可以prevent this restore point creation - MSIFASTINSTALL) 。此外,也许可以从serverfault和注册表值中检查此答案,以确定网络上是否存在更改默认服务启动超时的策略:How do I increase windows service startup timeoutServicesPipeTimeout)。坦率地说,我不确定MSI是否使用自己的超时或系统默认值 - 也许有人可以照亮?还可以推测您启动的数据库连接有自己的超时? (与您的交互式测试体验不符?)也许您可以检查您的代码和电话,并告诉我们? 您的服务是否依赖其他服务? (参见下面的赛门铁克链接)。对于 GAC WinSxS 中安装的文件的依赖关系,如下面第一个链接中Chris所述?

很多猜测。让我们希望它有一些帮助,或者它激发其他解决问题的想法。下面是一些安全保护链接(尝试编写一个通用的答案,也可以帮助其他人解决相同或类似的问题 - 这使得答案太长,对此感到抱歉)。

<强> 链接

答案 2 :(得分:0)

服务本身可能正在做某事。服务控制协议包括从服务本身返回的服务状态,这告诉Windows正在进行什么。其中一项是等待提示。对服务一无所知,服务可能意识到它可能启动缓慢并且告诉Windows(等待提示)它应该等待更长时间。 30秒实际上是默认值,而不是固定值。这篇文章引用了托管代码服务的等待提示:

How to choose value for serviceStatus.dwWaitHint?

您没有显示用于安装服务的ServiceControl,但如果它在同一进程中与其他服务共享,则事情会变得复杂,因为进程本身无法终止#&# 39; s还托管另一项服务。