- The ServerController class can run a command or schedule task on either local or remoter server
using System;
using System.Collections.Generic;
using System.Text;
using System.Management;
using System.Diagnostics;
namespace CIDS_RollupCostTesting
{
/// <summary>
/// The ServerController class can run a command or schedule task on either local or remoter server
/// </summary>
public class ServerController
{
private ManagementPath mPath;
private ManagementScope mScope;
private ServerController()
{ }
private ServerController(
string serverName,
string domain,
string userName,
string passWord
)
{
// set up scope
ConnectionOptions connection = new ConnectionOptions();
connection.Username = userName;
if (passWord != string.Empty)
connection.Password = passWord;
connection.Authority = string .Format("ntdlmdomain:{0}" , domain);
mScope = new ManagementScope( string.Format("\\\\{0}\\root\\CIMV2 ", serverName));
}
public static ServerController Instance(
string serverName,
string domain,
string userName,
string passWord)
{
if (serverName == string.Empty)
{
serverName = "." ;
}
if (domain == string.Empty)
{
domain = System.Environment.UserDomainName;
}
if (userName == string.Empty)
{
userName = Environment.UserName;
}
return new ServerController(
serverName,
domain,
userName,
passWord);
}
private string commandString;
public string CommandString
{
set { commandString = value; }
}
public static ServerController Instance()
{
return ServerController.Instance( string.Empty, string.Empty, string.Empty, string.Empty);
}
public bool ExecuteScheduleTask(string taskName)
{
return ExecuteCommand(string .Format("schtasks /Run /TN \" {0}\"", taskName));
}
public bool ExecuteCommand( string commandString)
{
try
{
// Get the object on which the method
// will be invoked
mPath = new ManagementPath("Win32_Process ");
ObjectGetOptions options = new ObjectGetOptions();
ManagementClass processClass =
new ManagementClass(mScope, mPath, options);
// Create a results and completion handler
ManagementOperationObserver handler =
new ManagementOperationObserver();
handler.Completed +=
new CompletedEventHandler(Completed);
// Invoke method asynchronously
ManagementBaseObject inParams = processClass.GetMethodParameters(" Create");
inParams["CommandLine "] = commandString;
processClass.InvokeMethod(
handler, "Create" , inParams, null);
// Do something while method is executing
Process commandProcess = null;
int id = GetCommandProcessID();
// check if it is complete?
if (id == int.MaxValue)
Console.WriteLine ("The command process has not started!");
else
{
Console.WriteLine(" The command process id is {0}.",id);
commandProcess = Process.GetProcessById(id);
}
while (!isComplete || (commandProcess != null && !commandProcess.HasExited))
{
Sleep(10 );
}
return true ;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
//throw ex;
return false;
}
}
/// <summary>
/// This method has thread safty
/// </summary>
public void ExecuteCommand()
{
lock ( this)
{
if (commandString == null)
throw new Exception("Please specify your command first! ");
ExecuteCommand(commandString);
}
}
/// <summary>
/// start running schedule task picked up
/// </summary>
/// <param name="schTaskName"> the schedule task exe</param>
/// <param name="Args">arguments used to set how to run the process </param>
/// <returns></returns>
public static string RunSchTask( string args)
{
const string schTaskExe = " schtasks";
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.FileName = schTaskExe;
process.StartInfo.Arguments = args;
process.StartInfo.CreateNoWindow = true;
process.Start();
string subID = process.StandardOutput.ReadToEnd();
process.WaitForExit();
//string subID = process.StandardOutput.ReadToEnd();
process.Close();
return subID;
}
private bool isComplete = false;
private void Completed(object sender,
CompletedEventArgs e)
{
isComplete = true;
}
const string CmdProcessName = "cmd";
private int tryTimes = 4;
/// <summary>
/// The try times to get the command process id and then wait until the command process exists
/// </summary>
public int TryTimes
{
get { return tryTimes; }
set { tryTimes = value; }
}
private int GetCommandProcessID()
{
int id = int.MaxValue;
// get the process ID
// wait the process to start
// try three times
Process[] cmdProcs = null ;
int index = 0;
while (index < tryTimes)
{
cmdProcs = Process.GetProcessesByName(CmdProcessName);
if (cmdProcs.Length > 0 )
break;
else
Sleep(5);
}
// Consume the newest command process is the created one
DateTime newest = DateTime.MinValue;
// On Windows server, the command process should be in the same session as the current process
int sessionID = Process.GetCurrentProcess().SessionId;
foreach (Process p in cmdProcs)
{
if (p.StartTime.CompareTo(newest) > 0 && p.SessionId == sessionID)
{
newest = p.StartTime;
id = p.Id;
}
}
return id;
}
/// <summary>
/// This method is not used
/// </summary>
/// <returns></returns>
private bool ClearCommandProcesses()
{
try
{
Process[] cmdProcs = Process.GetProcessesByName(CmdProcessName);
foreach (Process p in cmdProcs)
{
p.Kill();
}
return true;
}
catch (Exception ex)
{
throw ex;
}
}
private void Sleep( int seconds)
{
System.Threading.Thread.Sleep(new TimeSpan(0 , 0, seconds));
}
}
} - Use thread
ServerController server = ServerController.Instance();
server.CommandString = commandString;
// new thread
Thread td = new Thread(new ThreadStart(server.ExecuteCommand));
// start thread
td.Start();
// wait
td.Join(new TimeSpan(0 , 30, 0));
--
Happy day, happy life!
No comments:
Post a Comment