Get version information of the installed service?

I want to programmatically check if the latest version of my Windows service is installed. I have:

var ctl = ServiceController.GetServices().Where(s => s.ServiceName == "MyService").FirstOrDefault(); if (ctl != null) { // now what? } 

I don’t see anything in the ServiceController interface, which will tell me the version number. How to do it?

+6
c # windows-services
source share
3 answers

I am afraid that there is no way to get the executable path from the registry, because ServiceController does not provide this information.

Here is an example I created earlier:

 private static string GetExecutablePathForService(string serviceName, RegistryView registryView, bool throwErrorIfNonExisting) { string registryPath = @"SYSTEM\CurrentControlSet\Services\" + serviceName; RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView).OpenSubKey(registryPath); if(key==null) { if (throwErrorIfNonExisting) throw new ArgumentException("Non-existent service: " + serviceName, "serviceName"); else return null; } string value = key.GetValue("ImagePath").ToString(); key.Close(); if(value.StartsWith("\"")) { value = Regex.Match(value, "\"([^\"]+)\"").Groups[1].Value; } return Environment.ExpandEnvironmentVariables(value); } 

After getting the exe path, just use the FileVersionInfo.GetVersionInfo(exePath) class to get the version.

+8
source share

If you own the service, you can put version information in DisplayName , for example. DisplayName="MyService 2017.06.28.1517" . This allows you to find an existing installation of your service and analyze version information:

 var ctl = ServiceController .GetServices() .FirstOrDefault(s => s.ServiceName == "MyService"); if (ctl != null) { // get version substring, you might have your own style. string substr = s.DisplayName.SubString("MyService".Length); Version installedVersion = new Version(substr); // do stuff, eg check if installed version is newer than current assembly. } 

This can be useful if you want to avoid the registry. The problem is that service entries can go to different parts of the registry depending on the installation procedure.

0
source share

If you are talking about getting the current version of your service automatically from the assembly properties, then you can configure a property, such as below, in your ServiceBase class.

 public static string ServiceVersion { get; private set; } 

Then in your OnStart method add the following ...

 ServiceVersion = typeof(Program).Assembly.GetName().Version.ToString(); 

Full example

 using System.Diagnostics; using System.ServiceProcess; public partial class VaultServerUtilities : ServiceBase { public static string ServiceVersion { get; private set; } public VaultServerUtilities() { InitializeComponent(); VSUEventLog = new EventLog(); if (!EventLog.SourceExists("Vault Server Utilities")) { EventLog.CreateEventSource("Vault Server Utilities", "Service Log"); } VSUEventLog.Source = "Vault Server Utilities"; VSUEventLog.Log = "Service Log"; } protected override void OnStart(string[] args) { ServiceVersion = typeof(Program).Assembly.GetName().Version.ToString(); VSUEventLog.WriteEntry(string.Format("Vault Server Utilities v{0} has started successfully.", ServiceVersion)); } protected override void OnStop() { VSUEventLog.WriteEntry(string.Format("Vault Server Utilities v{0} has be shutdown.", ServiceVersion)); } } 

In the above example, my event log displays the current version of my service ... enter image description here

0
source share

All Articles