Wednesday, December 21, 2005

Installshield and services

Well this one cost me 7 hours. After figuring it out, I’m amazed it took me more than 10 minutes but it’s a sneaky one.

Installshield has a host of functions for windows service control. ServiceStartService, ServiceStopService, ServiceAddService, ServiceRemoveService are the more common ones. I was attempting to write an installer that would be doing an upgrade of a product that had a windows service. The task seemed simple…Stop the service, remove the service, uninstall the old product, install the new product, install the new service, start the new service? It looked pretty simple as a state diagram on a scrap piece of paper too.

The problem:
Eventhough the service stopped succesfully, it wouldn’t remove successfully. I kept getting a 1072 error which means “The stated service has been marked for deletion.” This prevented my new service from getting installed properly since they have the same name. So when does this service actually get deleted? The moment you close Installshield. This means that i’d have to basically quit the installer and then start it up again at a different state. Hacky!

The solution:
DO NOT USE ServiceStopService! Stop the service the old fashion way with “net stop myService”. Here’s a code snippet:

LaunchAppAndWait(WINDIR ^ "system32" ^ "net.exe", "stop myService", LAAW_OPTION_WAIT|LAAW_OPTION_HIDE);

Also, the same issue applies to ServiceRemoveService. You should use sc.exe instead which should be standard. It’s in Windows/System32.

LaunchAppAndWait(WINDIR ^ "system32" ^ "sc.exe", "delete myService", LAAW_OPTION_WAIT|LAAW_OPTION_HIDE);

The cause:
This is 100% speculation on my part as i have been unable to find any confirmation of my reasoning but here goes. ServiceStopService does work…the service is successfully stopped however the means through which it stops the service acquires a handle to the service that belongs to the Installshield application. Services reference count open handles to themselves so that they don’t get removed during usage. So when you stop the service, you open a handle that doesn’t get closed until you quit the application. By using “net stop” no handle is acquired. It’s an old fashion DOS command.

Sounds like Installshield needs a disclaimer on their function documentation for this.

1 comment:

  1. Thank you very much for the post.

    I had the same problem and finally had to follow this advice to get working the upgrade.