从 C# 结果 0 输出通过 CMD.exe 调用“查询用户”

Posted

技术标签:

【中文标题】从 C# 结果 0 输出通过 CMD.exe 调用“查询用户”【英文标题】:"Query User" called via CMD.exe results 0 Output 【发布时间】:2022-01-23 20:26:02 【问题描述】:

我正在尝试调用并收集 CMD 命令query user 返回的数据。

通过 cmd 从 Windows-startbar 调用它会给我一个正常的结果。

通过这个 c# 函数调用它会得到 0 输出。

     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);
        

我检查了,窗口说找不到命令...我还检查了它们是否都是相同的 cmd.exe,这也是正确的。似乎通过 C# 调用 cmd.exe 会有所不同。 有人知道我接下来可以检查什么吗?

【问题讨论】:

您没有等待进程退出 (process.WaitForExit()) @KlausGütter 抱歉,只是复制粘贴错误。当然,我在原始代码中等待退出。 Ty 试图提供帮助 :=) 您在 psiist 完全设置之前致电 Process.Start(psi)。当您将 Start 向下移动到 psi 完成时,它将起作用。 我想psi.WaitForExit() 应该是p.WaitForExit() WMI 可能更适合这个 【参考方案1】:

不必使用cmd 来检索您想要使用Process 的信息。但是,如果您的操作系统是 64 位,您的程序以 32 位运行,并且您尝试访问 %windir%\System32\query.exe,则需要改用 %windir%\Sysnative\query.exe

尝试以下方法:

选项 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();
     

选项 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);
    

资源

Accessing files from System32 directory using 32 bit application on 64 bit machine Process Class ProcessStartInfo Class Environment.GetEnvironmentVariable Method

【讨论】:

先生,你是我的英雄

以上是关于从 C# 结果 0 输出通过 CMD.exe 调用“查询用户”的主要内容,如果未能解决你的问题,请参考以下文章

用C#编程,需要用CMD窗口显示结果,可CMD窗口闪一下就退出了,如何让CMD窗口一直显示不退出?

如何从 PL/SQL 调用 .exe?

python subcommand.Popen调用不同目录下的脚本时cmd.exe弹出新窗口

C#程序调用CMD执行命令方法

C#进程线程不能写输出

c# 打开cmd.exe进程并执行多条命令