开发者

Get the version information of an installed service?

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

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

I don't see anything on the ServiceController interface that will tell me the version number. How do I do it?


I am afraid there is no way other than getting the executable path from the registry as ServiceController does not provide that information.

Here is a sample I had created before:

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 FileVersionInfo.GetVersionInfo(exePath) class to get the version.


If you own the service, you can put version information into the DisplayName, e.g. DisplayName="MyService 2017.06.28.1517". This allows you to find an existing installation of your service and parse the 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, e.g. check if installed version is newer than current assembly.
}

This may 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 routine.


If you are talking about getting the current version of your service automatically from the assembly properties then you can set up 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 example above my event log displays the current version of my service...

Get the version information of an installed service?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