Search code examples
c#windowscmdcommand-linecommand-prompt

"Query User" called via CMD.exe results 0 Output


i am trying to call and collect the data returned by the CMD command query user.

Calling this via cmd from the Windows-startbar gives me a normal result.

Calling this via this c# function give 0 output.

     public void callQueryUser()
        {
            ProcessStartInfo psi = new ProcessStartInfo("cmd.exe");
            Process p = Process.Start(psi);

            string cmd = string.Format(@"/c query user");
             
            psi.Arguments = cmd;
                                
            psi.RedirectStandardOutput = true;
            psi.UseShellExecute = false;
            psi.CreateNoWindow = true;
            psi.WaitForExit();
           
            string result = p.StandardOutput.ReadToEnd();
            MessageBox.Show(result);
        }

I checked and the Window says command cant befound... I also check if they are both the same cmd.exe and thats also true. It seems like calling the cmd.exe via C# makes somewhat of a differences. Anyone any idea what i could check next ?


Solution

  • It's not necessary to use cmd to retrieve the information you want using Process. However, if your OS is 64-bit, your program is running as 32-bit, and you're trying to access %windir%\System32\query.exe, you need to use %windir%\Sysnative\query.exe instead.

    Try the following:

    Option 1:

    public void callQueryUser()
    {
        string queryPath = string.Empty;
    
        //use 'Sysnative' to access 64-bit files (in System32) if program is running as 32-bit process
        //use 'SysWow64' to access 32-bit files on 64-bit OS
        if (Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess)
            queryPath = System.IO.Path.Combine(Environment.GetEnvironmentVariable("windir"), "Sysnative", "query.exe");
        else
            queryPath = System.IO.Path.Combine(Environment.GetEnvironmentVariable("windir"), "System32", "query.exe");
    
        Debug.WriteLine("queryPath: " + queryPath);
    
        // create new instance
        ProcessStartInfo startInfo = new ProcessStartInfo(queryPath);
        startInfo.Arguments = "user"; //arguments
        startInfo.CreateNoWindow = true; //don't create a window
        startInfo.RedirectStandardError = true; //redirect standard error
        startInfo.RedirectStandardOutput = true; //redirect standard output
        startInfo.UseShellExecute = false; //if true, uses 'ShellExecute'; if false, uses 'CreateProcess'
        startInfo.WindowStyle = ProcessWindowStyle.Hidden;
    
        //create new instance
        using (Process p = new Process { StartInfo = startInfo, EnableRaisingEvents = true })
        {
            //subscribe to event and add event handler code
            p.ErrorDataReceived += (sender, e) =>
            {
                if (!String.IsNullOrEmpty(e.Data))
                {
                    //ToDo: add desired code 
                    Debug.WriteLine("Error: " + e.Data);
                }
            };
    
            //subscribe to event and add event handler code
            p.OutputDataReceived += (sender, e) =>
            {
                if (!String.IsNullOrEmpty(e.Data))
                {
                    //ToDo: add desired code
                    Debug.WriteLine("Output: " + e.Data);
    
                    string result = e.Data;
                    MessageBox.Show(result);
                }
            };
    
            p.Start(); //start
    
            p.BeginErrorReadLine(); //begin async reading for standard error
            p.BeginOutputReadLine(); //begin async reading for standard output
    
            //waits until the process is finished before continuing
            p.WaitForExit();
        } 
    }
    

    Option 2:

    public void callQueryUser()
    {
        string queryPath = string.Empty;
    
        //environment variable windir has the same value as SystemRoot
        //use 'Sysnative' to access 64-bit files (in System32) if program is running as 32-bit process
        //use 'SysWow64' to access 32-bit files on 64-bit OS
        if (Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess)
            queryPath = System.IO.Path.Combine(Environment.GetEnvironmentVariable("windir"), "Sysnative", "query.exe");
        else
            queryPath = System.IO.Path.Combine(Environment.GetEnvironmentVariable("windir"), "System32", "query.exe");
    
        Debug.WriteLine("queryPath: " + queryPath);
    
        // create new instance
        ProcessStartInfo startInfo = new ProcessStartInfo(queryPath);
        startInfo.Arguments = "user"; //arguments
        startInfo.CreateNoWindow = true; //don't create a window
        startInfo.RedirectStandardError = true; //redirect standard error
        startInfo.RedirectStandardOutput = true; //redirect standard output
        startInfo.UseShellExecute = false; //if true, uses 'ShellExecute'; if false, uses 'CreateProcess'
        startInfo.WindowStyle = ProcessWindowStyle.Hidden;
    
        //create new instance
        using (Process p = new Process { StartInfo = startInfo, EnableRaisingEvents = true })
        {
            p.Start(); //start
    
            //waits until the process is finished before continuing
            p.WaitForExit();
    
            string result = p.StandardOutput.ReadToEnd();
            MessageBox.Show(result);
        }
    }
    

    Resources: