Powershell Command in C#

2019-06-16 19:20发布

问题:

I am trying to query the names all of the WMI classes within the root\CIMV2 namespace. Is there a way to use a powershell command to retrieve this information in C# ?

回答1:

Along the lines of Keith's approach

using System;
using System.Management.Automation;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var script = @" 
                Get-WmiObject -list -namespace root\cimv2 | Foreach {$_.Name}
            ";

            var powerShell = PowerShell.Create();
            powerShell.AddScript(script);

            foreach (var className in powerShell.Invoke())
            {
                Console.WriteLine(className);
            }
        }
    }
}


回答2:

I'm not sure why you mentioned PowerShell; you can do this in pure C# and WMI (the System.Management namespace, that is).

To get a list of all WMI classes, use the SELECT * FROM Meta_Class query:

using System.Management;
...

try
{
    EnumerationOptions options = new EnumerationOptions();
    options.ReturnImmediately = true;
    options.Rewindable = false;

    ManagementObjectSearcher searcher =
        new ManagementObjectSearcher("root\\cimv2", "SELECT * FROM Meta_Class", options);

    ManagementObjectCollection classes = searcher.Get();

    foreach (ManagementClass cls in classes)
    {
        Console.WriteLine(cls.ClassPath.ClassName);
    }
}
catch (ManagementException exception)
{
    Console.WriteLine(exception.Message);
}


回答3:

Just to note that there is a tool available that allows you to create, run, and save WMI scripts written in PowerShell, the PowerShell Scriptomatic tool, available for download from the Microsoft TechNet site.

Using this tool, you could explore all of the WMI classes within the root\CIMV2 or any other WMI namespace.



回答4:

You'd probably want to just use the System.Management namespace like Helen answered, but you can also host powershell within your application. See http://www.codeproject.com/KB/cs/HowToRunPowerShell.aspx



回答5:

Personally I would go with Helen's approach and eliminate taking a dependency on PowerShell. That said, here's how you would code this in C# to use PowerShell to retrieve the desired info:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Management.Automation;

namespace RunspaceInvokeExp
{
    class Program
    {
        static void Main()
        {
            using (var invoker = new RunspaceInvoke())
            {
                string command = @"Get-WmiObject -list -namespace root\cimv2" +
                                  " | Foreach {$_.Name}";
                Collection<PSObject> results = invoker.Invoke(command);
                var classNames = results.Select(ps => (string)ps.BaseObject);
                foreach (var name in classNames)
                {
                    Console.WriteLine(name);
                }
            }
        }
    }
}