Felix D.
Felix D.

Reputation: 5083

Can't get CMD Output

So this is my code:

private void CheckLastLogon(string computername)
{
    string cmd = $"/C query user /server:{computername}";
    System.Diagnostics.Process proc = new System.Diagnostics.Process();
    proc.StartInfo.FileName = "cmd.exe";
    proc.StartInfo.Arguments = cmd;
    proc.StartInfo.UseShellExecute = false;
    proc.StartInfo.CreateNoWindow = true;
    proc.StartInfo.RedirectStandardOutput = true;
    proc.Start();

    string output = proc.StandardOutput.ReadToEnd();

    proc.WaitForExit();
}

output is always string.Empty and I got no clue why ... (It's working in CMD).

Maybe cause of the /c in my command ? does it terminate to fast ?

Where is my error ?


UPDATE 1: After redirecting the ErrorOutput I got some additional information.

I added the ErrorOutputand it's saying The command 'query' is not found

So what's the issue with my command ?

Here you see it's working in the cmd:

enter image description here


Update 2: If I remove the /c from my command it's not doing anything. If I break the debugger it's waiting at proc.StandardOutput.ReadToEnd();

Some time later I get a ContextSwitchDeadlock ...

What is so horribly wrong about this ?

Upvotes: 1

Views: 478

Answers (1)

ScottishTapWater
ScottishTapWater

Reputation: 4786

If you're looking for errors you need to do:

proc.StartInfo.RedirectStandardError = true;

And then read from proc.StandardError.

UPDATE 1:

If using cmd as a go-between isn't working. You could try running C:\Windows\System32\query.exe directly as a standalone .exe. This avoids having to use cmd and all of the issues that this can cause.

So you'd be looking at something like:

ProcessStartInfo procstart = new ProcessStartInfo
{
           FileName = @"C:\Windows\System32\query.exe",
           Arguments = $"user /server:{computername}",
           UseShellExecute = false,
           CreateNoWindow = true,
           RedirectStandardOutput = true,
           RedirectStandardError = true
};
Process proc = new Process{StartInfo = procStart};
proc.Start();
string[] output = proc.StandardOutput.ReadAllLines();

UPDATE 2:

system32 can only be accessed by x64 programs, x32 programs get redirected to syswow64.

If you build for x64 only, the following code works:

        ProcessStartInfo procstart = new ProcessStartInfo
        {
            FileName = "query",
            Arguments = "$"user /server:{computername}"",
            UseShellExecute = false,
            CreateNoWindow = true,
            RedirectStandardOutput = true,
            RedirectStandardError = true
        };
        Process proc = new Process {StartInfo = procstart};
        proc.Start();
        Console.WriteLine(proc.StandardOutput.ReadToEnd());
        Console.WriteLine(proc.StandardError.ReadToEnd());
        Console.Read();

TLDR:

If you're trying to use a cmd command, don't use cmd as a go-between, just put it in the StartInfo.FileName. If that command is in system32 make sure you build for x64.

Upvotes: 2

Related Questions