Can't start Windows service with WiX

2019-04-06 04:15发布

I have the following WiX project to install my service:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Product Id="GUID" Name="SetupWinService" Language="1049"
           Version="1.0.0.0" Manufacturer="SetupWinService"
           UpgradeCode="GUID">
    <Package InstallerVersion="200" Compressed="yes"
             Languages="1049" SummaryCodepage="1251"
             InstallPrivileges="elevated"/>

    <Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />

    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="WinService" Name="My Windows Service">
        </Directory>
      </Directory>
    </Directory>

    <DirectoryRef Id="WinService">
      <Component Id="WinServiceInstallation" Guid="GUID">
        <File Id="ClientService.exe"
              Name="ClientService.exe"
              Source="...\ClientService.exe"
              Vital="yes" KeyPath="yes" DiskId="1"/>
        <File Id="App.config"
              Name="App.config"
              Source="...\App.config"
              Vital="yes" KeyPath="no" DiskId="1"/>

            <!--And some DLLs here-->

        <ServiceInstall Id="ServiceInstaller"
                        Type="ownProcess"
                        Vital="yes"
                        Name="WcfServiceHost"
                        DisplayName="WcfServiceHost"
                        Description="Hosts Wcf Service"
                        Start="auto"
                        Account="LocalSystem"
                        ErrorControl="ignore"
                        Interactive="no">
        </ServiceInstall>
        <ServiceControl Id="StartService" Name="WcfServiceHost"
                        Start="install" Stop="uninstall" Remove="uninstall"
                        Wait="yes" />
      </Component>
    </DirectoryRef>

    <Feature Id="Complete" Title="SetupWinService" Level="1">
      <ComponentRef Id="WinServiceInstallation" />
      <ComponentGroupRef Id="Product.Generated" />
    </Feature>
  </Product>
</Wix>

I can install my service, but I can't start it after installing. It tells:

Service failed to start. Verify that you have sufficient privileges to start system services.

But I run my installer as administrator (Windows 7 Professional) and also disable UAC. Furthermore, I can install and run the service with instalutil.exe through command prompt (my service project includes realization of Installer class and in general is marked up according to this article), and all works fine with the service in that case.

If I replace Wait="yes" of the ServiceControl element to "no", the service installs without errors, but it does not start. I also can't start the service manually in that case, because the service starts and immediately stops with message "service on Local Computer started and then stopped. Some services stop automatically if they have no work to do".

I searched about this problem on the Internet, but I didn't find any solutions.

How do I fix it?

That is the code of my Installer class:

[RunInstaller(true)]
public class ProjectInstaller : Installer
{
    private ServiceProcessInstaller serviceProcessInstaller;
    private ServiceInstaller serviceInstaller;

    public ProjectInstaller()
    {
        this.serviceProcessInstaller = new ServiceProcessInstaller();
        this.serviceProcessInstaller.Account = ServiceAccount.LocalSystem;
        this.serviceProcessInstaller.Username = null;
        this.serviceProcessInstaller.Password = null;
        this.serviceInstaller = new ServiceInstaller();
        this.serviceInstaller.ServiceName = "ClientServicesHost";
        this.serviceInstaller.StartType = ServiceStartMode.Automatic;
        this.Installers.Add(serviceProcessInstaller);
        this.Installers.Add(serviceInstaller);
        this.AfterInstall +=
                new InstallEventHandler(ProjectInstaller_AfterInstall);
    }

    void ProjectInstaller_AfterInstall(object sender, InstallEventArgs e)
    {
        ServiceController sc = new ServiceController("ClientServicesHost");
        sc.Start();
    }
}

And my Windows service:

class WindowsClientService : ServiceBase
{
    public ServiceHost serviceHost = null;

    public WindowsClientService()
    {
        this.ServiceName = "WcfServiceHost";
    }

    public static void Main()
    {
        ServiceBase.Run(new WindowsClientService());
    }

    protected override void OnStart(string[] args)
    {
        if (serviceHost != null)
        {
            serviceHost.Close();
        }

        // Create a ServiceHost for WcfClientService type
        // and provide the base address.
        serviceHost = new ServiceHost(typeof(WcfClientService));

        // Open the ServiceHost to create listeners
        // and start listening for messages.
        serviceHost.Open();
    }

