2010-12-29 2 views
6

私のWindowsサービスの最新バージョンがインストールされていることをプログラムでチェックしたいと思います。私は持っています:インストールされているサービスのバージョン情報を取得しますか?

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

バージョン番号を教えてくれるServiceControllerインターフェイスには何も表示されません。どうすればいいのですか?

+0

これをチェックしましたか?http://stackoverflow.com/questions/1357268/programmatically-retrieving-assembly-version-of-a-running-service –

+0

@Aaron - これは良いスタート地点です! :) –

答えて

8

ServiceControllerはその情報を提供しないため、レジストリから実行可能なパスを取得する以外の方法はありません。ちょうどバージョンを取得するFileVersionInfo.GetVersionInfo(exePath)クラスを使用し、exeファイルのパスを取得した後

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

:ここ

は、私が前に作成したサンプルです。

+0

+1ありがとう! 'FileVersionInfo'と' Assembly.GetAssembly(...)。GetName()。Version'から戻ってきた 'Version'オブジェクトをどのように比較しますか? –

+1

これは、あなたが言及したものがAssemblyVersionである間、あなたにFileVersionを与えるはずです。 AssemblyVersionが必要な場合は、(前述のように)アセンブリとしてロードする必要があります。しかし、** BEWARE **一度読み込んだら、プロセスが終了するまで(ReflectionOnlyとして読み込んでも)ファイルをロックしています。 – Aliostad

+0

私はここで正規表現が何をやっているのだろうか?私はそれが "値が引用符で始まるならば..."と解釈します。これは、先行する引用符と後続引用符を取り除くように見えます - value = value.Trim(new [] {'"'});と同じです;しかし、何か他のこともしていますか? – ckittel

0

サービスをご利用の場合は、バージョン情報を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. 
} 

これは、レジストリを避けたい場合に役立ちます。問題は、サービスエントリがインストールルーチンによってレジストリの異なる部分に移動できることです。

関連する問題