Finding File info with WMI in managed code

When WinFS comes around life will be much improved with respect to obtaining information about files stored on your system. For now, there is a mishmash of things you have to do depending on what information you are going after. If you need basic file attributes, you use the FileInfo object. If you need information about the content, you will usually have to open the file and do some form of parsing. If you want security related information, you will have to go through either a Win32 API or WMI in many cases.

I had someone at the Richmond.NET group I spoke at last night come to me with what seemed like a simple question: How do I get the owner of a file? My first reaction was that it should be part of the file attributes accessible through the FileInfo object, but that was not the case. A little digging revealed that particular piece of information is treated as part of the security information associated with a file in NTFS, and would not be available in Win98/Me.

Next look was at the Win32 APIs, and sure enough there is a fairly straightforward way through the GetSecurityInfo API, but that meant doing a lot of PInvoke interop, which I like to avoid if at all possible. It occurred to me that WMI probably had a way in, and that led me to a easy solution posted on the Experts Exchange site by “The Learned One”.

Here is a distilled version of what he presented, in C# instead of hisVB.NET:


privatestring GetFileOwner(string path)
{

ManagementObject mgmt = new ManagementObject(“Win32_LogicalFileSecuritySetting.path='” + path + “‘”);

ManagementBaseObject secDesc = mgmt.InvokeMethod(“GetSecurityDescriptor”,null,null);

ManagementBaseObject descriptor = secDesc.Properties[“Descriptor”].Value as ManagementBaseObject;

ManagementBaseObject owner = descriptor.Properties[“Owner”].Value as ManagementBaseObject;

return owner.Properties[“Domain”].Value.ToString() + “\” + owner.Properties[“Name”].Value.ToString();

}


The key to working with WMI is figuring out the right objects, methods, and properties to access. Once you get used to the hierarchical approach of the object model, it is fairly easy to thread your way through and find what you need in the WMI documentation, and then translate that into System.Management class calls you need to make.

Keep in mind that many of the things you can do with WMI require administrative privilege. If you are expecting people to be able to use your app as non-admins, make sure you test it out to make sure the things you are doing are not privileged operations. In the case of the queries above, you can just be a standard user account in windows running this code and it works fine.