我想以编程方式检查是否安装了最新版本的Windows服务。我有:
var ctl = ServiceController.GetServices().Where(s => s.ServiceName == "MyService").FirstOrDefault();
if (ctl != null) {
// now what?
}
我在ServiceController
界面上看不到会告诉我版本号的任何内容。我该怎么做?
答案 0 :(得分: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)
类来获取版本。
答案 1 :(得分: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.
}
如果您想避免使用注册表,这可能很有用。问题是,服务条目可以根据安装例程转到注册表的不同部分。
答案 2 :(得分:0)
如果您要谈论的是从程序集属性中自动获取服务的当前版本,则可以在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));
}
}