18

I have following .wxs-file:

<?xml version="1.0" encoding="UTF-8"?>
<?define ProductVersion="x.x.x.x" ?>
<?define UpgradeCode="{**MYGUID**}" ?>
<?define Manufacturer="My Company" ?>
<?define ProductName="My Product" ?>
<?define SkuName="MyProduct" ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="*"
             Name="$(var.ProductName)"
             Language="1033"
             Version="$(var.ProductVersion)"
             Manufacturer="$(var.Manufacturer)"
             UpgradeCode="$(var.UpgradeCode)">
        <Package InstallerVersion="301"
                 Compressed="yes"
                 InstallPrivileges="elevated"
                 InstallScope="perMachine"
                 Platform="x86" />
        <Media Id="1"
               Cabinet="$(var.SkuName).cab"
               EmbedCab="yes" />
        <Directory Id="TARGETDIR"
                   Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
                <Directory Id="ManufacturereDirectory"
                           Name="$(var.Manufacturer)">
                    <Directory Id="ProductDirectory"
                               Name="$(var.ProductName)" />
                </Directory>
            </Directory>
        </Directory>
        <ComponentGroup Id="MainComponentGroup">
            <Component Directory="ProductDirectory">
                <File Name="$(var.MyProject.TargetFileName)"
                      Source="$(var.MyProject.TargetPath)"
                      KeyPath="yes"
                      Vital="yes" />
                <ServiceInstall Id="SeviceInstall"
                                Name="$(var.ProductName)"
                                DisplayName="$(var.ProductName)"
                                Type="ownProcess"
                                Interactive="no"
                                Start="auto"
                                Vital="yes"
                                ErrorControl="normal"
                                Account="LOCALSYSTEM">
                </ServiceInstall>
                <ServiceControl Id="ServiceControl_Start"
                                Name="$(var.ProductName)"
                                Start="install"
                                Wait="no" />
                <ServiceControl Id="ServiceControl_Stop"
                                Name="$(var.ProductName)"
                                Stop="both"
                                Remove="uninstall"
                                Wait="yes" />
            </Component>
        </ComponentGroup>
        <Feature Id="MainFeature"
                 Level="1">
            <ComponentGroupRef Id="MainComponentGroup" />
        </Feature>
        <Upgrade Id="$(var.UpgradeCode)">
            <UpgradeVersion Property="UPGRADEFOUND"
                            Minimum="0.0.0.1" IncludeMinimum="yes"
                            Maximum="$(var.ProductVersion)" IncludeMaximum="yes"
                            OnlyDetect="no"
                            IgnoreRemoveFailure="yes"
                            MigrateFeatures="yes"/>
        </Upgrade>
        <CustomAction Id="ServiceRestarter"
                      Directory="ProductDirectory"
                      ExeCommand="&quot;[SystemFolder]sc.exe&quot; failure &quot;$(var.ProductName)&quot; reset= 60 actions= restart/0"
                      Impersonate="no" />
        <InstallExecuteSequence>
            <InstallExecute Before="RemoveExistingProducts" />
            <RemoveExistingProducts Before="InstallFinalize" />
            <Custom Action="ServiceRestarter" After="InstallFinalize"><![CDATA[NOT Installed]]></Custom>
        </InstallExecuteSequence>
    </Product>
</Wix>

Before that, I've tried:

<CustomAction Id="ServiceRestarter"
              Property="QtExecCmdLine"
              Value='"[SystemFolder]sc.exe" failure "$(var.ProductName)" reset= 60 actions= restart/0' />

which apparently called sc.exe - but changed nothing ...

Before that I've tried:

<ServiceInstall Id="SeviceInstall"
                Name="$(var.ProductName)"
                DisplayName="$(var.ProductName)"
                Type="ownProcess"
                Interactive="no"
                Start="auto"
                Vital="yes"
                ErrorControl="normal"
                Account="LOCALSYSTEM">
    <ServiceConfig Id="ServiceConfig"
                   DelayedAutoStart="yes"
                   OnInstall="yes"
                   OnReinstall="yes"
                   OnUninstall="no"
                   FailureActionsWhen="failedToStopOrReturnedError" />
    <ServiceConfigFailureActions Id="ServiceRestarter"
                                 OnInstall="yes"
                                 OnReinstall="yes"
                                 OnUninstall="no"
                                 ResetPeriod="0">
        <Failure Action="restartService" Delay="0" />
        <Failure Action="restartService" Delay="0" />
        <Failure Action="restartService" Delay="0" />
    </ServiceConfigFailureActions>
</ServiceInstall>

which did not work, as the MsiServiceConfigFailureActions table does not work if using an installer < 5.0, and even if using InstallerVersion="500" the only thing I get is an error:

Serivce 'My Product' (My Product) could not be configured. This could be a problem with the package or your permissions. Verify that you have sufficient privileges to configure system services.

