How can I start my service as soon as possible, before any other service?


A customer wanted to know how they could make their service start before any other service.

FIRST!

Of course, a simple application of the What if two programs did this? principle shows that this is not possible.

Upon closer questioning, the real problem was that they had a service which configured some piece of hardware, and they wanted to make sure this configuration was completed before starting the service that uses the hardware. "But we don't want to create a dependency between the two services."

Okay, so first of all, they didn't actually want to be FRIST. They merely wanted to come ahead of the other service. And the way to do that is to create a service dependency so that the other service depends on their custom service. But then they added a remark where they pre-emptively rejected the solution to their problem.

The way to control the order in which services start up is to create dependencies among them. Rejecting the correct solution only leads you down the path to creating incorrect solutions. And incorrect solutions tend to create all sorts of problems.

So do the right thing. Create the service dependency.

Comments (25)
  1. Mason Wheeler says:

    So what you do next is get them to articulate the reason why they believe the obvious solution won't work for them.  They might actually have a valid reason, or they might realize, as they think through it, that they *don't* have a valid reason and then the problem's solved.

  2. Beau Kuiper says:

    > Of course, a simple application of the What if two programs did this? principle shows that this is not possible.

    They fight to the death and the losing service is set to Disabled?

    I problem I had to solve was actually the opposite. A reconfiguration of an embedded industrial system resulted in services starting too soon, where hardware was not in a state ready to accept probing by the service. My solution was to put both services to manual, and write a new batch script that handled the startup of the services after an acceptable delay, then start up the rest of the applications that run on the embedded system.

    I figure your customer could have used the same sort of thing. Either have a program that started automatically at some time, started the first service manually, then the second.

    Of course, dependencies would have worked better.

  3. Anon says:

    @Mason Wheeler

    >Implying that they ever have a valid reason

  4. Ken in NH says:

    Since Raymond restrained himself from pushing the button on the thermonuclear device, I will: Yes there is a way to make sure that your special snowflake program is top-mostest, earliest-starting, boss of all other programs; write your own OS.

    Snide remarks aside, could their problem have been solved by writing a driver instead of a service? I guess we would need more details, but changing global values such as hardware configurations does not sound like something a sane person would do from a service. There might be other race conditions besides the dependent service. I mean services are not even guaranteed to be up and running completely before the user can start clicking around and wreaking havoc with your dependency laden code.

  5. Pazu2 says:

    Or the dependent service start configure as "Manual" and let your "first" service start it, when it thinks it is safe to. Model SQL FullText and others…

  6. David Crowell says:

    Didn't a certain printer manufacturer used to have an extra service installed as part of the driver.  It then modified the PrintSpooler to require that service.  It all worked fine, until you uninstalled the driver.  The uninstall process didn't fix the dependency, and you couldn't print anymore.

    Although this was a bug, it was very customer hostile.  USE OUR PRINTERS, OR ELSE!

  7. littlealex says:

    I can see only one way to do this 'correctly(tm)'. And "just set the dependency" is not what I am thinking about. (Because something unexpected can happen and _will happen_; the dependency should be set, but it is not enough).

    The right way is:

    When second service starts, it waits until it can successfully see that ALL requirements for it doing its work are met. Only then it actually starts working.

    No assuming the first service is already there and will always be there.

    No assuming any device will always be available, will never be removed, will never fail, power off, …

    A device is not (yet) ready? Every Software that does not expect and handle gracefully this kind of thing is bugged through and through.

    Another peace of software that is needed is not (yet) available? Every Software that does not expect and handle gracefully this kind of thing is bugged through and through.

    And for services, this is even more important. Every service at least somewhat correct-ish will just sit there and wait idly, until it can successfully do its work, and only then it will start working. And it will stop trying to do anything when the requirement is no longer met (another service crashed; a device was removed; a device failed; a network connection is no longer available; …)

    Is "handling an error that obviously will sometimes happen" really to much to ask for?

    And then, when the second service is no longer completely broken, i.e. it will just accept the first service not being there yet, then you should create a service dependency. Not because it is needed for the second service to work correctly, but because it is a very helpfull form of explicit dcoumentation, that can tell everybody including system administrators about the things you expect to be true. It gives, just as an example, a very cool message box telling the user/administrator what other services are depending on this one and will be also shut down when you shut down the first service.

  8. Adrian says:

    If Service B depends on Service A already having done some configuration step, then there's already a dependency between the services.  It's absurd to say they don't want to create a dependency.  They already have!

  9. mark says:

    Or, merge the services into one. Developers often create physical modules when all they need is a logical module (e.g. a service instead of a class).

  10. Joshua says:

    The day is coming when the reason given is the service starts the filesystem support that most of the rest of the system depends on. Think, open VPN connection and mount a disk over the VPN link.

  11. Ben Voigt says:

    Most likely they're running into deficiencies in the Windows service loader model.

    Some other OS / initscript managers are designed with two types of dependencies: "requires" and "after".  Windows doesn't (AFAIK) natively support the latter type, which is probably what they're looking for.

  12. Gabe says:

    What I don't think they understand is that "first" doesn't do what they want. It may be the case that their service is started first, but that doesn't matter. What they really care about is that their service *finishes* starting before something else.

    And of course the way to ensure that one service is not started until another service completes its startup is with the dependency mechanism.

  13. Bill_Stewart says:

    /s/FRIST/FIRST/

  14. ranta says:

    SERVICE_TRIGGER_TYPE_DEVICE_INTERFACE_ARRIVAL might be reasonable.  Have the driver of the device pop up a device interface when the first service configures it, and configure the second service to start on that trigger.  The advantage is that, after the device has already been configured, you can stop the first service without stopping the second service.

    If you have multiple devices of this type, then the second service will start as soon as the first device has been configured.  It then needs to keep watching for additional device interfaces so that it can start using those devices as well.

  15. Norm says:

    First service auto start, second manual start. First does what it needs and then starts the second.

  16. John says:

    @Bill_Stewart

    Frist time on the Internet? ;)

  17. bzakharin says:

    It's not clear whether "the service that uses the hardware" is controlled by your customer or not, or even if the set of services that rely on this service is known to the user. So it can be a legitimate question

  18. Nico says:

    Clearly, the best way to do this is to:

    1) Change all existing services start type to "Automatic (Delayed)" when you install your software.

    2) Set your #1 Best Service service set to "Automatic".

    3) Monitor the SCM's named pipes to watch for new services and also set them to Delayed.

    4) ???

    5) Profit (by getting a nice bonus for that feature!)

  19. Katie says:

    @Nico

    Bonus points if your loop doesn't actually check if they were set to manual or disabled when it changes then all.

  20. cheong00 says:

    Actually I can think of a possible reason why dependency is not desired. Their ServiceA could be a configuration detection service that will stop automatically when the job is done. If you create dependency on it, the ServiceB will stop or fail to start.

    So the correct solution to be provided should be to set ServiceA as Automatic and ServiceB as Manual. Then add code to ServiceA so that when it's job is done, it'll send start signal to service controller to start ServiceB before ServiceA stops itself. No dependency is needed.

  21. Killer{R} says:

    That another service they wanted to overtake could be some 3rd part service, and modifying configuration of 3rd party service also not very good idea.

    However specifying service load group could help, if that another service had specified group.

  22. Anon says:

    @cheong00

    And what happens when Service A fails to complete for whatever reason, then Application C starts Service B?

  23. Henke37 says:

    @anon Same as if there was a normal dependency?

  24. Dave says:

    @Mason: "So what you do next is get them to articulate the reason why they believe the obvious solution won't work for them".

    That would have been my response as well, tempered by the fact that I'm currently involved in a discussion thread where I've explicitly stated (twice) that I can't use obvious solution X because the system I'm working with doesn't have the hardware support for it.  So far I've had three replies to that, all telling me to use solution X.

    I think it's going to come down to a race between how many times I can say I CAN'T USE OBVIOUS SOLUTION X BECAUSE THE SYSTEM I'M WORKING WITH DOESN'T HAVE THE HARDWARE SUPPORT FOR IT and people losing interest after suggesting solution X over and over.

  25. cheong00 says:

    @Anon: If C is application that runs in user session, adding Scheduler Task that runs "sc start" to the ServiceB on user login should be good enough. (It does no harm trying to start a service that has already been started)

    If ServiceB is doing it's work unrelated to other piece of software, use fire a timer on ServiceA that will cause ServiceB to start after X seconds. (it'd be fine as solution to "what if there is Application C" question too)

Comments are closed.

Skip to main content