Click here to Skip to main content
Click here to Skip to main content

Tagged as

Introduction to Linq To WMI with Code Generation GUI

, 17 Aug 2011
Rate this:
Please Sign up or sign in to vote.
 
WMI can be a treasure trove of system information, yet accessing it programmatically is cumbersome and error-prone. Using LINQ can ease these pain points by providing a now-familiar common interface to accessing data with the benefits of strong typing and IntelliSense that we have become accustomed to. Microsoft doesn’t provide such a provider but the open source project Linq to WMI does. As a caveat, please be aware that the provider implementation is limited. Writing a robust IQueryable implementation is not for the faint of heart and the implementation currently could be better. Working within its limitations, the project is still quite usable.
 
For this article, I have created a simple GUI that makes generating classes from WMI schemas easier. I’ll run through the code generation process using the GUI and then provide examples of how to use this. Using Linq to WMI requires code generation for the schemas that are used. There is a command-line based generator with the project. I have augmented that with a simple WPF-based GUI available as part of the sample code. The form in the GUI maps pretty directly to the command-line arguments. The GUI does allow multiple classes to be generated at one time. Each generated class contains all necessary properties from within this WMI class.
 
Let me go through a simple example that I worked through in LinqPad. WMI has extensive information about threads and processes available. If I look through the thread class, it has a process handle but not a process name. Finding the process name requires identifying info from the process class.
 
With Linq to WMI we can perform a join on these tables and gather the complete set of information we want. As a prerequisite, I have set up my LinqPad query by referencing the assemblies with the generated WMI entities and the LinqToWmi.Core assembly. I create a WMI context that refers, in this case with the local machine. Replacing the “.” with a remote computer followed by “\Root\CimV2” will access the remote machine. From there it is just standard linq. I have two from clauses for the two classes Win32_Thread and Win32_Process that we want to query on. The where clause joins based on the actual process ID. Finally, the projection in the select statement covers just the fields that we care about.
 
WmiContext context = new WmiContext(@"\\.");  
var query = from threadStuff in context.Source<Win32_Thread>()
            join processStuff in context.Source<Win32_Process>() 
            on threadStuff.ProcessHandle equals processStuff.Handle
            select new
            {
               threadStuff.Handle,
               threadStuff.ProcessHandle,
               processStuff.Caption
            };
query.Dump();
context.Dispose();

There is a viable workaround to the limitations of the Linq to WMI provider. You can enter a simpler query against the provider, obtaining an IEnumerable<T>. From there, you can execute any Linq to Objects query you want, without worrying about the limitations. Here is an example of what that would look like.
 
WmiContext context = new WmiContext(@"\\.");  
var query = from processStuff in context.Source<Win32_Process>)
            select processStuff;
var filteredQuery = from proc in query
                    group proc by proc.Caption into procGroup
                    let recordCount = procGroup.Count()
                    orderby recordCount descending
                    select new 
                    {
                       Name = procGroup.Key,
                       Count = recordCount
                    };
Context.Dispose();
Here are the primary links for this project

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

John Wigger

United States United States
No Biography provided

Comments and Discussions

 
GeneralRiz, The key is using multiple steps. You can think of t... PinmemberJohn Wigger23-Aug-11 4:08 
GeneralWhy is getting a IEnumerable<T> removing the limitations? Do... PinmemberRiz Thon22-Aug-11 17:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140827.1 | Last Updated 17 Aug 2011
Article Copyright 2011 by John Wigger
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid