Jon K
Jon K

Reputation:

Help needed to get Process ID for PsExec.exe in C#?

I am using the below code to invoke PsExec.exe which invokes my console application in two servers, I am not able to grab the ProcessId of the invoked processes (my console apps).

process.StandardOutput.ReadToEnd()); is only giving me the servernames but not the complete content.

Can you please help me to get the process id's generated by PsExec.exe on the remote servers ??

        Process process = new Process();
        ProcessStartInfo psi = new ProcessStartInfo(@"PsExec.exe");
        psi.UseShellExecute = false;
        psi.RedirectStandardOutput = true;
        psi.RedirectStandardError = true;
        psi.RedirectStandardInput = true;
        psi.WindowStyle = ProcessWindowStyle.Minimized;
        psi.CreateNoWindow = true;
        psi.Arguments = @"-i -u Username -p xxxxxx \\server1,server2 C:\data\GridWorker\GridWorker.exe 100000";
        process.StartInfo = psi;
        process.Start();

        Console.WriteLine(process.StandardOutput.ReadToEnd());

Upvotes: 6

Views: 6144

Answers (3)

mabra
mabra

Reputation: 383

So far I understodd the original question, the task was to get the PID of the remoetely started processes on the remote machines. Is this true? In this case, none of the answers are really helpful.

You must create WMI queries for each of you remote computers, to fetch the started processes. This can be done using the "Win32_ProcessStartTrace" classes.

If you need more help, let me know.

br--mabra

Upvotes: 0

Yannick Motton
Yannick Motton

Reputation: 36031

Try adding the -d parameter to the PsExec commandline.

Don't wait for application to terminate. Only use this option for non-interactive applications.

This should correctly return the Process ID to StandardError.

The example:

ProcessStartInfo psi = new ProcessStartInfo(
    @"PsExec.exe",
    @"-d -i -u user -p password \\server C:\WINDOWS\system32\mspaint.exe")
                           {
                               UseShellExecute = false,
                               RedirectStandardOutput = true,
                               RedirectStandardError = true,
                               RedirectStandardInput = true,
                               WindowStyle = ProcessWindowStyle.Minimized,
                               CreateNoWindow = true
                           };
Process process = Process.Start(psi);

Console.WriteLine(process.StandardError.ReadToEnd());

Output:

PsExec v1.94 - Execute processes remotely
Copyright (C) 2001-2008 Mark Russinovich
Sysinternals - www.sysinternals.com

C:\WINDOWS\system32\mspaint.exe started with process ID 5896.

Upvotes: 5

Rob Levine
Rob Levine

Reputation: 41338

I don't think you can get PsExec to return the pid in the way you want.

However, what you can do is write your own application starter wrapper as a console application, and have this return the pid. You can then have PsExec always start applications by calling this "AppStarter", thus returning your pid.

Something along the lines of:

namespace AppStarter
{
    class Program
    {
        static void Main(string[] args)
        {
            Process process = new Process();
            ProcessStartInfo psi = new ProcessStartInfo(args[0]);
            psi.UseShellExecute = false;
            psi.RedirectStandardOutput = true;
            psi.RedirectStandardError = true;
            psi.RedirectStandardInput = true;
            psi.Arguments = string.Join(" ", args, 1, args.Length - 1);
            process.StartInfo = psi;
            process.Start();
            Console.WriteLine("Process started with PID {0}", process.Id);
        }
    }
}

[this is a rough and ready example, with no exception handling, etc - just as an illustration]

Your code above now becomes somthing like

 Process process = new Process();
    ProcessStartInfo psi = new ProcessStartInfo(@"AppStarter.exe");
    psi.UseShellExecute = false;
    psi.RedirectStandardOutput = true;
    psi.RedirectStandardError = true;
    psi.RedirectStandardInput = true;
    psi.WindowStyle = ProcessWindowStyle.Minimized;
    psi.CreateNoWindow = true;
    psi.Arguments = @"PsExec.exe -i -u Username -p 26.06.08 \\server1,server2 C:\data\GridWorker\GridWorker.exe 100000";
    process.StartInfo = psi;
    process.Start();

    Console.WriteLine(process.StandardOutput.ReadToEnd());

Upvotes: 0

Related Questions