0

I am facing a very peculiar issue. I have a .net core windows service (XYZ) whose installer (XYZ.msi) is created using Wix. I am trying to install this service in a container. The service gets installed, then windows tries to register it as a service, the service times out giving me the following "information" in System Eventlogs The XYZ Service (XYZ) service failed to start due to the following error: %%1053 A timeout was reached (30000 milliseconds) while waiting for the XYZ service (XYZ) service to connect., and then the service gets uninstalled which is expected.

Further when I check the Application event logs I get these

Product: XYZ -- Error 1920. Service 'XYZ' (XYZ) failed to start. Verify that you have sufficient privileges to start system services.

Windows Installer installed the product. Product Name: XYZ. Product Version: 0.0.0.0. Product Language: 1033. Manufacturer: .... Installation success or error status: 1603.

So in order to understand these error codes I referred to Error Code 1603 and few other links on Error 1920, but since these are pretty generic, these links were of no use.

The same service is working fine locally and on a different server.

The folder inside the container where XYZ.msi resides has these privileges

Path   : Microsoft.PowerShell.Core\FileSystem::C:\app
Owner  : NT AUTHORITY\SYSTEM
Group  : NT AUTHORITY\SYSTEM
Access : BUILTIN\Administrators Allow  FullControl
         BUILTIN\Administrators Allow  268435456
         NT AUTHORITY\SYSTEM Allow  FullControl
         NT AUTHORITY\SYSTEM Allow  268435456
         NT AUTHORITY\Authenticated Users Allow  Modify, Synchronize
         NT AUTHORITY\Authenticated Users Allow  -536805376
         BUILTIN\Users Allow  ReadAndExecute, Synchronize
         BUILTIN\Users Allow  -1610612736
Audit  :
Sddl   : O:SYG:SYD:(A;ID;FA;;;BA)(A;OICIIOID;GA;;;BA)(A;ID;FA;;;SY)(A;OICIIOID;GA;;;SY)(A;ID;0x1301bf;;;AU)(A;OICIIOID;SDGXGWGR;;;AU)(A;ID;0x1200a9;;;BU)(A;OICIIOID;GXGR;;;BU)

Also I am assuming that all the installation happen with ContainerAdministrator account inside the container.

Now I am not able to figure out what the problem is, how to troubleshoot it further and if its a privileges issue what privileges do I need to set. Any help in this regard would be appreciated. Thanks !

EDIT: The dockerFile looks like this

FROM mcr.microsoft.com/windows/servercore:ltsc2019-amd64
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
WORKDIR /app
COPY [".","."]
RUN  ["powershell.exe", "./install.cmd"]

WiX .wxs code

<Fragment>
    <ComponentGroup Id="ServiceComponents" Directory="APPLICATIONFOLDER">
      <Component Id="ServiceComponent" Guid="649E5964-126A-4DF5-95CF-CE7C2474E981">
        <File Id="xyz.exe" KeyPath="yes" Vital="yes" DiskId="1" Source="..\xyz\bin\$(var.Platform)\$(var.Configuration)\netcoreapp3.1\win-x64\xyz.exe"/>
        <ServiceInstall
          Id="ServiceInstaller"
          Type="ownProcess"
          Vital="yes"
          Name="xyz"
          DisplayName="$(var.ProductName)"
          Description="$(var.Description)"
          Start="auto"
          Account="NT AUTHORITY\LocalService"
          ErrorControl="normal" Interactive="no">
          <ServiceConfig DelayedAutoStart="yes" OnInstall="yes" OnReinstall="yes" />
          <util:ServiceConfig FirstFailureActionType="restart" SecondFailureActionType="restart" ThirdFailureActionType="none" ResetPeriodInDays="1" RestartServiceDelayInSeconds="0" />
        </ServiceInstall>
        <ServiceControl
          Id="ServiceController"
          Name="xyz"
          Start="install"
          Stop="both"
          Remove="both"
          Wait="yes" />
      </Component>
    </ComponentGroup>
  </Fragment>
user_19240589
  • 97
  • 1
  • 14
  • Have you actually verified that it's running as ContainerAdministrator at install time? What does your Dockerfile look like? – Matt Thalman Apr 23 '21 at 12:56
  • It's just an assumption, haven't verified it. Is there a way I can do that? I'll add my dockerfile as well – user_19240589 Apr 23 '21 at 13:39
  • Have you tried building a 2019 ltsc2019 server-core VM and installing the MSI on it? – Christopher Painter Apr 23 '21 at 14:29
  • tried using both ```mcr.microsoft.com/windows/servercore:ltsc2019-amd64``` and ```mcr.microsoft.com/windows/servercore:ltsc2019``` – user_19240589 Apr 23 '21 at 14:33
  • To check what user is running, you just need to add an instruction like `RUN echo %USERNAME%` and it will output what user it is in the output of `docker build`. Based on your Dockerfile, it would be running as ContainerUser, not ContainerAdministrator. – Matt Thalman Apr 23 '21 at 21:00

