Home

Awesome

WmiLight Build NuGet Status

What is WmiLight?

A simple and light wmi framework. It has only one function: sending WMI queries. It's a subset of the System.Management.Instrumentation namespace.

In which case should you use WmiLight?

The .Net framework implementation has one big problem. It leaks a little bit memory on each remote operation. Use this framework if your application is a service or runs a long time and you're sending a lot of remote queries.

Installation

This project is being distributed as a NuGet package, so open your Package Manager Console window and execute the following command:

<a href="https://www.nuget.org/packages/WmiLight/" target="_blank"> <img title="NuGet" src="https://github.com/MartinKuschnik/WmiLight/blob/master/doc/pics/install_nuget_package.JPG" alt="NuGet"/> </a>

How to use?

Query all running processes for the local machine:

using (WmiConnection con = new WmiConnection())
{
    foreach (WmiObject process in con.CreateQuery("SELECT * FROM Win32_Process"))
    {
        Console.WriteLine(process["Name"]);
    }
}

Query all partitions for a remote machine with credentials:


var opt = new WmiConnectionOptions() { EnablePackageEncryption = true };
var cred = new NetworkCredential("USERNAME", "PASSWORD", "DOMAIN");

using (WmiConnection con = new WmiConnection(@"\\MACHINENAME\root\cimv2", cred, opt))
{
    foreach (WmiObject partition in con.CreateQuery("SELECT * FROM Win32_DiskPartition"))
    {
        Console.WriteLine(partition["Name"]);
    }
}

Query all partitions for a remote machine with Integrated Windows Authentication:

var opt = new WmiConnectionOptions() { EnablePackageEncryption = true };

using (WmiConnection con = new WmiConnection(@"\\MACHINENAME\root\cimv2", opt))
{
    foreach (WmiObject partition in con.CreateQuery("SELECT * FROM Win32_DiskPartition"))
    {
        Console.WriteLine(partition["Name"]);
    }
}

Calling a static WMI method:

using (WmiConnection connection = new WmiConnection())
using (WmiMethod createMethod = connection.GetMethod("Win32_Process", "Create"))
using (WmiMethodParameters methodParams = createMethod.CreateInParameters())
{
    methodParams.SetPropertyValue("CommandLine", "cmd.exe");
  
    uint result = connection.ExecuteMethod<uint>(createMethod, methodParams, out WmiMethodParameters outParams);
  
    if (result != 0)
            throw new Exception($"Win32_Process::Create(...) failed with {result}");
  
    uint processId =  outParams.GetPropertyValue<uint>("ProcessId");

    // ...
}

And the following code shows how to call a non-static WMI method:

using (WmiConnection connection = new WmiConnection())
{
    foreach (WmiObject process in connection.CreateQuery("SELECT * FROM Win32_Process"))
    {
        if (process.GetPropertyValue<string>("Name") == "cmd.exe")
        {
            using (WmiMethod terminateMethod = process.GetMethod("Terminate"))
            using (WmiMethodParameters parameters = terminateMethod.CreateInParameters())
            {
                parameters.SetPropertyValue("Reason", 20);

                uint result = process.ExecuteMethod<uint>(terminateMethod, parameters, out WmiMethodParameters terminateOutParameters2);

                if (result != 0)
                    throw new Exception($"Win32_Process::Terminate(...) failed with {result}");
            }
        }
    }
}

Get a notification if a process has started:

var opt = new WmiConnectionOptions() { EnablePackageEncryption = true };

using (WmiConnection connection = new WmiConnection(@"\\MACHINENAME\root\cimv2", opt))
{
    using (WmiEventSubscription sub = connection.CreateEventSubscription(
            "SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process'", 
            x => Console.WriteLine("Process '{0}' started", x.GetPropertyValue<WmiObject>("TargetInstance").GetPropertyValue<string>("Name"))))
    {
        // ToDo: wait or do some other suff
    }
}

Alternative way to get a notification if a process has started:

var opt = new WmiConnectionOptions() { EnablePackageEncryption = true };

using (WmiConnection connection = new WmiConnection(@"\\MACHINENAME\root\cimv2", opt))
{
    using (WmiEventWatcher eventWatcher = connection.CreateEventWatcher("SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process'"))
    {
        eventWatcher.EventArrived += EventWatcher_EventArrived;

        eventWatcher.Start();

        // ToDo: wait or do some other suff

        eventWatcher.Stop();

        eventWatcher.EventArrived -= EventWatcher_EventArrived;
    }
}

Native AOT deployment

WmiLight supports Native AOT deployment since Version 5.0.0.

It's also possible to link WmiLight statically to have only one executable working without the WmiLight.dll. <br/> To link WmiLight statically, add <PublishWmiLightStaticallyLinked>true</PublishWmiLightStaticallyLinked> to your project file.

<PropertyGroup>
    <PublishAot>true</PublishAot>
    <PublishWmiLightStaticallyLinked>true</PublishWmiLightStaticallyLinked>
</PropertyGroup>

Other benefits: