Search code examples
wqlcim

How to use Microsoft.Management.Infrastructure in an application to determine which app has a file locked?


I've got Microsoft.Management.Infrastructure working in my application, at least as far as the very first sample code:

CimSession.Create(null)
    .QueryInstances(@"root\cimv2", "WQL", "SELECT * FROM Win32_OperatingSystem")
    .FirstOrDefault().CimInstanceProperties["Version"].Value.ToString();

What I need is to use MMI to determine whether any applications on the local machine have a lock on a specific file (see this question to see why approaches besides MMI aren't working)

I've been reading page after page of documentation on MMI and WQL and CIM and a flock of other TLAs but cannot figure out how to either

1) ask the question "which process has file X open/locked"?

or

2) enumerate all open/locked files so I can look for file X

Important - I need to do this in code (running Process Explorer won't work for me).


Solution

  • As far as I know, it is not possible to do in CIM/WMI.

    If you have time, you can inspect ~1400 available CIM/WMI classes in a tool like WMI Explorer. Or you can limit your search by looking only at the classes containing certain property names by running something like this in PowerShell:

    Get-CimClass -PropertyName *handle*
    

    where handle is a property name you're interested in.

    You could think that the CIM_LogicalFile.InUseCount provides something similar to what you need but the complaints that it doesn't work go as back as 2003. It is quite possible that it was never implemented.

    As a side note, it seems that most authors of "file unlocker" tools operate under assumption that a locked file means that there is a file handle owned by a process, so you just need to enumerate all active file handles and correlate them with the list of running processes. Unfortunately, there is no class in WMI that allows you to do that, but even if there was such class, it wouldn't work for the memory-mapped files (which judging by your other question is what you are concerned with) because most apps dispose the file handle as soon as they open the memory-mapped file. In order to get that information, you would need to enumerate virtual memory regions in a process and then query Windows memory manager asking what image or memory-mapped file corresponds to that region. A task like this feels quite far out of scope of what WMI is typically able to do.