65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 WMI 操作服务(安装、卸载、启动、暂停等)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.63/5 (15投票s)

2008年7月27日

CPOL

2分钟阅读

viewsIcon

103043

downloadIcon

4063

仅使用 WMI 即可对服务执行所有可用的操作。

引言

最近,我被要求组装一个类,用于处理许多 Windows 服务操作。 在 Google 上花费了数小时寻找帮助后,我得到的只是一些非常复杂的 API,仅仅是编写它们的声明就如此繁琐,以至于我立即放弃了该解决方案。

另一种解决方案是使用 Visual Studio 安装和部署向导(非常浪费),或者使用 InstallUtil(.NET Framework 附带),或者使用 sc.exe(这很好,但仍然是外部的)。

最后,我决定使用 WMI,它是 Windows Management Instrumentation 的缩写。 这些类提供对许多 Windows 管理设备的访问,包括服务。 唯一的缺点是它主要为 VBScript 设计,因此我必须进行一些更改才能使其适应此处。

一般信息

WMI 包括一个名为 Win32_Service 的类(有关此类的更多信息可以在这里找到:MSDN)。 在我的类中,我必须将其用于两个对象:服务管理器和服务本身。 服务管理器的使用主要用于安装服务(因为我们需要在其中创建一个新服务); 在那之后(当服务安装完成后),我将使用服务本身。

第一部分:安装服务

假设你遇到了和我一样的问题——你有一个 exe 文件(它是服务),并且你想安装它。 你的选择是

  1. 创建一个安装项目(Visual Studio)——我认为这太多了。
  2. 使用 InstallUtil.exe – 外部程序。
  3. 使用 sc.exe – 比 InstallUtil 更好(至少我是这么认为的),但同样 – 外部程序。

所以这里是另一种更好的方法,使用 WMI

public static ReturnValue InstallService(string svcName, string svcDispName,
       string svcPath, ServiceType svcType, 
       OnError errHandle, StartMode svcStartMode,
       bool interactWithDesktop, string svcStartName, string svcPassword,
       string loadOrderGroup, string[] loadOrderGroupDependencies, 
       string[] svcDependencies) 
{ 
    ManagementClass mc = new ManagementClass("Win32_Service"); 
    ManagementBaseObject inParams = mc.GetMethodParameters("create"); 
    inParams["Name"] = svcName; 
    inParams["DisplayName"] = svcDispName; 
    inParams["PathName"] = svcPath; 
    inParams["ServiceType"] = svcType; 
    inParams["ErrorControl"] = errHandle; 
    inParams["StartMode"] = svcStartMode.ToString(); 
    inParams["DesktopInteract"] = interactWithDesktop; 
    inParams["StartName"] = svcStartName; 
    inParams["StartPassword"] = svcPassword; 
    inParams["LoadOrderGroup"] = loadOrderGroup; 
    inParams["LoadOrderGroupDependencies"] = loadOrderGroupDependencies; 
    inParams["ServiceDependencies"] = svcDependencies; 
    try 
    { 
        ManagementBaseObject outParams = mc.InvokeMethod("create", inParams, null); 
        return (ReturnValue)Enum.Parse(typeof(ReturnValue),
        outParams["ReturnValue"].ToString()); 
    } 
    catch (Exception ex) 
    { throw ex; } 
}

在这里,我们使用 Win32_Service 将一个新服务添加到服务管理器中。(所有枚举都在代码中声明,我不想让这篇文章太臃肿。)

第二部分:对服务执行所有其他操作

所以,是的,我们只在想要安装新服务(或遍历所有服务)时才使用服务管理器,但是现在,我们希望对我们的服务进行各种操作。 在这里,我们将使用这一行代码,它最终将为我们提供对服务的控制权

string objPath = string.Format("Win32_Service.Name='{0}'", svcName);
using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
{…}
...

在这里,“service”保存了我们服务的实例,现在,我们所要做的就是调用此实例上的方法(您可以在上面的 URL 中找到所有方法)。

public static ReturnValue UninstallService(string svcName)
{
    string objPath = string.Format("Win32_Service.Name='{0}'", svcName);
    using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
    {
        try
        {
            ManagementBaseObject outParams = service.InvokeMethod("delete", null,  null);
            return (ReturnValue)Enum.Parse(typeof(ReturnValue),
            outParams["ReturnValue"].ToString());
        }
        catch (Exception ex)
        {
            if (ex.Message.ToLower().Trim() == "not found" || ex.GetHashCode() == 41149443)
                return ReturnValue.ServiceNotFound;
            else
                throw ex;
        }
    }
}

public static ReturnValue StartService(string svcName)
{
    string objPath = string.Format("Win32_Service.Name='{0}'", svcName);
    using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
    {
        try
        {
            ManagementBaseObject outParams = service.InvokeMethod("StartService",
                null, null);
            return (ReturnValue)Enum.Parse(typeof(ReturnValue),
            outParams["ReturnValue"].ToString());
        }
        catch (Exception ex)
        {
            if (ex.Message.ToLower().Trim() == "not found" || ex.GetHashCode() == 41149443)
                return ReturnValue.ServiceNotFound;
            else
                throw ex;
        }
    }
}

public static ReturnValue StopService(string svcName)
{
    string objPath = string.Format("Win32_Service.Name='{0}'", svcName);
    using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
    {
        try
        {
            ManagementBaseObject outParams = service.InvokeMethod("StopService",
                null, null);
            return (ReturnValue)Enum.Parse(typeof(ReturnValue),
            outParams["ReturnValue"].ToString());
        }
        catch (Exception ex)
        {
            if (ex.Message.ToLower().Trim() == "not found" || ex.GetHashCode() == 41149443)
                return ReturnValue.ServiceNotFound;
            else
                throw ex;
        }
    }
}

public static ReturnValue ResumeService(string svcName)
{
    string objPath = string.Format("Win32_Service.Name='{0}'", svcName);
    using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
    {
        try
        {
            ManagementBaseObject outParams = service.InvokeMethod("ResumeService",
                null, null);
            return (ReturnValue)Enum.Parse(typeof(ReturnValue),
                outParams["ReturnValue"].ToString());
        }
        catch (Exception ex)
        {
            if (ex.Message.ToLower().Trim() == "not found" || ex.GetHashCode() == 41149443)
                return ReturnValue.ServiceNotFound;
            else
                throw ex;
        }
    }
}

public static ReturnValue PauseService(string svcName)
{
    string objPath = string.Format("Win32_Service.Name='{0}'", svcName);
    using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
    {
        try
        {
            ManagementBaseObject outParams = service.InvokeMethod("PauseService",
                null, null);
            return (ReturnValue)Enum.Parse(typeof(ReturnValue),
                outParams["ReturnValue"].ToString());
        }
        catch (Exception ex)
        {
            if (ex.Message.ToLower().Trim() == "not found" || ex.GetHashCode() == 41149443)
                return ReturnValue.ServiceNotFound;
            else
                throw ex;
        }
    }
}

public static ReturnValue ChangeStartMode(string svcName, StartMode startMode)
{
    string objPath = string.Format("Win32_Service.Name='{0}'", svcName);
    using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
    {
        ManagementBaseObject inParams = service.GetMethodParameters("ChangeStartMode");
        inParams["StartMode"] = startMode.ToString();
        try
        {
            ManagementBaseObject outParams = service.InvokeMethod("ChangeStartMode",
                inParams, null);
            return (ReturnValue)Enum.Parse(typeof(ReturnValue),
                outParams["ReturnValue"].ToString());
        }
        catch (Exception ex)
        { throw ex; }
    }
}

public static bool IsServiceInstalled(string svcName)
{
    string objPath = string.Format("Win32_Service.Name='{0}'", svcName);
    using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
    {
        try
        {
            ManagementBaseObject outParams = service.InvokeMethod("InterrogateService",
                null, null);
            return true;
        }
        catch (Exception ex)
        {
            if (ex.Message.ToLower().Trim() == "not found" || ex.GetHashCode() == 41149443)
                return false;
            else
                throw ex;
        }    
    }
}

public static ServiceState GetServiceState(string svcName)
{
    ServiceState toReturn = ServiceState.Stopped;
    string _state = string.Empty;
    string objPath = string.Format("Win32_Service.Name='{0}'", svcName);
    using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
    {
        try
        {
            _state = service.Properties["State"].Value.ToString().Trim();
            switch (_state)
            {
            case "Running":
                toReturn = ServiceState.Running;
                break;
            case "Stopped":
                toReturn = ServiceState.Stopped;
                break;
            case "Paused":
                toReturn = ServiceState.Paused;
                break;
            case "Start Pending":
                toReturn = ServiceState.StartPending;
                break;
            case "Stop Pending":
                toReturn = ServiceState.StopPending;
                break;
            case "Continue Pending":
                toReturn = ServiceState.ContinuePending;
                break;
            case "Pause Pending":
                toReturn = ServiceState.PausePending;
                break;
            }
        }
        catch (Exception ex)
        { throw ex; }
    }
    return toReturn;
}

public static bool CanStop(string svcName)
{
    string objPath = string.Format("Win32_Service.Name='{0}'", svcName);
    using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
    {
        try
        {
            return bool.Parse(service.Properties["AcceptStop"].Value.ToString());
        }
        catch
        {
            return false;
        }
    }
}

public static bool CanPauseAndContinue(string svcName)
{
    string objPath = string.Format("Win32_Service.Name='{0}'", svcName);
    using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
    {
        try
        {
            return bool.Parse(service.Properties["AcceptPause"].Value.ToString());
        }
        catch
        {
            return false;
        }
    }
}

public static int GetProcessId(string svcName)
{
    string objPath = string.Format("Win32_Service.Name='{0}'", svcName);
    using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
    {
        try
        {
            return int.Parse(service.Properties["ProcessId"].Value.ToString());
        }
        catch
        {
            return 0;
        }
    }
}

public static string GetPath(string svcName)
{
    string objPath = string.Format("Win32_Service.Name='{0}'", svcName);
    using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
    {
        try
        {
            return service.Properties["PathName"].Value.ToString();
        }
        catch
        {
            return string.Empty;
        }
    }
}

结论

嗯,这一切有点混乱,但如果你仔细观察 - 所有这些都非常相似的模板......只需获取对象,然后对其执行任何你想要的操作。

您可以使用以下方式找到许多对象的属性

foreach (PropertyData pd in service.Properties)
  if (pd.Value!= null)
    MessageBox.Show(pd.Name + " = " + pd.Value.ToString());

我希望这篇文章对你们很多人都有用。 我认为这是第一个使用 WMI 处理服务的迷你综合指南。

欢迎任何评论。 感谢您的阅读。

© . All rights reserved.