c ++ Windows - 如何从其路径获取进程PID

时间:2014-05-22 18:52:46

标签: c++ c windows

C++ Windows - How to get process path from its PID类似,但相反:如何从给定路径获取pid?

我正在尝试编写更新工具,我想查看是否正在使用该exe。然后如果它正在使用中,我想等待进程退出。因此,我想获得属于该文件的进程PID。

1 个答案:

答案 0 :(得分:2)

这是一种快速简单的方法来完成您所需要的工作。通过使用QueryFullProcessImageName,您可以快速检查。

可能导致以下代码无法正常工作的事情:

  • 如果您没有查看流程的权限,则不会 能够看到这些信息。
  • 如果进程为64位且您将应用程序作为32位运行,则会看到进程ID,但无法打开进程ID。

示例:

BOOL GetProcessName(LPTSTR szFilename, DWORD dwSize, DWORD dwProcID)
{
    BOOLEAN retVal = FALSE;
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcID);
    DWORD dwPathSize = dwSize;
    if (hProcess == 0)
        return retVal; // You should check for error code, if you are concerned about this
    retVal = QueryFullProcessImageName(hProcess, 0, szFilename, &dwPathSize);

    CloseHandle(hProcess);

    return retVal;
}

BOOL IsProcessInUse(LPCTSTR process_name)
{
    DWORD* pProcs = NULL;
    DWORD dwSize = 0;
    DWORD dwRealSize = 0;
    TCHAR szCompareName[MAX_PATH + 1];
    int nCount = 0;
    int nResult = 0;

    dwSize = 1024;
    pProcs = new DWORD[dwSize];
    EnumProcesses(pProcs, dwSize*sizeof(DWORD), &dwRealSize);
    dwSize = dwRealSize / sizeof(DWORD);

    for (DWORD nCount = 0; nCount < dwSize; nCount++)
    {
        ZeroMemory(szCompareName, MAX_PATH + 1 * (sizeof(TCHAR)));
        if (GetProcessName(szCompareName, MAX_PATH, pProcs[nCount]))
        {
            if (_tcscmp(process_name, szCompareName) == 0)
            {
                delete[] pProcs;
                return true;
            }
        }
    }
    delete[] pProcs;
    return FALSE;
}

然后你会使用像下面这样简单的东西来测试它:

if (IsProcessInUse(your_file))
    AfxMessageBox(_T("The process is still running"));
else
    AfxMessageBox(_T("The process has been closed"));

以上回答了您的间接问题。要回答您的文字问题,您可以按如下方式更改IsProcessInUse:

DWORD GetNamedProcessID(LPCTSTR process_name)
{
    DWORD* pProcs = NULL;
    DWORD retVal = 0;
    DWORD dwSize = 0;
    DWORD dwRealSize = 0;
    TCHAR szCompareName[MAX_PATH + 1];
    int nCount = 0;
    int nResult = 0;

    dwSize = 1024;
    pProcs = new DWORD[dwSize];
    EnumProcesses(pProcs, dwSize*sizeof(DWORD), &dwRealSize);
    dwSize = dwRealSize / sizeof(DWORD);

    for (DWORD nCount = 0; nCount < dwSize; nCount++)
    {
        ZeroMemory(szCompareName, MAX_PATH + 1 * (sizeof(TCHAR)));
        if (GetProcessName(szCompareName, MAX_PATH, pProcs[nCount]))
        {
            if (_tcscmp(process_name, szCompareName) == 0)
            {
                retVal = pProcs[nCount];
                delete[] pProcs;
                return retVal;
            }
        }
    }
    delete[] pProcs;
    return 0;
}

最后要注意的一件事是,这只会返回一个文件的单个实例(或PID),这不会查找进程使用的模块(因此进程使用的任何DLL都不会但是,从您提供的链接中可以看出,您可以看到利用它来获得该级别功能的方法。