0

I'm dealing with a circular dependency w.r.t. a Windows service and its dependence upon a driver. The situation is as follows:

I wrote a Windows service in C++. This service depends on a DLL which installs a driver the first time it is loaded/used; the DLL uses the driver during operation thenceforth.

In early testing I would install the service via a command-line call to the service executable with the /INSTALL flag -- this would call InstallService internally.

Then I ran into an issue: the service would run when I started it manually, but when it was set to run automatically after boot it would start before the driver had been loaded and it would error because of this.

To fix this, I set up a dependency for the service upon the driver -- Windows treats drivers similar to services -- in the service's registry entry @ HKLM\System\CurrentControlSet\Services\<SERVICE> in the DependOnService value. This fixed that issue.

Fast-forward to deployment: I am using WiX to install and start the service. During installation, I want to set the driver up as a dependency of my service. However, if I define the driver as a dependency in the ServiceInstall element then WiX tries to start it before starting my service, thus my problem: WiX can't start the service without starting the dependency, and the dependency isn't there because the service hasn't run yet.

If I don't specify the dependency in the installer configuration file then the service installs and runs fine.

I figured that I could define the dependency after installing the service, in the registry like before, but there's no entry for the service there!

Another thing: the service runs after boot now! Without having defined the dependency! I haven't done much testing to see if this is consistent or not.

So, how does WiX tell Windows that there's a service, i.e. why is there no registry entry? How can I specify the dependency? Do I even need to specify one anymore? Should I forego using the WiX service-related elements and run the commands I did during testing manually in the installer?

I've been wrestling with this and researching for at least a week; any insight would be appreciated.


Environment Info:

  • Development: Windows 7, 32-bit
  • Visual Studio 2010
  • WiX v3.8
  • Deployment: Windows 7, 32-bit and 64-bit -- CUSTOM, STRIPPED-DOWN IMAGES so something standard might not be present
paul
  • 1,603
  • 11
  • 22
  • I understand your problem, however what I don't understand is the part "I wrote a Windows service in C++. This service depends on a DLL which installs a driver the first time it is loaded/used; the DLL uses the driver during operation thenceforth." - sounds like a very bad design choice that's causing you many problems. Starting a service shouldn't start any installation process. Why did you do it like that? I would say get rid any installations your service does, and start using full capabilities of WiX. – Erti-Chris Eelmaa Oct 09 '14 at 20:41
  • Also WiX trying to start your dependency sounds wrong. It's not supposed to start anything. It's only supposed to install the necessary driver/DLL that your Service depends on. That's it. – Erti-Chris Eelmaa Oct 09 '14 at 20:45
  • @ChrisEelmaa Sorry that part was unclear, perhaps I can clarify: There is a `.sys` driver file packaged within the DLL. The first time the DLL is used, if that `.sys` file is not present on the system then the DLL unpacks it and writes it to disk -- it doesn't launch another installer or anything. The choice to do things this way was not mine but the authors' of the third-party DLL. I suppose I could get the `.sys` file from a system it's been installed on already and have WiX install it to the proper location; I'll have to look into this. – paul Oct 10 '14 at 12:21
  • @ChrisEelmaa I was specifying the `.sys` file as a dependency of the service using the [ServiceDependency](http://wixtoolset.org/documentation/manual/v3/xsd/wix/servicedependency.html) element within my `ServiceInstall` element. The description says: `Service or group of services that must start before the parent service.` so I was thinking that WiX was trying to start the dependency, but after re-reading that and thinking about it it must be that Windows is the one trying to start it before it would start the service. – paul Oct 10 '14 at 12:25
  • did you get any further? What you said didn't make sense. `ServiceInstall` element takes ANOTHER service(s) as input. Why would you assume that you can pass your custom DLL/sys there? You can't. The way WiX handles things: it will install everything to hard disk, and after that, start your service, on which point all the dependency issues are already resolved. You don't need to specify anything in the `ServiceInstall` element. – Erti-Chris Eelmaa Oct 13 '14 at 11:28
  • Nope, I haven't worked further on this; I started working on a different project while waiting for more feedback on this issue. From my research (and the testing/fix I mentioned above), the assertion that one cannot specify a driver (a `.sys` file) as a dependency of a service is incorrect; see [this wiki](http://en.wikipedia.org/wiki/Service_Control_Manager#Device_drivers), specifically in the Device Drivers section: `Services whose Type registry value is [elided] are handled specially: these represent device drivers... (usually a file with an extension .sys)....` – paul Oct 13 '14 at 13:04
  • @ChrisEelmaa I did some more research and thinking and found a solution. Thank you for your comments, they helped lead me to doing some fruitful research. – paul Oct 14 '14 at 14:43

1 Answers1

1

I found a solution.

Much of the issue was an RTFM problem (though to my defense the documentation wasn't all that clear):

I had been using a generic name for the value of the ServiceInstall element's Name attribute -- I was under the impression that this was used for linking the ServiceInstall element to the ServiceControl element.

The documentation for the ServiceInstall element says the following about the Name attribute:

This column is the string that gives the service name to install.

The documentation for the ServiceControl element says:

Name of the service.

The actual use for the value of the Name attribute is the hidden, system name of the service; this is the name used in the registry under HKLM\System\CurrentControlSet\Services. My service was thus being installed under the ServiceManagement key, since that's what I had in the Name attribute.

The different name is what was causing things to work dependency-wise. Apparently, barring dependencies, Windows loads services in order alphabetically (see the comments on this answer). When I was installing manually, my service had a name that came before that of the driver, so it was erroring when the dependency was not specified. The generic name I had specified in the Name attribute of the WiX project came after the driver's service name, so the driver was getting loaded before my service was.

What I ended up doing was switching the Name back to the proper name of the service then adding a RegistryValue to the WiX project to specify my service's dependency on the driver (service).

Community
  • 1
  • 1
paul
  • 1,603
  • 11
  • 22