C++ | Windows - 有没有办法找出哪个进程拥有锁定文件的所有权?

C++ | Windows - Is there a way to find out which process has ownership of the locked file?

我想知道的是,是否可以尝试打开一个文件(当它失败时,因为它是用另一个关闭共享的进程打开的)来找出哪个进程正在使用该文件?

我想知道这些信息的原因是我正在制作一个小应用程序,它会 "fix" 恶意文件。

例如,某些 malicious/adware 等设置文件安全描述符使用户无法删除文件等。我的应用程序只是重置安全描述符以允许用户重新获得控制权。

我还看到一个文件打开它的子​​进程,例如 (CreateFile) 并关闭共享模式,这样文件就不能被触及,然后应用程序将从内存中执行子进程。

是的,您通常可以只使用 openfiles 命令,在通过以下方式启用此信息收集后,会出现 openfiles /local on.

在 Windows NT 直到并包括(似乎)Windows XP 中,有一个名为 oh 的类似 Resource Kit 命令,是 open handles[ 的简称=26=].

两者的替代方法是使用 SysInternal 的 Process Explorer


注意:在某些情况下openfiles将无法列出某些句柄。当 Windows 拒绝卸载 USB 磁盘时,我会遇到这种情况,声称某个进程正在使用该磁盘上的文件。从来没有出现过这样的过程。

我开发了一个函数来定位这样的进程,杀死它并删除锁定的文件。

bool ForceDeleteFile(LPWSTR FileName);

这里是完整的源代码:

bool KillFileProcess(LPWSTR FileName)
{
    HANDLE hProcessSnap;
    HANDLE hProcess;
    PROCESSENTRY32 pe32;
    DWORD dwPriorityClass;
    bool result = false;
    // Take a snapshot of all processes in the system.
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE)
    {
        //printError(TEXT("CreateToolhelp32Snapshot (of processes)"));
        return(FALSE);
    }

    // Set the size of the structure before using it.
    pe32.dwSize = sizeof(PROCESSENTRY32);

    // Retrieve information about the first process,
    // and exit if unsuccessful
    if (!Process32First(hProcessSnap, &pe32))
    {
        //printError(TEXT("Process32First")); // show cause of failure
        CloseHandle(hProcessSnap);          // clean the snapshot object
        return(FALSE);
    }

    // Now walk the snapshot of processes, and
    // display information about each process in turn
    do
    {
        // Retrieve the priority class.
        dwPriorityClass = 0;
        hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
        if (hProcess == NULL)
        {
            //printError(TEXT("OpenProcess"));
        }
        else
        {
            dwPriorityClass = GetPriorityClass(hProcess);
            if (!dwPriorityClass)
            {
                //printError(TEXT("GetPriorityClass"));
            }
            CloseHandle(hProcess);
            if (HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pe32.th32ProcessID))
            {
                WCHAR filename[MAX_PATH] = {};

                if (GetModuleFileNameEx(hProcess, NULL, filename, MAX_PATH))
                {
                    if (_wcsicmp((const wchar_t *)FileName, (const wchar_t *)filename) == NULL)
                    {
                        if (TerminateProcess(pe32.th32ProcessID, 0))
                        {
                            _tprintf(L"Found: Process full killed\nKILLED!\n");
                            result = true;

                        }
                        else
                        {
                            _tprintf(L"Found: Process full \nFailed to terminate\n");
                            DoRun(((CString)L"taskkill /F /IM " + (CString)pe32.szExeFile).GetBuffer());

                            result = false;

                        }
                    }
                }
                else
                {
                    // handle error
                }

                CloseHandle(hProcess);
            }
        }


    } while (Process32Next(hProcessSnap, &pe32));

    CloseHandle(hProcessSnap);
    return(result);
}
bool ForceDeleteFile(LPWSTR FileName)
{
    bool result = DeleteFile(FileName);
    if (!result)
    {
        _tprintf(L"Can't delete file. using DeleteFile(). Trying to locate process and kill it\n");
        result = KillFileProcess(FileName);
        if (!result)
            _tprintf(L"Couldn't find the process\n");
        else
        {
            Sleep(1000);
            result = DeleteFile(FileName);
            if (result)
                _tprintf(L"DeleteFile success");
            else
                _tprintf(L"DeleteFile  ============== failed ===============");

        }
    }
    return result;
}
BOOL TerminateProcess(DWORD dwProcessId, UINT uExitCode)
{
    DWORD dwDesiredAccess = PROCESS_TERMINATE;
    BOOL  bInheritHandle = FALSE;
    HANDLE hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
    if (hProcess == NULL)
        return FALSE;

    BOOL result = TerminateProcess(hProcess, uExitCode);

    CloseHandle(hProcess);

    return result;
}