【问题标题】:Wix MSI package : for Windows serviceWix MSI 包:用于 Windows 服务
【发布时间】:2018-04-13 16:21:53
【问题描述】:

错误:使用 WiX 工具集为 Windows 服务创建新安装程序。无法安装服务。收到错误
Error screenshot

环境

  • 微软视觉工作室 2017
  • Windows 7
  • WiX 工具集 v3:MSI 设置项目

问题/目标

我想创建一个安装 Windows 服务的 MSI。

安装时:

Windows 服务已安装并在 services.msc 中可见

卸载时:

停止并删除服务。

我的 Windows 服务有很多依赖项,在运行服务时要使用这些依赖项。

我已将所有文件添加为组件,并为每个组件 ID 添加了ServiceDependency,但仍然无法解决错误。事件查看器中的错误也与上面的屏幕截图相同。

欢迎任何指点。

我的代码

    <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

    <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
    <MediaTemplate EmbedCab="yes" />

    <Feature Id="ProductFeature" Title="LayoutSwitcher" Level="1">
        <ComponentGroupRef Id="ProductComponents" />
    </Feature>
</Product>

<Fragment>
    <Directory Id="TARGETDIR" Name="SourceDir">
        <Directory Id="ProgramFilesFolder">
            <Directory Id="INSTALLFOLDER" Name="LayoutSwitcher" />
        </Directory>
    </Directory>
</Fragment>

<Fragment>
    <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">

  <Component Id="PlcmLayoutSwitcherWinSvc.exe" Guid="PUT_GUID_HERE" KeyPath="yes">
            <File Id="LayoutSwitcherWinSvc.exe" 
 Name="LayoutSwitcherWinSvc.exe" Source="$(var.LayoutSwitcherWinSvc_TargetDir)LayoutSwitcherWinSvc.exe" />

    <CreateFolder />
    <ServiceInstall Id="LayoutSwitcher" Type="ownProcess" Vital="yes" 
                    Name="LayoutSwitcher" DisplayName="LayoutSwitcher" 
                    Description="LayoutSwitcher" Start="auto" Account="NT AUTHORITY\LocalSystem" 
                    ErrorControl="ignore" Interactive="no">
   <ServiceControl Id="StartService" Start="install" Stop="both" 
    Remove="uninstall" Name="LayoutSwitcher" Wait="yes" />
  </Component>
    <Component Id="logoicon.ico" Guid="PUT_GUID_HERE">
        <File Id="logoicon.ico" Name="logoicon.ico" Source="$(var.LayoutSwitcherWinSvc_ProjectDir)logoicon.ico" />
     </Component>
     <Component Id="LayoutSwitcherWinSvc.exe.config" Guid="PUT_GUID_HERE">
     <File Id="LayoutSwitcherWinSvc.exe.config" Name="LayoutSwitcherWinSvc.exe.config" Source="$(var.LayoutSwitcherWinSvc_TargetDir)LayoutSwitcherWinSvc.exe.config" />
  </Component>
  <Component Id="Transactions.dll" Guid="PUT_GUID_HERE">
    <File Id="Transactions.dll" Name="Transactions.dll" Source="$(var.LayoutSwitcherWinSvc_TargetDir)Transactions.dll" />
  </Component>
  <Component Id="Transactions.Cfg.dll" Guid="PUT_GUID_HERE">
    <File Id=" Transactions.Cfg.dll" Name="Transactions.Cfg.dll" Source="$(var.LayoutSwitcherWinSvc_TargetDir) Transactions.Cfg.dll" />
  </Component>

编辑:1

去掉服务依赖后更新了源码,还是报同样的错误

编辑:2

删除了空格,但仍然出现相同的错误。

编辑:3

附上详细日志。请从以下链接下载。
http://www.yourfilelink.com/get.php?fid=1432133

【问题讨论】:

  • 查看事件查看器,查看缺少哪个文件。当实际上由于缺少组件而无法安装服务时,Wix 服务安装程序会弹出“拒绝访问”等错误。肯定抓到我很多次了!几乎可以保证您缺少项目 dll 或依赖框架,如 c++ redist 或 .net 框架

标签: c# windows wix windows-services windows-installer


【解决方案1】:

你能试试这段wix代码吗?我对其进行了一些清理以删除一些默认值。

除非你想用不同的文件名放置文件,否则你不需要 Name 属性。

如果您希望您的服务作为本地系统运行,那么您需要设置空帐户。如果您希望它以特定用户身份运行,则可以在命令行 SVCACCOUNT=someuser SVCPASSWORD="password" 上设置属性,否则跳过它们。

如果 Name 和 Id 相同,则可以跳过 Id。

我更喜欢将变量用于我在多个地方使用的东西以避免拼写错误,例如我使用的 ServiceInstall 和 ServiceControl 中使用的 ServiceName:

&lt;WixVariable Id="ServiceName" Value="LayoutSwitcher" /&gt;

<Component Id="PlcmLayoutSwitcherWinSvc.exe" Guid="PUT_GUID_HERE">
  <File Id="LayoutSwitcherWinSvc.exe" Source="$(var.LayoutSwitcherWinSvc_TargetDir)LayoutSwitcherWinSvc.exe" KeyPath="yes" />
  <ServiceInstall Name="!(wix.ServiceName)"
                  DisplayName="LayoutSwitcher"
                  Description="LayoutSwitcher"
                  ErrorControl="ignore"
                  Type="ownProcess" 
                  Vital="yes"
                  Start="auto"
                  Account="[SVCACCOUNT]"
                  Password="[SVCPASSWORD]" 
                  Interactive="no" />
  <ServiceControl Id="ServiceControl_!(wix.ServiceName)"
                  Name="!(wix.ServiceName)"
                  Start="install"
                  Stop="both"
                  Remove="uninstall"
                  Wait="yes" />
</Component>

您附加的日志不完整,请一直运行安装程序并仅在关闭安装程序后附加日志。不需要 IMO 调试日志。

【讨论】:

    【解决方案2】:

    尝试使安装和控件中的两个名称属性完全相同。他们需要完全匹配,但他们不需要。您正在尝试启动一个不存在的服务。

    【讨论】:

    • @alrightyy 您确定您在 ServiceControl 和 ServiceInstall 之间同步了名称属性吗?如果是,您能否检查 Windows 服务的事件日志。它可以为您提供更多信息,说明您的服务未启动的原因。
    • 保留存储 ServiceName 的单个安全属性,并在 serviceControl 和 serviceInstaller name 属性之间共享。这可以解决您的问题。
    【解决方案3】:

    您的 ServiceDepenency 元素似乎列出了您的服务的可执行文件所依赖的 dll 和其他文件。这不是 ServiceDependency 元素的意图。它应该列出必须在此服务之前启动的其他服务。您收到的错误可能是由于 LayoutSwitcherWinSvc.exe.config 和您列出的所有 *.dll 文件不是目标上安装的服务的名称机器。

    修复可能会删除这些 ServiceDependency 元素。然后,仅当您的服务依赖于其他服务时,才按名称为这些服务添加 ServiceDependency 元素。


    解决了这部分问题后,您的 ServiceInstallServiceControl 元素似乎仍然不正确。特别是,Name 属性不匹配。在您的示例代码中,您似乎在很多元素中都包含前导空格,我会删除它。但是,即使这只是复制和粘贴的勘误表,安装的 LayoutSwitcher 与启动的 Layout Switcher 之间也有一些空白。

    这与您在评论中提到的错误 0x80070424 匹配,因为 0x424 = 1060,并且 net helpmsg 1060 报告:

    指定的服务不作为已安装的服务存在。

    确保 ServiceInstall/@NameServiceControl/@Name 属性与您在手动启动服务时使用的属性相匹配。 (请注意,如果您的手动测试是在命令行上进行的,则很可能会隐式删除任何空格。)

    【讨论】:

    • 感谢您的回复。我已经编辑了帖子并删除了所有“服务依赖项”并添加了一个“文件”标签以将文件添加到该位置。但仍然遇到同样的错误。
    • 详细日志是否包含有关错误的更多信息?如果您删除了启动服务的配置(出于调试目的),您是否可以在安装完成后手动启动它?
    • 是的,我可以在删除“服务控制”后手动启动服务。详细日志不包含任何特定信息。
    • 以下是错误:无法存储 ACL 回滚信息,错误为 0x80070424;错误 0x80070424:无法获取对象的安全信息;CustomAction ExecSecureObjects 返回实际错误代码 1603
    • 我也曾尝试删除空格。仅供参考...手动启动时,尝试在 cmd 提示符下使用“installutil” .... VS 开发工具的实用程序。
    【解决方案4】:

    您的留言:

    “存储 ACL 回滚信息失败,错误 0x80070424;错误 0x80070424:无法获取对象的安全信息;CustomAction ExecSecureObjects 返回实际错误代码 1603”

    与服务无关。理想情况下,您应该关闭此问题,因为服务问题已解决,并且您现在有一个单独的问题,由该错误消息描述。

    不知何故,您设法调用了与您的服务无关的 WiX 自定义操作“ExecSecureObjects”。在您的 WiX 中的某个地方,您正尝试使用来自 WiX util 扩展的 PermissionEx 来保护某些对象。这就是你现在看到的问题。

    【讨论】:

      猜你喜欢
      • 2016-03-06
      • 2012-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-28
      • 2010-11-19
      相关资源
      最近更新 更多