【问题标题】:Runing command into CMD and get output into variable using C#将命令运行到 CMD 并使用 C# 将输出转换为变量
【发布时间】:2015-12-23 22:28:10
【问题描述】:

我需要在 CMD 窗口中运行一个命令并将结果放入一个变量中。 我用下面的代码做同样的事情,但输出不正确

        var proc = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = "cmd.exe",
                Arguments = " wmic.exe /node:(computername or ip address) computersystem get username ",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                CreateNoWindow = true
            }
        };

        proc.Start();
        string line = "";
        while (!proc.StandardOutput.EndOfStream)
        {
            line += (line.Length > 0 ? "-----" : "") + proc.StandardOutput.ReadLine();
        }

        proc.WaitForExit(); 

输出

Microsoft Windows [Version 6.1.7601]-----Copyright (c) 2009 Microsoft Corporation.  All rights reserved.----------C:\Program Files (x86)\Common Files\Microsoft Shared\DevServer\10.0>

但是当我在 CMD 窗口中运行这个命令时,它会显示当前登录的用户名。

谁能帮我解决这个问题。

注意:- 给定的命令用于获取当前登录的用户 使用其 IP 地址在网络系统上命名。

【问题讨论】:

标签: c# cmd


【解决方案1】:

你需要的是 cmd 的 /c 选项

C:\>cmd /?
Starts a new instance of the Windows command interpreter

CMD [/A | /U] [/Q] [/D] [/E:ON | /E:OFF] [/F:ON | /F:OFF] [/V:ON | /V:OFF]
    [[/S] [/C | /K] string]

/C      Carries out the command specified by string and then terminates

我会在这里质疑 cmd.exe 的必要性。您可以直接调用 wmic,如下所示

var proc = new Process {
    StartInfo = new ProcessStartInfo {
        FileName = "wmic.exe",
        Arguments = "/node:localhost computersystem get username ",
        UseShellExecute = false,
        RedirectStandardOutput = true,
        CreateNoWindow = true
    }
};

proc.Start();
string line = "";
while (!proc.StandardOutput.EndOfStream) {
    line += (line.Length > 0 ? "-----" : "") + proc.StandardOutput.ReadLine();
}

proc.WaitForExit();

【讨论】:

    【解决方案2】:

    如果System.Management 拥有您在进程中获取和管理信息所需的所有类,您为什么还要麻烦调用命令行工具并解析其结果?

    var ip = "127.0.0.1";
    var scope = new ManagementScope(
        String.Format("\\\\{0}\\root\\cimv2", ip),
        new ConnectionOptions { Impersonation = ImpersonationLevel.Impersonate });
    scope.Connect();
    
    var users = new ManagementObjectSearcher(
        scope,
        new ObjectQuery("Select * from Win32_LoggedonUser"))
            .Get()
            .GetEnumerator();
    
    while(users.MoveNext())
    {
            var user =  users.Current["antecedent"];
            var mo = new ManagementObject(new ManagementPath(user.ToString()));
    
            try
            {
                var username = mo.Properties["name"];
                Console.WriteLine("username {0}", username.Value);
            }
            catch
            {
                Console.WriteLine(mo);
            }
    }
    

    您所要做的就是创建一个ManagementScope,然后使用ManagementObjectSearcher 使用可用的WMI Classes 之一运行任何WMI Query Language 语句。

    如果您有一个有效的wmic 呼叫,您可以随时添加/TRACE:ON,这样您就可以检查正在进行的呼叫。使用 wmic /? 查看别名。

    【讨论】:

    • 我已将 System.Management 命名空间添加到我的代码中并尝试了您的代码,但它出现错误{找不到类型或命名空间名称 ManagementScope}。
    • 更改参考解决了上述问题,但在下面的代码行出现错误 {Not Found}:- var username = mo.Properties["name"];
    • @AshishRathore 这很奇怪。您使用的是哪个操作系统以及 .Net 框架的哪个版本?您是在本地机器上运行它还是连接到远程机器。如果是这样,那个远程盒子运行的是什么操作系统? user.ToString() 中有什么内容?它是否包含带有域的用户名和它所在的服务器路径?
    • user.ToString() = "\\\\.\\root\\cimv2:Win32_Account.Domain=\"IDR-ITD-SS169\",Name=\"IUSR\"" 本地系统操作系统 = Windows7 远程系统操作系统 = Windows7
    • @AshishRathore 出于某种原因,即使是被提升的管理员也不允许访问某些管理对象的某些属性。我试图找到一种方法来阻止使用 try/catch 块,但我没有找到其他解决方案,所以 try/catch 它是.. ;(
    猜你喜欢
    • 2020-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-04
    • 2012-07-05
    • 2014-02-25
    • 2013-02-08
    • 2012-02-15
    相关资源
    最近更新 更多