2010-12-29 14 views
6

मैं प्रोग्रामेटिक रूप से जांचना चाहता हूं कि मेरी विंडोज सेवा का नवीनतम संस्करण स्थापित है। मेरे पास है:एक स्थापित सेवा की संस्करण जानकारी प्राप्त करें?

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 उस जानकारी को प्रदान नहीं करता है।

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

+1 धन्यवाद! आप 'FileVersionInfo' से' वर्जन 'ऑब्जेक्ट की तुलना कैसे करते हैं, जिसे आप' असेंबली.गेटएस्प्लोरस (...) से वापस प्राप्त करते हैं। GetName()। संस्करण'? –

+1

आपको फ़ाइलवर्सन देना चाहिए जबकि आपने जिस व्यक्ति का उल्लेख किया है वह असेंबली वर्जन है। यदि आपको असेंबली वर्जन की आवश्यकता है, तो आपको इसे एक असेंबली के रूप में लोड करना होगा (जैसा कि आपने बताया है)। लेकिन ** सावधान ** एक बार जब आप इसे लोड कर लेंगे, तो आपने अपनी प्रक्रिया समाप्त होने तक फ़ाइल को लॉक कर दिया है (भले ही आप प्रतिबिंब के रूप में लोड हों)। – Aliostad

+0

मुझे उत्सुकता है कि रेगेक्स यहाँ क्या कर रहा है? मुझे लगता है कि "यदि मूल्य उद्धरण के साथ शुरू होता है, तो ..." ऐसा लगता है कि यह अग्रणी और पिछला उद्धरण बंद कर देता है - वैल्यू = वैल्यू के रूप में। टीआरएम (नया [] {'' '}}; करेंगे .. लेकिन यह कुछ और कर रहा है? – 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. 
} 

अगर आप रजिस्ट्री से बचना चाहते हैं उपयोगी हो सकता है: यह आप अपनी सेवा के एक मौजूदा स्थापना खोजने के लिए और संस्करण जानकारी पार्स करने के लिए अनुमति देता है। समस्या यह है कि सेवा प्रविष्टियां स्थापना दिनचर्या के आधार पर रजिस्ट्री के विभिन्न हिस्सों में जा सकती हैं।

संबंधित मुद्दे