API Search for SC.exe Utility and Windows Service Self-Update Recommendations

We created a Windows service that runs on client computers, which downloads a newer version from time to time, and then performs a self-update: installs a new service, starts it, stops the old one and ultimately deletes it, the Service cannot stop itself and do others things, so it twists another executable file that does some work. getting this right is difficult, and it's especially bad when a new service is built using the newer .NET Framework (such as the recent switch from .Net 2.0 to .net 4.0). The problem is that the .NET 2.0 library cannot work with the .Net 4.0 service.

Now, one approach would be for the older version of the service to run a helper program that comes with the newer version, but ... what if this user’s behavior needs to be changed by a break? I feel more confident not to mix versions, even if some things usually stay the same - it helps reduce design complexity.

Now, apparently, there is a neutral version of .NET for working in Windows services: sc.exe tool: http://support.microsoft.com/kb/251192

I wonder if this is really the silver bullet I was looking for. Now, because I will call this guy programmatically and check for errors, then I could also use the API for this. Ideally, I would have one native C ++ project that compiles into native exe that interacts with SC.exe. Is it possible? If not, how can I find the localization of sc.exe on different computers? They can be 32-bit or 64-bit and run any version of Windows, starting with Windows XP SP2 / 3.

Let me know if you have questions about my question or any brilliant idea or answer to the exact question I asked here.


Edit: if I try to install service 4.0 using 2.0 code, I get the same error as me:

 > C:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe MyService4.exe 

Microsoft (R) .NET Framework Installation Version Version 2.0.50727.4927 Copyright (c) Microsoft Corporation. All rights reserved.

An exception occurred during initialization of the installation: System.BadImageFormatException: it is possible not to load the file or assembly 'file: /// [path] \ MyService4.exe' or one of its dependencies. This assembly is built at runtime, but the runtime is currently loaded and cannot be loaded ..

+4
source share
4 answers

Your own C ++ application can call the functions described here: http://msdn.microsoft.com/en-us/library/ms685942(v=VS.85).aspx (the SCM API others mentioned)

You need to do something in the lines

 OpenSCManager OpenService (or CreateService) ChangeServiceConfig CloseServiceHandle 
+1
source

I'm not sure what you mean by this:

The problem is that the .NET 2.0 library cannot work with the .Net 4.0 service.

The ServiceController class is able to control any service, even the native one. I have not tried, but I believe that the ServiceInstaller class can be used to (un) install any service.

If ServiceController and ServiceInstaller do not meet your needs, I would recommend wrapping your own API directly, rather than sc.exe . MSDN docs should get you started; You will need the features of Service Control Manager. The sc.exe program is just a thin shell of the command line around the SCM API.

+1
source

The service pack includes an executable file with a name that does not change between versions, for example. Setup.exe: -)

This tool then performs all the settings at startup as a new process using the update logic. It must be compiled using the same version of the Framework as the rest of the package to avoid problems with CLR versions.

The biggest problem I encountered with the existing ServiceInstaller class is the lack of support for new service features, such as description and failure / recovery actions. To get around this, I changed the Narendra (Neil) Baliga code from CodeProject and used the ServiceInstallerEx class ServiceInstallerEx . Its code includes the required p-invoke definitions to invoke the same Windows APIs as SC.exe .

Partly: if your upgrade requirements are similar to those I used earlier, I would recommend installing them side by side folders (whose names include version / release number) and keeping the last 2 or 3 to ensure rollback. Pass the path of the current version to the configuration tool so that it knows the current state of the game.

+1
source

sc.exe is actually always on the same path:% windir% \ System32 \ sc.exe (x64 uses System32 for 64-bit binaries :-). I don’t know what your current installation looks like, but if you have or can switch to MSI, it can launch its own installation action, which can be your new .exe with a configuration file that is built for the SCM API or just runs sc. exe 2-3 times make a stop, configure, start. Technically, you can even use .cmd as a custom installation action in MSI, but it may seem a little ugly (the user sees the cmd window).

If you want to switch to the SCM API and know your C ++, this is definitely the best way to go - not a single layer between them should spoil anything. In addition, as soon as you have a separate binary task for installation, you are not bound by the built-in .NET installation procedure - you can contact the same NT API with C # and C ++. The key is that the binary that executes the administrator’s tasks to stop, start, configure, etc., must be different from the binary for the service itself . This .NET problem is linked.

Since you make the main switch, if your previous installation is not under MSI, then the new MSI will not be able to process anything, so you can literally drop the .cmd file to just stop and clear the old service with sc.exe, just in order to start cleaning, and then run the new installation binary - whatever that is. MSI will stop and disable the window service, but only if it was previously installed by MSI. It's kind of sticky :-)

+1
source

All Articles