Get the version information of an installed service?

旧时模样 提交于 2019-12-07 02:10:44

问题


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").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?


回答1:


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.




回答2:


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.




回答3:


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...



来源:https://stackoverflow.com/questions/4555350/get-the-version-information-of-an-installed-service

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!