how to find which process has a handle on a file from the file name

后端 未结 2 550
春和景丽
春和景丽 2021-02-08 21:38

Is there anything in the Windows c++ API to give me a list of processes that have a handle to a given file?

相关标签:
2条回答
  • 2021-02-08 22:15

    From Microsoft's blog: How do I find out which process has a file open?

    Enter the Restart Manager.

    The official goal of the Restart Manager is to help make it possible to shut down and restart applications which are using a file you want to update. In order to do that, it needs to keep track of which processes are holding references to which files. And it’s that database that is of use here. (Why is the kernel keeping track of which processes have a file open? Because it’s the converse of the principle of not keeping track of information you don’t need: Now it needs the information!)

    Here’s a simple program which takes a file name on the command line and shows which processes have the file open.

    #include <windows.h>
    #include <RestartManager.h>
    #include <stdio.h>
    
    int __cdecl wmain(int argc, WCHAR **argv)
    {
     DWORD dwSession;
     WCHAR szSessionKey[CCH_RM_SESSION_KEY+1] = { 0 };
     DWORD dwError = RmStartSession(&dwSession, 0, szSessionKey);
     wprintf(L"RmStartSession returned %d\n", dwError);
     if (dwError == ERROR_SUCCESS) {
       PCWSTR pszFile = argv[1];
       dwError = RmRegisterResources(dwSession, 1, &pszFile,
                                     0, NULL, 0, NULL);
       wprintf(L"RmRegisterResources(%ls) returned %d\n",
               pszFile, dwError);
      if (dwError == ERROR_SUCCESS) {
       DWORD dwReason;
       UINT i;
       UINT nProcInfoNeeded;
       UINT nProcInfo = 10;
       RM_PROCESS_INFO rgpi[10];
       dwError = RmGetList(dwSession, &nProcInfoNeeded,
                           &nProcInfo, rgpi, &dwReason);
       wprintf(L"RmGetList returned %d\n", dwError);
       if (dwError == ERROR_SUCCESS) {
        wprintf(L"RmGetList returned %d infos (%d needed)\n",
                nProcInfo, nProcInfoNeeded);
        for (i = 0; i < nProcInfo; i++) {
         wprintf(L"%d.ApplicationType = %d\n", i,
                                  rgpi[i].ApplicationType);
         wprintf(L"%d.strAppName = %ls\n", i,
                                  rgpi[i].strAppName);
         wprintf(L"%d.Process.dwProcessId = %d\n", i,
                                  rgpi[i].Process.dwProcessId);
         HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION,
                                       FALSE, rgpi[i].Process.dwProcessId);
         if (hProcess) {
          FILETIME ftCreate, ftExit, ftKernel, ftUser;
          if (GetProcessTimes(hProcess, &ftCreate, &ftExit,
                              &ftKernel, &ftUser) &&
              CompareFileTime(&rgpi[i].Process.ProcessStartTime,
                              &ftCreate) == 0) {
           WCHAR sz[MAX_PATH];
           DWORD cch = MAX_PATH;
           if (QueryFullProcessImageNameW(hProcess, 0, sz, &cch) &&
               cch <= MAX_PATH) {
            wprintf(L"  = %ls\n", sz);
           }
          }
          CloseHandle(hProcess);
         }
        }
       }
      }
      RmEndSession(dwSession);
     }
     return 0;
    }
    
    0 讨论(0)
  • 2021-02-08 22:20

    http://www.codeproject.com/KB/shell/OpenedFileFinder.aspx?fid=422864&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=26&select=2277170

    This article explains it pretty good. It uses NtQuerySystemInformation to get the handles.

    http://msdn.microsoft.com/en-us/library/ms724509(VS.85).aspx

    0 讨论(0)
提交回复
热议问题