Awesome
WmiLight
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:
-
easy usage
-
support for Native AOT deployment
-
no distinction between local and remote queries
-
Debugger Preview