    protected override void OnStop()
    {
        if (serviceHost != null)
        {
            serviceHost.Close();
            serviceHost = null;
        }
    }
}

I was pointed out that the reason of my service automatically stops - it does nothing after start. Can it be? My service creates listeners and starts listening - is that "does nothing"?

7条回答
再贱就再见
2楼-- · 2019-04-06 04:27

I have been looking for the answer for a while, and finally I've resolved it!

Keep the same ServiceControl name as the ServiceInstall name.

Result:

<?xml version="1.0" encoding="utf-8"?>
<?define ProductVersion = "1.0.0"?>
<?define ProductUpgradeCode = "{E8DFD614-41F6-4592-AD7A-27EA8A49C82E}"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
     xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
  <Product Id="*" UpgradeCode="$(var.ProductUpgradeCode)"
           Name="Eyes Relax"
           Version="$(var.ProductVersion)"
           Manufacturer="Ourdark"
           Language="1033">
    <Package Manufacturer="Ourdark" InstallerVersion="100" Languages="1033" Compressed="yes" />

    <Media Id="1" Cabinet="WHSDiskManagement.1.1.0.0.cab" EmbedCab="yes" />

    <Property Id="WHSLogo">1</Property>

    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder" Name="PFiles">
        <Directory Id="WHS" Name="Eyes Relax">
          <Component Id="EyesRelax" Guid="{78534F5E-FC72-49E6-AF11-4F2068EA7571}">

            <File Id="RelaxEyes.exe.config"
                  Name="RelaxEyes.exe.config"
                  Source="RelaxEyes\bin\Debug\RelaxEyes.exe.config"
                  Vital="yes"
                  KeyPath="no"
                  DiskId="1"/>

            <File Id="RelaxEyes.exe"
                  Name="RelaxEyes.exe"
                  Source="RelaxEyes\bin\Debug\RelaxEyes.exe"
                  Vital="yes"
                  KeyPath="yes"
                  DiskId="1"/>

            <ServiceInstall
              Id="ServiceInstaller"
              Type="ownProcess"
              Vital="yes"
              Name="Eyes Relax"
              DisplayName="Eyes Relax"
              Description="Eyes Relax"
              Start="auto"
              Account="NT AUTHORITY\LocalService"
              ErrorControl="ignore"
              Interactive="no">
            </ServiceInstall>
            <ServiceControl Id="StartService"
                            Start="install"
                            Stop="both"
                            Remove="uninstall"
                            Name="Eyes Relax"
                            Wait="yes" />
          </Component>
        </Directory>
      </Directory>
    </Directory>

    <Feature Id="ProductFeature" Title="WHSDiskManagement" Level="1">
      <ComponentRef Id="EyesRelax" />
    </Feature>
  </Product>
</Wix>
查看更多
我命由我不由天
3楼-- · 2019-04-06 04:28

Well, I returned to this project after about 1 and half year. And trying to recompile it and start this service again. And it works!

All that changed is I added clientaccesspolicy.xml to my service and run policyServiceHost (of type WebServiceHost) along with my service. But I don't think it is important because of it relates to insides of my application - not to service start.

So I tried many variations, like:

1) this.serviceProcessInstaller.Username = null;

or

this.serviceProcessInstaller.Username = @"NT AUTHORITY\SYSTEM";

2) Two or single ServiceControl sections.

3) Stop="both"

or

Stop="uninstall"

ALL WORKS FINE NOW!!!

I don't know what is happening. I just leave it to some type of bug or something strange configuration of my system or whatever else that doesn't allow me to start my service automatically before. But now all worksfine.

Another words, I didn't find out what was the reason of my service won't to start automatically. It was about "sufficient privileges" (see the first post) but it is not clear enough for me even now.

Only one remark. If I use two ServiceControl sections while uninstalling the service, a warning window appears (Windows 7) and offer to close application (service) automatically and so on. So I just accept and service uninstalls well. But no warning windows appear if I use only one ServiceControl section as in my example in the first post. And again it is no relations to 1) and 3) points combination.

查看更多
姐就是有狂的资本
4楼-- · 2019-04-06 04:31

I had the same issue using WiX 3.7.821.0 and my service. It installed for a while and the same annoying "Service failed to start. Verify that you have sufficient privileges to start system services" appeared.

I tried a lot, but the final thing was to use two sections for <ServiceControl> instead of trying to cram all in a single one. One for Start and one for Stop. Now the service starts fine.

This does not work:

<ServiceControl Id="StartService" 
                Start="install" 
                Stop="both" 
                Remove="uninstall" 
                Name="MyService" 
                Wait="yes" />

This works:

<ServiceControl Id="ServiceControl_Start"
                Name="MyService"
                Start="install"
                Wait="no" />
<ServiceControl Id="ServiceControl_Stop"
                Name="MyService"
                Stop="both"
                Remove="uninstall"
                Wait="yes" />
查看更多
相关推荐>>
5楼-- · 2019-04-06 04:31

I'd use this snippet for the .wxs-file

<?xml version="1.0" encoding="UTF-8"?>
<?define ProductVersion="1.0.0.0" ?>
<?define UpgradeCode="{YOURGUID}" ?>
<?define Manufacturer="SetupWinService" ?>
<?define ProductName="WcfServiceHost" ?>
<?define SkuName="WcfServiceHost" ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="*"
             Name="$(var.ProductName)"
             Language="1049"
             Version="$(var.ProductVersion)"
             Manufacturer="$(var.Manufacturer)"
             UpgradeCode="$(var.UpgradeCode)">
        <!-- do you really need 200? i'd try at least 301 -->
        <Package InstallerVersion="301"
                 Compressed="yes"
                 Languages="1049"
                 InstallPrivileges="elevated"
                 SummaryCodepage="1251"
                 Platform="x86" />
        <Media Id="1"
               Cabinet="$(var.SkuName).cab"
               EmbedCab="yes" />
        <Directory Id="TARGETDIR"
                   Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
                <Directory Id="ProductDirectory"
                           Name="$(var.ProductName)" />
            </Directory>
        </Directory>
        <ComponentGroup Id="MainComponentGroup">
            <Component Directory="ProductDirectory">
                <File Name="$(var.**Project**.TargetFileName)"
                      Source="$(var.**Project**.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>
            <Component Directory="ProductDirectory">
                <File Name="App.config"
                      Source="$(var.**Project**.TargetDir)\app.config"
                      Vital="yes" />
            </Component>
        </ComponentGroup>
        <Feature Id="MainFeature"
                 Level="1">
            <ComponentGroupRef Id="MainComponentGroup" />
        </Feature>
        <!-- added automatic upgrading -->
        <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>
        <InstallExecuteSequence>
            <InstallExecute Before="RemoveExistingProducts" />
            <RemoveExistingProducts Before="InstallFinalize" />
        </InstallExecuteSequence>
    </Product>
</Wix>

With this basic System.ServiceProcess.ServiceBase-implementation (which does not really differ from yours)

public partial class Service : ServiceBase
{
    public Service()
    {
        this.InitializeComponent();
    }

    public static void Main()
    {
        Run(new Service());
    }

    #region Service Commands

    protected override void OnStart(string[] args)
    {
    }

    protected override void OnStop()
    {
    }

    protected override void OnPause()
    {
        this.OnStop();
    }

    #endregion
}

With this snippet I got a demo-project to work ...

Fully working demo project available - if this still fails, please adapt the code, so that I can reproduce your issue!

查看更多
啃猪蹄的小仙女
6楼-- · 2019-04-06 04:33

I had this error on some computers. The same executable works on some and gives this error on others.

Updating .NET 1.1/2.0/3.0 on these computers helps (it worked for me on Windows XP, 7 and 8.1).

查看更多
\"骚年 ilove
7楼-- · 2019-04-06 04:35

I had the same error, and in my case I was missing KeyPath='yes' Vital="yes" on my file element.

Here is my component definition:

<Component Id="ComponentName"
           Guid="3aa1d5a5-28f0-4753-8e4b-a7ac0848d8be" >
    <File Id='ServiceFile'
          Name='Service.exe'
          DiskId='1'
          Source='bin\Service.exe'
          KeyPath='yes'
          Vital="yes"/>

    <ServiceInstall Id="ServiceInstaller"
                    Type="ownProcess"
                    Name="Service"
                    DisplayName="Service"
                    Description="A Service"
                    Start="auto"
                    ErrorControl="normal"
                    />

    <ServiceControl Id="ServiceControl"
                    Start="install"
                    Stop="both"
                    Remove="uninstall"
                    Name="Service"
                    Wait="yes" />
</Component>
查看更多
登录 后发表回答