2010-12-29 12 views
6

Quiero comprobar mediante programación que está instalada la última versión de mi servicio de Windows. Tengo:¿Obtenga la información de la versión de un servicio instalado?

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

no se ve nada en la interfaz ServiceController que me diga el número de versión. ¿Cómo lo hago?

+0

¿Ha comprobado esto ... http: //stackoverflow.com/questions/1357268/programmatically-retrieving-assembly-version-of-a-running-service –

+0

@ Aaron - gracias, ese es un buen lugar para comenzar ! :) –

Respuesta

8

Me temo que no hay otra manera que obtener la ruta del archivo ejecutable desde el registro ya que ServiceController no proporciona esa información.

Aquí es una muestra que había creado antes:

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

Después de conseguir el camino exe, sólo tiene que utilizar FileVersionInfo.GetVersionInfo(exePath) clase para obtener la versión.

+0

+1 ¡Gracias! ¿Cómo se compara un 'FileVersionInfo' con el objeto' Version' que se obtiene de 'Assembly.GetAssembly (...). GetName(). Version'? –

+1

Eso debería darte FileVersion mientras que el que mencionaste es AssemblyVersion. Si necesita AssemblyVersion, debe cargarlo como un ensamblaje (como lo mencionó). Pero ** TENGA CUIDADO ** una vez que lo haya cargado, ha bloqueado el archivo (incluso si lo carga como ReflectionOnly) hasta que finalice su proceso. – Aliostad

+0

Tengo curiosidad por lo que está haciendo Regex aquí? Entiendo que "si el valor comienza con una cita, entonces ..." Parece que quita las comillas principales y finales, igual que value = value.Trim (new [] {'"'}); would do .. pero también está haciendo otra cosa? – ckittel

0

Si posee el servicio, puede poner la información de la versión en el DisplayName, p. DisplayName="MyService 2017.06.28.1517". Esto le permite encontrar una instalación existente de su servicio y analizar la información de la versión:

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

Esto puede ser útil si se quiere evitar el registro. El problema es que las entradas de servicio pueden ir a diferentes partes del registro dependiendo de la rutina de instalación.

Cuestiones relacionadas