Получить информацию о версии установленного сервиса? - PullRequest
6 голосов
/ 29 декабря 2010

Я хочу программно проверить, установлена ​​ли последняя версия моей службы Windows. У меня есть:

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

В интерфейсе ServiceController я не вижу ничего, что сообщало бы мне номер версии. Как мне это сделать?

Ответы [ 3 ]

9 голосов
/ 29 декабря 2010

Боюсь, что нет другого способа, кроме как получить путь к исполняемому файлу из реестра, так как ServiceController не предоставляет эту информацию.

Вот пример, который я создал ранее:

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);
    }

Получив путь к exe, просто используйте класс FileVersionInfo.GetVersionInfo(exePath), чтобы получить версию.

0 голосов
/ 11 декабря 2018

Если вы говорите о том, чтобы автоматически получать текущую версию вашей службы из свойств сборки, вы можете настроить свойство, такое как ниже, в вашем классе ServiceBase.

public static string ServiceVersion { get; private set; }

Затем в вашем методе OnStart добавьте следующее ...

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

Полный пример

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));
    }
}

В приведенном выше примере мой журнал событий отображает текущую версию моей службы ... enter image description here

0 голосов
/ 28 июня 2017

Если вы являетесь владельцем сервиса, вы можете поместить информацию о версии в DisplayName, например, DisplayName="MyService 2017.06.28.1517". Это позволяет вам найти существующую установку вашего сервиса и проанализировать информацию о версии:

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

Это может быть полезно, если вы хотите избежать регистрации. Проблема заключается в том, что служебные записи могут попадать в разные части реестра в зависимости от процедуры установки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...