Click here to Skip to main content
15,885,309 members
Articles / Programming Languages / Visual Basic
Tip/Trick

Introduction to Linq To WMI with Code Generation GUI

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
17 Aug 2011CPOL2 min read 24.5K   8   2


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.

C#
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.

C#
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)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

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

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

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