Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read standard output from a command run via Process.Start() as a list or array

Tags:

c#

I need to get a list of all the scheduled tasks running on a certain host into a list or array in C#.

The query

schtasks /query /S CHESTNUT105B /FO List

returns a list like this:

HostName:      CHESTNUT105B
TaskName:      Calculator
Next Run Time: 12:00:00, 10/28/2010
Status:        Running

HostName:      CHESTNUT105B
TaskName:      GoogleUpdateTaskMachineCore
Next Run Time: At logon time
Status:

HostName:      CHESTNUT105B
TaskName:      GoogleUpdateTaskMachineCore
Next Run Time: 13:02:00, 10/28/2010

I have the following code to execute the command I specified above:

static void Main(string[] args)
{
    Process p = new Process();
    p.StartInfo.UseShellExecute = false;
    p.StartInfo.FileName = "SCHTASKS.exe";
    p.StartInfo.RedirectStandardError = true;
    p.StartInfo.RedirectStandardOutput = true;
    p.StartInfo.CreateNoWindow = true;
    p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;


    string MachineName = "CHESTNUT105b";
    string ScheduledTaskName = "Calculator";
    string activeDirectoryDomainName = "xxx";
    string userName = "xxx";
    string password = "xxxxx";

    p.StartInfo.Arguments = String.Format("/Query /S {0} /FO LIST", MachineName);

    p.Start();
}

How can I read the list generated into a list in C#?

like image 849
xbonez Avatar asked Oct 14 '22 22:10

xbonez


2 Answers

Something like this should work (untested). This will have each line of output in an element of the List.

class GetSchTasks {

    List<string> output = new List<string>();

    public void Run()
    {
        Process p = new Process();
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.FileName = "SCHTASKS.exe";
        p.StartInfo.RedirectStandardError = true;
        p.StartInfo.RedirectStandardOutput = true;
        p.StartInfo.CreateNoWindow = true;
        p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;


        string MachineName = "CHESTNUT105b";
        string ScheduledTaskName = "Calculator";
        string activeDirectoryDomainName = "xxx";
        string userName = "xxx";
        string password = "xxxxx";

        p.StartInfo.Arguments = String.Format("/Query /S {0} /FO LIST", MachineName);

        p.Start();
        p.BeginOutputReadLine();
        p.BeginErrorReadLine();
        p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
        p.ErrorDataReceived += new DataReceivedEventHandler(p_ErrorDataReceived);
        p.WaitForExit();
        p.Close();
        p.Dispose();

    }

    void p_ErrorDataReceived(object sender, DataReceivedEventArgs e)
    {
        //Handle errors here
    }

    void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        output.Add(e.Data);
    }

}

Now, you can interpret that list afterwards to build a suitable set of objects representing each a Scheduled Task, or not, depending the actual use case. You could also build a list of ScheduledTasks objects in the p_OutputDataReceived handler itself, just comparing each line against the expected beginnings, for example, if (e.Data.StartsWith("HostName:") ) { //parse the line and grab the host name }

like image 159
Vinko Vrsalovic Avatar answered Nov 01 '22 14:11

Vinko Vrsalovic


Part of this question can be answered by this previous question - "C# How To Read Console Output With Parameters"

After retrieving the console output into a StreamReader as suggested in that question, then you just have to parse the console output into individual scheduled tasks, and then into an object that stores each piece of data you are interested in.

To break into individual tasks, it looks like you can just use: str.split("\n\n") - this will give you each task as a separate string, so loop over this array, and create a class that reads the string and populates its values by parsing the data.

like image 20
davisoa Avatar answered Nov 01 '22 13:11

davisoa