(and yes, ... I've tried InstallPrivilges="elevated" also - but ... the real issue is Action="restartService" according to this)

So ... using a CustomAction is the way to go (or not?).

I have following output of the log

MSI (s) (34:28) [13:56:46:914]: Note: 1: 1722 2: ServiceRestarter 3: C:\Program Files (x86)\My Company\My Product\ 4: "C:\Windows\SysWOW64\sc.exe" failure "My Product" reset= 60 actions= restart/0
MSI (s) (34:28) [13:56:46:914]: Note: 1: 2205 2: 3: Error
MSI (s) (34:28) [13:56:46:914]: Note: 1: 2228 2: 3: Error 4: SELECT Message FROM Error WHERE Error = 1722
MSI (c) (2C:0C) [13:56:46:914]: Font created. Charset: Req=0, Ret=0, Font: Req=MS Shell Dlg, Ret=MS Shell Dlg

Error 1722. There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. Action ServiceRestarter, location: C:\Program Files (x86)\My Company\My Product\, command: "C:\Windows\SysWOW64\sc.exe" failure "My Product" reset= 60 actions= restart/0
MSI (s) (34:28) [13:56:48:849]: Note: 1: 2205 2: 3: Error
MSI (s) (34:28) [13:56:48:849]: Note: 1: 2228 2: 3: Error 4: SELECT Message FROM Error WHERE Error = 1709
MSI (s) (34:28) [13:56:48:849]: Product: My Product -- Error 1722. There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. Action ServiceRestarter, location: C:\Program Files (x86)\My Company\My Product\, command: "C:\Windows\SysWOW64\sc.exe" failure "My Product" reset= 60 actions= restart/0

Action ended 13:56:48: ServiceRestarter. Return value 3.
Action ended 13:56:48: INSTALL. Return value 3.

Can anybody help me out?

edit

I've used the old ServiceConfig-extension:

<util:ServiceConfig xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"
                    FirstFailureActionType="restart"
                    SecondFailureActionType="restart"
                    ThirdFailureActionType="restart"
                    ResetPeriodInDays="1"
                    RestartServiceDelayInSeconds="20" />

which gives me a following build-error:

error CNDL0200: The ServiceInstall element contains an unhandled extension element 'util:ServiceConfig'. Please ensure that the extension for elements in the 'http://schemas.microsoft.com/wix/UtilExtension' namespace has been provided.

I know that I can resolve this error by using -ext WixUtilExtension via commandline - but I want to use Visual Studio for building ... So how can I adapt the build-command?

Only chance is to add a reference to WixUtilExtension.dll to my project.

  • @david.barkhuizen actually, there is one available: http://stackoverflow.com/questions/tagged/wix4 –  Jan 21 '16 at 14:37
  • @david.barkhuizen my question specifically targets 3.5/3.6, so the introduction of the [tag:wix4] would be wrong - that's the reason why your edit got rejected (or otherwise I'd have reverted it) –  Jan 22 '16 at 12:37

3 Answers3

23

I can see that you've only tried the ServiceConfig element, which came with MSI 5.0. However, there's another ServiceConfig element in UtilExtension, which has been there for a long time and it seems that the thread you mention in your question confirms that it works.

The util:ServiceConfig element contains 3 parameters you'd like to use: FirstFailureActionType, SecondFailureActionType and ThirdFailureActionType, all accepting the same enumeration of values - none, reboot, restart and runCommand.

Try it out and if it works, it is far better choice than a custom action.

Yan Sklyarenko
  • 31,557
  • 24
  • 104
  • 139
12

For WIX V 4.0, building with VS2015, the following works:

1: Ensure that WixUtilExtension.dll assembly is referenced by WIX project.

2: Add http://wixtoolset.org/schemas/v4/wxs/util ns to root Wix element. Note that this is the correct NS for WIX 4.0 (NOT http://schemas.microsoft.com/wix/UtilExtension as for previous versions).

<Wix
  xmlns="http://wixtoolset.org/schemas/v4/wxs"
  xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util"
  >

3: Ensure that ServiceConfig element is prefixed with correct namespace reference.

<ServiceInstall
      Id="MyService"
      Type="ownProcess"
      Name="MyService"
      DisplayName="MyService"
      Description="My Service"
      Start="auto"
      Account="[SERVICEACCOUNT]"
      Password="[SERVICEPASSWORD]"
      ErrorControl="normal"
    >

      <util:ServiceConfig
        FirstFailureActionType='restart'
        SecondFailureActionType='restart'
        ThirdFailureActionType='restart'            
        RestartServiceDelayInSeconds='30'
        ResetPeriodInDays='1'/>

</ServiceInstall>
david.barkhuizen
  • 5,239
  • 4
  • 36
  • 38
  • 4
    util:ServiceConfig also works with WIX version 3.10.0.1503, using the xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" definition and the .dll reference – Jared Dykstra Mar 02 '16 at 17:50
  • 1
    The answer of @JaredDykstra not work to me. but thats give me an orientation. I found and try with this: `` and works. My version of WIX is 3.10.0.2103. – gemr1423 Mar 08 '16 at 20:39
  • 1
    Keep in mind "RestartServiceDelayInSeconds" is in seconds, but the Windows UI shows minutes, so if you set 30 seconds in this parameter, when viewed through the Windows UI, you'll see this parameter set to 0 minutes. – Eccentropy Nov 22 '17 at 22:37
1

In Visual Studio, to avoid using -ext in CLI you may do the following:

Of course, you add a resource: <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">

then, in Solution Explorer -> References -> Add.. WixUtilExtension.dll

After that everything works like a charm. (wix 3.10)

Of course, if you do use the second ServiceConfig from utils. Like <util:ServiceConfig blablabla

Osolemio
  • 41
  • 1
  • 5
  • Thanks for your input, but that approach has already been suggested in other comments and answers :) –  Feb 07 '17 at 08:25