One of the issues I run into here and there is determining in a file is in use. I have done this in the past by relying on exceptions to help me determine this. I have never liked that so I looked into other ways of determining this.
I am going to try and leverage the ManagementObjectSearcher I know I can write WMI queries to the system and ask for stuff. I found a page on MSDN that lists stuff I can get information on through the WMI query. Check it out here: http://msdn.microsoft.com/en-us/library/aa386179(VS.85).aspx

After adding a reference to System.Management I wrote the following code:

public ManagementObject GetFileManagementObject(string drive, string extension, string fileName, string wmiPath)
{
ManagementObjectSearcher moSearcher = new ManagementObjectSearcher(string.Format("SELECT * FROM CIM_LogicalFile WHERE (Drive='{0}' AND FileName='{1}' AND Extension='{2}')", drive, fileName, extension));
foreach (ManagementObject mangementObj in moSearcher.Get())
{
if (mangementObj.Properties["Path"].Value.ToString() == wmiPath)
{
return (mangementObj);
}
}

return (null);
}

This will find a file and return the management object of the file. You could tweak the inputs to take a file path and chop it up but I am not looking to add all that code for a simple test. I find it odd that I can’t seem to add a clause like “WHERE PATH=’C:\myfile.txt'” as it results in a error indicating an invalid query. Looks like you can only query certain properties. I tested this on a large VHD file I had at “C:\Test\xpbasedynamic.vhd”. Here was my method call:

ManagementObject mangementObj = GetFileManagementObject("C:", "vhd", "xpbasedynamic", @"\test\");

I then ran the following code:

foreach (PropertyData moPropData in mangementObj.Properties)
{
Console.WriteLine(String.Format("{0}:\t{1}", moPropData.Name, moPropData.Value));
}

This resulted in the following printing to the console:

AccessMask: 18809343
Archive: True
Caption: c:\test\xpbasedynamic.vhd
Compressed: False
CompressionMethod:
CreationClassName: CIM_LogicalFile
CreationDate: 20080819163136.458642-240
CSCreationClassName: Win32_ComputerSystem
CSName: YOGI
Description: c:\test\xpbasedynamic.vhd
Drive: c:
EightDotThreeFileName: c:\test\xpbase~1.vhd
Encrypted: False
EncryptionMethod:
Extension: vhd
FileName: xpbasedynamic
FileSize: 1478863872
FileType: Virtual Machine Hard Drive Image
FSCreationClassName: Win32_FileSystem
FSName: NTFS
Hidden: False
InstallDate: 20080819163136.458642-240
InUseCount:
LastAccessed: 20080819163447.176171-240
LastModified: 20070404113325.000000-240
Manufacturer:
Name: c:\test\xpbasedynamic.vhd
Path: \test\
Readable: True
Status: OK
System: False
Version:
Writeable: True

One would think that you could leverage the “InUseCount” property to determine if the file is “In Use.” That is not the case. The “InUseCount” property apparently doesn’t report the proper data. I Googled around on that and found that people have run into the same thing.
So my big attempt to not rely on exceptions to determine if a file is in use has failed. However, I was introduced to WMI Queries which will be a great addition to my code knowledge.

Leave a Reply

Your email address will not be published. Required fields are marked *