Archive: Old topic: Deinstallation of services under NT/2K/XP/2003


Old topic: Deinstallation of services under NT/2K/XP/2003
Dear Folks -

I am stuck with my Installer Package. I need to uninstall several services within my packages.

This has to be done with the uninstaller.
--> Check if running (yes: stop), if "not" proceed with uninstall.

Can this goal be achieved within "board-functions" in the uninstaller? And if not, is there a way to make the uninstaller running *.bat-scripts? These scripts have to be *extracted* out of the uninstaller package at runtime. What I don't want is to install the scripts at installation time, and run them at uninstall-time, because if anybody deletes these scripts, the uninstaller will hang up!

Cheers and thx
Chris


I doubt it can somehow be done with just NSIS commands. Maybe its state is somewhere in the registery but I doubt it. Sunjammer's services.dll plug-in can check if a service is running and can stop it:

This plugin does things relating to Windows NT/2000/XP services. It can find out if they are installed or running, start them, stop them, etc. It can also do other useful things like grant, remove and test for the right on a user to logon as a service.
You can get it at the Archive's downloads page.

Aside from that, you can extract .bat files at uninstall time. The File command can be used there. You can execute them using Exec, ExecWait or nsExec.

It's very easy to create a plugin to remove a specific service. Alternatively I have a simple executable I once wrote which is capable of deleting any service by name or display name, but I don't generally give it out because it's very dangerous to be able to delete any service at will.

Are you sure that the service itself doesn't have a command line option to remove the service? Did you write the service?

[edit]If you need anything coded relating to services just drop me a line and I'll write it for you.[/edit]

[edit2]Actually, I'm not sure why I didn't make that plugin capable of deleting services. I think it was because I figured services should have other ways of being removed, "proper" ways. I can add that functionality if it's desired to the services plugin.[/edit2]


Lol... looks like everybody one wants to delete processes/services in a bad way :P

Bad habit, bad habit :)


@Kichik

I tried it and, well it does find these services, but there is no parameter to uninstall it....

@Sunjammer

Every of the named services has its own start/stop/install/uninstall command, but I have no idea how to combine the search for service-stop it- call uninstall -scenario. I am absolutely the worst programmer in the world, think my sister can do better (and she's fashion-designer)

So what I need is @ uninstall-time:

1.) Find "service running"
2.) stop "service if running"
3.) Uninstall "service(s)"
4.) Proceed with uninstallation

Service one has the following parameter:
-k uninstall, but where can I get the fully path back to its binary executable?

Chris


I can add a function to the services dll to get you information about the service, or you can just look under HKLM\System\CurrentControlSet\Services\ServiceName\ImagePath but you need to know the real service name, not the display name. The services plugin dll can tell you the real name from the display name.


@Sunjammer

Ok, understood!
I know the real service name. How can I read it from Registry, and than call the /stop /uninstall ?

The four (I forgot one at the last post) services are:

1.) Apache with optional parameters Apache.exe -k stop (or net STOP Apache) and Apache.exe -k uninstall
2.) Apache2 with the same parameters
3.) A FTP-Server with parameter /stop and /uninstall and
4.) MySQL with parameter mysqladmin -u root shutdown*) (or net stop mysql[/b]) and \Path\to\binary.exe --remove

*) This can't be read from registry

Thx

Joker


If you already know the real service name then you can get the path to the service executable (e.g. Apache.exe) by doing:-

StrCpy $1 "realservicename"
ReadRegStr $0 HKLM "System\CurrentControlSet\Services\$1\ImagePath"


Now in the case of Apache I noticed in my registry that the ImagePath also includes options to apache so you'll need to strip out just the path from the string you get back in $0. Note: I have not tried this, I don't have time :(.

Ohh,...
so thx for your time!

Can anybody tell me how to write the result of "Registry-reading" into a file, parsing it, to get the missing parameters written at the end of String, rename it (the written file) to *.bat, execute it and delete it afterwards?

Or more simple (as I think)
1.) At "install-time" I write a *.bat (I know how to:)) which has all the parameters in it to uninstall (at least an unmodified, original installed service).

2.) So my problem is as mentioned early in this post, to bring this file to the uninstaller!!!!

The uninstaller should content this *.bat, to extract it at uninstallation-time, call/execute it and delete it the next step.

How can this be achieved?

Chris


P.S.: So as Kichik mentioned above, but before the uninstaller is built, the files have to be modified to get the path. S**t, how should I explain:

Hmmm, I do all the file manipulation with the "search & replace" function from the Archive. So I need to have the files (*.bat) to be written at iunstallation-time and packed into the uninstaller. Otherwise at least the /uninstall function of the services will fail, not the stops as I can call them by "net stop servicename"


For the "more simple" approach :-

You could get the uninstaller to write the bat file using FileWrite in the Uninstaller part of the .nsi (icky I know but the File commands are for the installer, not the uninstaller). Then you just execute it as you would execute anything else from an .nsi, i.e. using Exec, or ExecWait, or nsExec::xxx etc.


Ok, but the uninstaller is written at compile time, not installation time, right? So I will never get the unmodified installation path!


I attached an example.nsi, which I wrote for this. Will it work? Can somebody take a look?

What I want is: Create a file, manipulate it, pack it to the uninstaller. At uninstallation time call the file, and delete the directory with the included files. As mentioned earlier, the file should never appear visible for the user, because of probably deletion. so I want to pack it with the uninstaller.

Thx
Chris


Why not just execute it without a batch file? Get the ImagePath into, lets say, $1, and then use:

ExecWait '"$1" /k uninstall'


or:

nsExec::ExecToLog '"$1" /k uninstall'

@ Kichik -

Sorry, sorry, sorry you have a really really DAU in front of you

(DAU = Dümmster anzunehmender User, means "Most stupid User you can get")
:igor:

So please be more specific

Chris


Specific enough? :p


If it works :D

Thx man, I'll give it a try and post result as soon as I tested it!

Thx again
Chris


Hey Kichik! :up:

Sensational !!! It really works great, but that's not really a surprise. Never got advice from you which didn't work :D

Thx
Chris