【问题标题】:How to run msinfo32 console command from C#?如何从 C# 运行 msinfo32 控制台命令?
【发布时间】:2018-09-20 06:21:34
【问题描述】:

我想从 msinfo32 命令向用户桌面文件夹中的 nfo 文件生成报告。我直接运行这个 exe,因为命令 msinfo32 有时不在 XP 的 PATH 中。所以,这就是我想要的 C#:

"C:\Program Files\Common Files\Microsoft Shared\MSInfo\msinfo32.exe" /nfo C:\Users\someUser\Desktop\my_pc.nfo

我现在有这段代码,它调用 UAC,然后 cmd 窗口关闭。该文件未创建。为什么这不起作用?

        var proc1 = new ProcessStartInfo();

        string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        string myFile = "my_pc.nfo";
        string myFullPath = Path.Combine(desktopPath, myFile);
        string myCommand = @"/C C:\Program Files\Common Files\Microsoft Shared\MSInfo\msinfo32.exe /nfo " + myFullPath;

        proc1.UseShellExecute = true;
        proc1.WorkingDirectory = @"C:\Windows\System32";
        proc1.FileName = @"C:\Windows\System32\cmd.exe";
        proc1.Verb = "runas";

        char quote = '"';
        proc1.Arguments = "/C " + quote + myCommand + quote;
        proc1.WindowStyle = ProcessWindowStyle.Normal;
        Process.Start(proc1);

        Console.ReadLine();

【问题讨论】:

  • 难道不能直接调用msinfo32.exe,中间不调用cmd.exe吗?我认为不可能链接调用并保留参数。 /nfo 参数将成为 cmd.exe 调用的参数,并在 msinfo32“子”调用中丢失。
  • 必须查明进程是否成功完成,使用ExitCode属性。如果不为 0 则失败。较大的负值往往有助于诊断异常。

标签: c# cmd


【解决方案1】:

注意:MSInfo 没有设置错误级别。

您的 MSINFO32 命令行没有引用保存的文件名。因此,如果它包含空格,它将不起作用。

出于一个完全未知的原因,您调用 CMD,即使您不希望它执行任何操作。

您正在使用不受支持的方式来提升,它仅在 exe 文件关联的配置未更改的情况下才有效。您使用清单来提升。见Run batch script as admin during Maven build

还可以将 wmi 视为一个程序应该做的事情。您可以尝试使用 wmic 命令行工具。程序是供用户使用的,而不是其他程序。

这是寻找 wifi 网络

Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")

Set colItems = objWMIService.ExecQuery("Select * From WiFi_AvailableNetwork")
'msgbox colitems
For Each objItem in colItems
    msgbox objItem.name & " " & objItem.Description
Next

此列表服务,

Set objWMIService = GetObject("winmgmts:\\127.0.0.1\root\cimv2")

Set config = objWMIService.ExecQuery("Select * From Win32_Service")
For Each thing in Config
        Msgbox thing.Caption
Next

监视器

Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")

Set colItems = objWMIService.ExecQuery("Select * From Win32_DesktopMonitor")

For Each objItem in colItems
    msgbox  objItem.Model & " " & objItem.Manufacturer & " " & objItem.SerialNumber
Next

这会等待电源事件发生并杀死或启动计算器。

Set colMonitoredEvents = GetObject("winmgmts:")._
    ExecNotificationQuery("SELECT * FROM Win32_PowerManagementEvent")
Do
    Set strLatestEvent = colMonitoredEvents.NextEvent
    If strLatestEvent.EventType = 4 Then 
        Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
        Set colItems = objWMIService.ExecQuery("Select * From Win32_Process")
        For Each objItem in colItems
            If objItem.name = "Calculator.exe" then objItem.terminate
        Next
    ElseIf strLatestEvent.EventType = 7 Then 
        wscript.sleep 2000
        Set WshShell = WScript.CreateObject("WScript.Shell")
        WshShell.Run "calc.exe", 1, false
    End If
Loop

【讨论】:

  • 感谢您提供清单文件。我从 VS 中添加了它,就像这里 stackoverflow.com/questions/2818179/… 一样。我是 C# 的初学者,不知道 VB 也不知道 wmic。无论如何,谢谢。
【解决方案2】:

根据@CatCat 的建议,我设法以管理员身份运行该程序。您需要修改嵌入到程序中的清单。这适用于 Visual Studio 2008 及更高版本:项目 + 添加新项目,选择“应用程序清单文件”。将<requestedExecutionLevel> 元素更改为:

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

用户在启动程序时会收到 UAC 提示。我将Enviroment.SpecialFolder.Desktop 与我的其他参数连接到一个进程参数,现在它可以按我的意愿工作了。

using System;
using System.Diagnostics;
using System.ServiceProcess;

namespace WinTImeSync
{
    class Program
    {
        static void Main(string[] args)
        {
            if (MsInfoReport() == true)
            {
                Console.WriteLine("Command ran successfully.");
            }
            else
            {
                Console.WriteLine("Did not run.");
            }
            Console.Write("Press any key to continue...");
            Console.ReadKey();
        }

        public static bool MsInfoReport()
        {
            try
            {
                string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                Process processTime = new Process();
                processTime.StartInfo.FileName = @"C:\Program Files\Common Files\microsoft shared\MSInfo\msinfo32.exe";
                processTime.StartInfo.Arguments = "/report " + desktopPath + "\\mypc_info.nfo /categories +systemsummary";
                processTime.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                processTime.Start();
                processTime.WaitForExit();

                return true;
            }
            catch (Exception exception)
            {
                Trace.TraceWarning("unable to run msinfo32", exception);
                return false;
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-17
    • 1970-01-01
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 2016-03-19
    • 2023-03-13
    • 1970-01-01
    相关资源
    最近更新 更多