WMI远程进程启动

时间:2010-04-13 07:47:25

标签: c# process wmi

方案

我编写了一个WMI Wrapper似乎已经足够了,但每当我运行代码在服务器上启动远程进程时,我看到进程名称出现在任务管理器中,但进程本身并不像它应该(因为,我没有看到进程的命令行日志窗口打印出它正在做什么等) 我试图启动的过程只是我编写的C#应用​​程序可执行文件。 下面是我的WMI包装器代码和我用来开始运行该过程的代码。

问题

这个过程真的在运行吗? - 即使它只在任务管理器中显示进程名称而不是实际将应用程序启动到用户窗口?

启动流程的代码

        IPHostEntry hostEntry = Dns.GetHostEntry("InsertServerName");
        WMIWrapper wrapper = new WMIWrapper("Insert User Name", "Insert Password",  hostEntry.HostName);
         List<Process> processes = wrapper.GetProcesses();
         foreach (Process process in processes)
         {
             if (process.Caption.Equals("MyAppName.exe"))
             {
                Console.WriteLine(process.Caption);
                Console.WriteLine(process.CommandLine);
                int processId;
                wrapper.StartProcess("E:\\MyData\\Data\\MyAppName.exe", out processId);
                Console.WriteLine(processId.ToString());
            }
        }
        Console.ReadLine();

WMI Wrapper Code

 using System;
 using System.Collections.Generic;
 using System.Management;
 using System.Runtime.InteropServices;
 using Common.WMI.Objects;
 using System.Net;

 namespace Common.WMIWrapper
 {
 public class WMIWrapper : IDisposable
 {
    #region Constructor

    /// <summary>
    /// Creates a new instance of the wrapper
    /// </summary>
    /// <param jobName="username"></param>
    /// <param jobName="password"></param>
    /// <param jobName="server"></param>
    public WMIWrapper(string server)
    {
        Initialise(server);
    }

    /// <summary>
    /// Creates a new instance of the wrapper
    /// </summary>
    /// <param jobName="username"></param>
    /// <param jobName="password"></param>
    /// <param jobName="server"></param>
    public WMIWrapper(string username, string password, string server)
    {
        Initialise(username, password, server);
    }
    #endregion

    #region Destructor
    /// <summary>
    /// Clean up unmanaged references
    /// </summary>
    ~WMIWrapper()
    {
        Dispose(false);
    }
    #endregion

    #region Initialise

    /// <summary>
    /// Initialise the WMI Connection (local machine)
    /// </summary>
    /// <param name="server"></param>
    private void Initialise(string server)
    {
        m_server = server;

        // set connection options
        m_connectOptions = new ConnectionOptions();

        IPHostEntry host = Dns.GetHostEntry(Environment.MachineName);
    }

    /// <summary>
    /// Initialise the WMI connection
    /// </summary>
    /// <param jobName="username">Username to connect to server with</param>
    /// <param jobName="password">Password to connect to server with</param>
    /// <param jobName="server">Server to connect to</param>
    private void Initialise(string username, string password, string server)
    {
        m_server = server;

        // set connection options
        m_connectOptions = new ConnectionOptions();

        IPHostEntry host = Dns.GetHostEntry(Environment.MachineName);

        if (host.HostName.Equals(server, StringComparison.OrdinalIgnoreCase))
            return;


        m_connectOptions.Username = username;
        m_connectOptions.Password = password;
        m_connectOptions.Impersonation = ImpersonationLevel.Impersonate;
        m_connectOptions.EnablePrivileges = true;            
    }

    #endregion

    /// <summary>
    /// Return a list of available wmi namespaces
    /// </summary>
    /// <returns></returns>
    public List<String> GetWMINamespaces()
    {
        ManagementScope wmiScope = new ManagementScope(String.Format("\\\\{0}\\root",  this.Server), this.ConnectionOptions);
        List<String> wmiNamespaceList = new List<String>();

        ManagementClass wmiNamespaces = new ManagementClass(wmiScope, new ManagementPath("__namespace"), null); ;

        foreach (ManagementObject ns in wmiNamespaces.GetInstances())
            wmiNamespaceList.Add(ns["Name"].ToString());

        return wmiNamespaceList;
    }

    /// <summary>
    /// Return a list of available classes in a namespace
    /// </summary>
    /// <param jobName="wmiNameSpace">Namespace to get wmi classes for</param>
    /// <returns>List of classes in the requested namespace</returns>
    public List<String> GetWMIClassList(string wmiNameSpace)
    {
        ManagementScope wmiScope = new ManagementScope(String.Format("\\\\{0}\\root\\{1}", this.Server, wmiNameSpace), this.ConnectionOptions);
        List<String> wmiClasses = new List<String>();

        ManagementObjectSearcher wmiSearcher = new ManagementObjectSearcher(wmiScope, new WqlObjectQuery("SELECT * FROM meta_Class"), null);

        foreach (ManagementClass wmiClass in wmiSearcher.Get())
            wmiClasses.Add(wmiClass["__CLASS"].ToString());

        return wmiClasses;
    }

    /// <summary>
    /// Get a list of wmi properties for the specified class
    /// </summary>
    /// <param jobName="wmiNameSpace">WMI Namespace</param>
    /// <param jobName="wmiClass">WMI Class</param>
    /// <returns>List of properties for the class</returns>
    public List<String> GetWMIClassPropertyList(string wmiNameSpace, string wmiClass)
    {
        List<String> wmiClassProperties = new List<string>();

        ManagementClass managementClass = GetWMIClass(wmiNameSpace, wmiClass);

        foreach (PropertyData property in managementClass.Properties)
            wmiClassProperties.Add(property.Name);

        return wmiClassProperties;
    }

    /// <summary>
    /// Returns a list of methods for the class
    /// </summary>
    /// <param jobName="wmiNameSpace"></param>
    /// <param jobName="wmiClass"></param>
    /// <returns></returns>
    public List<String> GetWMIClassMethodList(string wmiNameSpace, string wmiClass)
    {
        List<String> wmiClassMethods = new List<string>();


        ManagementClass managementClass = GetWMIClass(wmiNameSpace, wmiClass);

        foreach (MethodData method in managementClass.Methods)
            wmiClassMethods.Add(method.Name);

        return wmiClassMethods;
    }

    /// <summary>
    /// Retrieve the specified management class
    /// </summary>
    /// <param jobName="wmiNameSpace">Namespace of the class</param>
    /// <param jobName="wmiClass">Type of the class</param>
    /// <returns></returns>
    public ManagementClass GetWMIClass(string wmiNameSpace, string wmiClass)
    {
        ManagementScope wmiScope = new ManagementScope(String.Format("\\\\{0}\\root\\{1}", this.Server, wmiNameSpace), this.ConnectionOptions);
        ManagementClass managementClass = null;

        ManagementObjectSearcher wmiSearcher = new ManagementObjectSearcher(wmiScope, new WqlObjectQuery(String.Format("SELECT * FROM meta_Class WHERE __CLASS = '{0}'", wmiClass)), null);

        foreach (ManagementClass wmiObject in wmiSearcher.Get())
            managementClass = wmiObject;

        return managementClass;
    }

    /// <summary>
    /// Get an instance of the specficied class
    /// </summary>
    /// <param jobName="wmiNameSpace">Namespace of the classes</param>
    /// <param jobName="wmiClass">Type of the classes</param>
    /// <returns>Array of management classes</returns>
    public ManagementObject[] GetWMIClassObjects(string wmiNameSpace, string wmiClass)
    {
        ManagementScope wmiScope = new ManagementScope(String.Format("\\\\{0}\\root\\{1}", this.Server, wmiNameSpace), this.ConnectionOptions);
        List<ManagementObject> wmiClasses = new List<ManagementObject>();

        ManagementObjectSearcher wmiSearcher = new ManagementObjectSearcher(wmiScope, new WqlObjectQuery(String.Format("SELECT * FROM {0}", wmiClass)), null);

        foreach (ManagementObject wmiObject in wmiSearcher.Get())
            wmiClasses.Add(wmiObject);

        return wmiClasses.ToArray();
    }

    /// <summary>
    /// Get a full list of services
    /// </summary>
    /// <returns></returns>
    public List<Service> GetServices()
    {
        return GetService(null);
    }

    /// <summary>
    /// Get a list of services
    /// </summary>
    /// <returns></returns>
    public List<Service> GetService(string name)
    {
        ManagementObject[] services = GetWMIClassObjects("CIMV2", "WIN32_Service");
        List<Service> serviceList = new List<Service>();

        for (int i = 0; i < services.Length; i++)
        {
            ManagementObject managementObject = services[i];
            Service service = new Service(managementObject);
            service.Status = (string)managementObject["Status"];
            service.Name = (string)managementObject["Name"];
            service.DisplayName = (string)managementObject["DisplayName"];
            service.PathName = (string)managementObject["PathName"];
            service.ProcessId = (uint)managementObject["ProcessId"];
            service.Started = (bool)managementObject["Started"];
            service.StartMode = (string)managementObject["StartMode"];
            service.ServiceType = (string)managementObject["ServiceType"];
            service.InstallDate = (string)managementObject["InstallDate"];
            service.Description = (string)managementObject["Description"];
            service.Caption = (string)managementObject["Caption"];

            if (String.IsNullOrEmpty(name) || name.Equals(service.Name, StringComparison.OrdinalIgnoreCase))
                serviceList.Add(service);
        }

        return serviceList;
    }


    /// <summary>
    /// Get a list of processes
    /// </summary>
    /// <returns></returns>
    public List<Process> GetProcesses()
    {
        return GetProcess(null);
    }

    /// <summary>
    /// Get a list of processes
    /// </summary>
    /// <returns></returns>
    public List<Process> GetProcess(uint? processId)
    {
        ManagementObject[] processes = GetWMIClassObjects("CIMV2", "WIN32_Process");
        List<Process> processList = new List<Process>();

        for (int i = 0; i < processes.Length; i++)
        {
            ManagementObject managementObject = processes[i];
            Process process = new Process(managementObject);
            process.Priority = (uint)managementObject["Priority"];
            process.ProcessId = (uint)managementObject["ProcessId"];
            process.Status = (string)managementObject["Status"];

            DateTime createDate;

            if (ConvertFromWmiDate((string)managementObject["CreationDate"], out  createDate))                
                process.CreationDate = createDate.ToString("dd-MMM-yyyy HH:mm:ss");


            process.Caption = (string)managementObject["Caption"];
            process.CommandLine = (string)managementObject["CommandLine"];
            process.Description = (string)managementObject["Description"];
            process.ExecutablePath = (string)managementObject["ExecutablePath"];
            process.ExecutionState = (string)managementObject["ExecutionState"];
            process.MaximumWorkingSetSize = (UInt32?)managementObject ["MaximumWorkingSetSize"];
            process.MinimumWorkingSetSize = (UInt32?)managementObject["MinimumWorkingSetSize"];
            process.KernelModeTime = (UInt64)managementObject["KernelModeTime"];
            process.ThreadCount = (UInt32)managementObject["ThreadCount"];
            process.UserModeTime = (UInt64)managementObject["UserModeTime"];
            process.VirtualSize = (UInt64)managementObject["VirtualSize"];
            process.WorkingSetSize = (UInt64)managementObject["WorkingSetSize"];

            if (processId == null || process.ProcessId == processId.Value)
                processList.Add(process);
        }

        return processList;
    }

    /// <summary>
    /// Start the specified process
    /// </summary>
    /// <param jobName="commandLine"></param>
    /// <returns></returns>
    public bool StartProcess(string command, out int processId)
    {
        processId = int.MaxValue;

        ManagementClass processClass = GetWMIClass("CIMV2", "WIN32_Process");           

        object[] objectsIn = new object[4];
        objectsIn[0] = command;

        processClass.InvokeMethod("Create", objectsIn);

        if (objectsIn[3] == null)
            return false;

        processId = int.Parse(objectsIn[3].ToString());

        return true;
    }

    /// <summary>
    /// Schedule a process on the remote machine
    /// </summary>
    /// <param name="command"></param>
    /// <param name="scheduleTime"></param>
    /// <param name="jobName"></param>
    /// <returns></returns>
    public bool ScheduleProcess(string command, DateTime scheduleTime, out string jobName)
    {
        jobName = String.Empty;

        ManagementClass scheduleClass = GetWMIClass("CIMV2", "Win32_ScheduledJob");

        object[] objectsIn = new object[7];

        objectsIn[0] = command;

        objectsIn[1] = String.Format("********{0:00}{1:00}{2:00}.000000+060", scheduleTime.Hour, scheduleTime.Minute, scheduleTime.Second);
        objectsIn[5] = true;

        scheduleClass.InvokeMethod("Create", objectsIn);

        if (objectsIn[6] == null)
            return false;

        UInt32 scheduleid = (uint)objectsIn[6];

        jobName = scheduleid.ToString();

        return true;
    }


    /// <summary>
    /// Returns the current time on the remote server
    /// </summary>
    /// <returns></returns>
    public DateTime Now()
    {
        ManagementScope wmiScope = new ManagementScope(String.Format("\\\\{0}\\root\\{1}", this.Server, "CIMV2"), this.ConnectionOptions);
        ManagementClass managementClass = null;

        ManagementObjectSearcher wmiSearcher = new ManagementObjectSearcher(wmiScope, new WqlObjectQuery(String.Format("SELECT * FROM Win32_LocalTime")), null);

        DateTime localTime = DateTime.MinValue;

        foreach (ManagementObject time in wmiSearcher.Get())
        {
            UInt32 day = (UInt32)time["Day"];
            UInt32 month = (UInt32)time["Month"];
            UInt32 year = (UInt32)time["Year"];
            UInt32 hour = (UInt32)time["Hour"];
            UInt32 minute = (UInt32)time["Minute"];
            UInt32 second = (UInt32)time["Second"];
            localTime = new DateTime((int)year, (int)month, (int)day, (int)hour, (int)minute, (int)second);
        };



        return localTime;
    }

    /// <summary>
    /// Converts a wmi date into a proper date
    /// </summary>
    /// <param jobName="wmiDate">Wmi formatted date</param>
    /// <returns>Date time object</returns>
    private static bool ConvertFromWmiDate(string wmiDate, out DateTime properDate)
    {
        properDate = DateTime.MinValue;

        string properDateString;

        // check if string is populated
        if (String.IsNullOrEmpty(wmiDate))
            return false;

        wmiDate = wmiDate.Trim().ToLower().Replace("*", "0");

        string[] months = new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

        try
        {
            properDateString = String.Format("{0}-{1}-{2} {3}:{4}:{5}.{6}",
                wmiDate.Substring(6, 2), months[int.Parse(wmiDate.Substring(4, 2)) - 1], wmiDate.Substring(0, 4), wmiDate.Substring(8, 2), wmiDate.Substring(10, 2), wmiDate.Substring(12, 2), wmiDate.Substring(15, 6));
        }
        catch (InvalidCastException)
        {
            return false;
        }
        catch (ArgumentOutOfRangeException)
        {
            return false;
        }

        // try and parse the new date
        if (!DateTime.TryParse(properDateString, out properDate))
            return false;

        // true if conversion successful
        return true;
    }


    private bool m_disposed;

    #region IDisposable Members

    /// <summary>
    /// Managed dispose
    /// </summary>
    public void Dispose()
    {
        Dispose(true);

        GC.SuppressFinalize(this);
    }

    /// <summary>
    /// Dispose of managed and unmanaged objects
    /// </summary>
    /// <param jobName="disposing"></param>
    public void Dispose(bool disposing)
    {
        if (disposing)
        {
            m_connectOptions = null;
        }
    }
    #endregion

    #region Properties
    private ConnectionOptions m_connectOptions;

    /// <summary>
    /// Gets or sets the management scope
    /// </summary>
    private ConnectionOptions ConnectionOptions
    {
        get
        {
            return m_connectOptions;
        }
        set
        {
            m_connectOptions = value;
        }
    }

    private String m_server;

    /// <summary>
    /// Gets or sets the server to connect to
    /// </summary>
    public String Server
    {
        get
        {
            return m_server;
        }
        set
        {
            m_server = value;
        }
    }

    #endregion


}

}

1 个答案:

答案 0 :(得分:0)

它正在运行,但它没有运行交互式。如果您正在远程运行进程,则无法确定是否有人登录到该计算机,因此您无法假设它可以具有用户可以与之交互的GUI。

我建议,不要将进度写入控制台窗口,而是将其写入文件或事件日志。