3 Answers3

0

I've personally never attempted to install an MSI inside a container. The containers I've worked with (mostly linux based) the container simple would call the EXE as a console app and it's not actually a service per say. I'll assume from what you write that it's somehow possible to install an MSI inside of a windows container.

With that said, the 1920 error simply means the service didn't start. The 'verify you have admin' has always been a misnomer. To troubleshoot in windows I usually pause the installer right there and try to run the EXE manually to see if I get any errors to the console. Typically this will be a message saying .NET (Core) or some dependency isn't installed. If the EXE actually starts and you have some exception down the road then this will take additional debugging.

I'm not sure how you hijack a windows container but you'll need to do something similar to debug/profile the issue. Basically it works on one machine and not your container because your docker image doesn't have something that the other machine does have and your code doesn't like it.

Christopher Painter
  • 54,556
  • 6
  • 63
  • 100
  • The outcome is the same with exe as well and the exe/msi works perfectly fine on a different vm server and local machine. I'll try and create a service from applicaton.exe instead of installing it. My best guess is that if the application is registered manually and starts running then it has to be the wix installer code – user_19240589 Apr 23 '21 at 13:49
  • I come from a different perspective and absolutely disagree. WiX/MSI is anti self registration. If the service is doing something special when called using InstallUtil that's not a good thing in my book. Those things should be done by WiX. Also another VM server isn't the docker image so that really doesn't tell you anything. – Christopher Painter Apr 23 '21 at 13:52
  • PS- If you want to just skip MSI and WiX all together and put an InstallUtil command in your dockerfile and register it inside the image/container that's an acceptable path. MSI is more of a server / desktop technology and not really a serverless cloud native technology. – Christopher Painter Apr 23 '21 at 13:54
  • What do you mean by "anti self registration" ? also the service is not doing anything special. I am just accessing the container using ```docker run``` and then executing the msi ```ps> .\xyz.msi /q```. The service registration code is in WiX itself. I am not sure if I have made it easier to understand my setup. I'll keep in mind not to use MSI for my container and instead use exe. – user_19240589 Apr 23 '21 at 14:09
  • 1
    ServiceInstall and ServiceControl elements in WiX are fine. The problem comes if you've implemented any custom code in a ServiceInstaller class Install, Rollback or Uninstall methods. This code would be considered self registration because the service code is doing logic instead of MSI doing logic. This code only gets executed via InstallUtil. MSI doesn't execute these methods so if they are setting up any dependencies they aren't getting set up and it can be a source of problem. A common example I've seen in the past is setting up an EventLog/EventSource. This should be done in WiX. – Christopher Painter Apr 23 '21 at 14:16
  • Self registration comes in a variety of forms. I described one above but a more common one is Native DLL registration and Managed DLL RegAsm. See this link for more background: https://stackoverflow.com/questions/6129816/msi-register-dll-self-registration-considered-harmful – Christopher Painter Apr 23 '21 at 14:17
  • PS- Another trick is to install the service (ServiceInstall) but don't attempt to start it (ServiceControl). This at least gets your installed so you can run commands inside the container to troubleshoot after. I often do this when adding a new service to a product where it's code completion and quality isn't yet known. Once it's been ok a few weeks I start it in the install before shipping a product. – Christopher Painter Apr 23 '21 at 14:19
0

I would first try and find the root cause of the problem by installing the MSI with verbose logging enabled. Here you can find an example of how to do that. The logfile should give more details regarding what happened (maybe you have some failing custom actions in your installer and the infamous 'value 3' in the log file).

I would also try and modify the wxs file so that installation does not start the service (by removing ServiceControl Start="install" and replacing ServiceInstall Start="auto" with ServiceInstall Start="demand"). With this modification installation of MSI should probably succeed. Are you then able to start the xyz.exe (directly, not as a service)? If no, the problem is not in the installation, but in the executable. Are you able to start the service manually after those changes?

Robert
  • 1
  • 4
0

Although I am still investigating the behavior of .net core windows service and has started another thread here to take the SO community's view on this, it appears that the problem was with the way the service was implemented. It's a strange behavior but if I do not use Worker Template that comes with .net core 3 and instead create the service like it was done in .net core 2.1 using ServiceBase and IHostingLifetime it works fine in all the environments.

user_19240589
  • 97
  • 1
  • 14