Windows C ++ - Как получить PID процесса с его пути

0

Похоже на C++ Windows - Как получить путь к процессу с его PID, но наоборот: как я могу получить pid из заданного пути?

Я пытаюсь написать средство обновления, и я хочу посмотреть, используется ли exe. Затем, если он используется, я хочу дождаться завершения процесса. Поэтому я хочу получить PID процесса, принадлежащий файлу.

  • 2
    Вы должны найти все живые процессы и посмотреть, какой из них запущен, с вашего пути, если таковой имеется.
  • 0
    Разве вы не можете просто попытаться открыть файл EXE для чтения один раз в секунду? Когда это удастся, вы можете идти.
Теги:

1 ответ

2
Лучший ответ

Вот быстрый и простой способ сделать то, что вы ищете. Используя QueryFullProcessImageName, вы можете выполнить быструю проверку.

Вещи, которые могут привести к тому, что следующий код не будет работать по желанию:

  • Если у вас нет разрешений для просмотра процесса, вы не сможете просмотреть информацию.
  • Если процесс равен 64 бит, и вы запускаете приложение как 32-битное, вы увидите идентификатор процесса, но вы не можете открыть его дескриптор процесса.

Пример:

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, используемая процессом, не будет идентифицирована, однако из предоставленной вами ссылки вы можете увидеть способы использования этого для достижения такого уровня функциональности.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню