Scenario
I've written a WMI Wrapper that seems to be quite sufficient, however whenever I run the code to start a remote process on a server, I see the process name appear in the task manager but the process itself does not start like it should (as in, I don't see the command line log window of the process that prints out what it's doing etc.)
The process I am trying to start is just a C# application executable that I have written.
Below is my WMI Wrapper Code and the code I am using to start running the process.
Question
Is the process actually running? - Even if it is only displaying the process name in the task manager and not actually launching the application to the users window?
Code To Start The Process
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
}
}