Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Получить Process ID по Process Handle

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки

Открыть новую тему     Написать ответ в эту тему

OldGopher



Silver Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Есть вопрос.  
Как получить в программе под Win32 id некоего процесса, на который имеется handle.
Обратно все просто: OpenProcess и из id получается вполне приличный handle.  
 
В Windows NT4+ все решается вызовом функции ядра из NTDLL.DLL.
ZwQueryInformationProcess довольно просто возвращает id процесса по его handle и в нагрузку - id родительского процесса, что тоже может быть полезно.
 
Вопрос: как сделать подобное в Windows 98/ME?  
Windows 95 интересует меньше...

Всего записей: 3802 | Зарегистр. 25-10-2001 | Отправлено: 22:34 06-04-2005
KADABRA



Великий покусатель
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
OldGopher
В Ритхере есть хороший пример.
Вот кусок:

Код:
 
VOID Dlg_PopulateProcessList(HWND hwnd) {
 
   HWND hwndList = GetDlgItem(hwnd, IDC_PROCESSMODULELIST);
   SetWindowRedraw(hwndList, FALSE);
   ComboBox_ResetContent(hwndList);
 
   CToolhelp thProcesses(TH32CS_SNAPPROCESS);
   PROCESSENTRY32 pe = { sizeof(pe) };
   BOOL fOk = thProcesses.ProcessFirst(&pe);
   for (; fOk; fOk = thProcesses.ProcessNext(&pe)) {
      TCHAR sz[1024];
 
      // Place the process name (without its path) & ID in the list
      PCTSTR pszExeFile = _tcsrchr(pe.szExeFile, TEXT('\\'));
      if (pszExeFile == NULL) pszExeFile = pe.szExeFile;
      else pszExeFile++; // Skip over the slash
          wsprintf(sz, TEXT("%s     (0x%08X)"), pszExeFile, pe.th32ProcessID);
      int n = ComboBox_AddString(hwndList, sz);
 
      // Associate the process ID with the added item
      ComboBox_SetItemData(hwndList, n, pe.th32ProcessID);
   }
   ComboBox_SetCurSel(hwndList, 0);  // Select the first entry
 
   // Simulate the user selecting this first item so that the
   // results pane shows something interesting
   FORWARD_WM_COMMAND(hwnd, IDC_PROCESSMODULELIST,  
      hwndList, CBN_SELCHANGE, SendMessage);
 
   SetWindowRedraw(hwndList, TRUE);
   InvalidateRect(hwndList, NULL, FALSE);
}
 


----------
Это не подпись.

Всего записей: 1718 | Зарегистр. 14-07-2003 | Отправлено: 22:54 06-04-2005 | Исправлено: KADABRA, 23:01 06-04-2005
OldGopher



Silver Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
KADABRA
Рихтер... это конечно хорошо. Но мне не поможет энумератор...  
Есть только handle процесса, причем не обязательно полученный через OpenProcess.
Есть такая бяка, как DuplicateHandle.
 
Иметь полный список процессов с их id, конечно полезно, но как сопоставить некий handle какому-то процессу из списка?  
Известно, что ids уникальны внутри системы, а handle - уникальны внутри процесса.
 
Скажем, некий процесс получил свой id, сделал из него handle, потом сгенерил handle внутри другого процесса через DuplicateHandle и передеал тому процессу через WM_COPYDATA.  
Теперь второй процесс, получив handle первого, пригодный для использования в своем поле памяти, хочет получить обратно id. Ку-ку... и энумерация здесь не поможет.

Всего записей: 3802 | Зарегистр. 25-10-2001 | Отправлено: 23:01 06-04-2005
gar

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Может GetWindowThreadProcessId(Wd, @pid) подойдет?

Всего записей: 115 | Зарегистр. 16-04-2004 | Отправлено: 15:56 12-04-2005
MrZeRo



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Всего записей: 831 | Зарегистр. 30-01-2002 | Отправлено: 16:37 12-04-2005 | Исправлено: MrZeRo, 16:58 12-04-2005
OldGopher



Silver Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
gar
Неа... не катит. Процесс по условию может вообще не иметь окон. Да и как угадать, какое окно относится именно к этому хэндлу?  
Хотя задача точно решена, но люди не хотят делиться кодом.  
 
Добавлено:
Там надо лезть прямо в функции ядра. Native API...
 
На Windows NT4-2000-XP все понятно (и то, только с правами администратора), а вот в Windows 98/ME (что б они горели), не выходит-с...
 
 
Добавлено:
И еще две задачи вдогонку:
 
- Как по хэндлу файла найти его полный путь?  
Есть на сайте Микрософта решение для административного режима Windows NT4-XP, если файл ненулевой длины.
Известно, что можно в любых Windows, но только в admin режиме. Как? Секрет sysinternals. За бабки...
 
- как из FILE структуры (см. функции fopen etc) получить скрытый хэндл? Функция _fileno к теме не относится. Здесь вообще нет идей.
 

Всего записей: 3802 | Зарегистр. 25-10-2001 | Отправлено: 12:35 13-04-2005
ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
На Windows NT4-2000-XP все понятно (и то, только с правами администратора), а вот в Windows 98/ME (что б они горели), не выходит-с...

На XPSP1 и выше есть функция GetProcessID  

Цитата:
 
The GetProcessId function retrieves the process identifier of the specified process.
 
DWORD GetProcessId(
  HANDLE Process
);
Parameters
Process
[in] Handle to the process. The handle must have the PROCESS_QUERY_INFORMATION access right.  
Return Values
 
If the function succeeds, the return value is the process identifier of the specified process.
 
If the function fails, the return value is zero. To get extended error information, call GetLastError.
 

Причем все удивляются, почему она не появилась раньше еще под 9х. Это я  на форуме одном англоязычнопм прочитал когда смотрел что может тебе помочь.

Цитата:
- Как по хэндлу файла найти его полный путь?  

Было такое, сам же и спрашивал К модератору здесь даю полный код а не ссылку на страницу, ибо страница была удалена из базы мсдн

Цитата:
 
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <string.h>
#include <psapi.h>
 
#define BUFSIZE 512
 
BOOL GetFileNameFromHandle(HANDLE hFile)  
{
  BOOL bSuccess = FALSE;
  TCHAR pszFilename[MAX_PATH+1];
  HANDLE hFileMap;
 
  // Get the file size.
  DWORD dwFileSizeHi = 0;
  DWORD dwFileSizeLo = GetFileSize(hFile, &dwFileSizeHi);  
 
  if( dwFileSizeLo == 0 && dwFileSizeHi == 0 )
  {
     printf("Cannot map a file with a length of zero.\n");
     return FALSE;
  }
 
  // Create a file mapping object.
  hFileMap = CreateFileMapping(hFile,  
                    NULL,  
                    PAGE_READONLY,
                    0,  
                    1,
                    NULL);
 
  if (hFileMap)  
  {
    // Create a file mapping to get the file name.
    void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1);
 
    if (pMem)  
    {
      if (GetMappedFileName (GetCurrentProcess(),  
                             pMem,  
                             pszFilename,
                             MAX_PATH))  
      {
 
        // Translate path with device name to drive letters.
        TCHAR szTemp[BUFSIZE];
        szTemp[0] = '\0';
 
        if (GetLogicalDriveStrings(BUFSIZE-1, szTemp))  
        {
          TCHAR szName[MAX_PATH];
          TCHAR szDrive[3] = TEXT(" :");
          BOOL bFound = FALSE;
          TCHAR* p = szTemp;
 
          do  
          {
            // Copy the drive letter to the template string
            *szDrive = *p;
 
            // Look up each device name
            if (QueryDosDevice(szDrive, szName, BUFSIZE))
            {
              UINT uNameLen = _tcslen(szName);
 
              if (uNameLen < MAX_PATH)  
              {
                bFound = _tcsnicmp(pszFilename, szName,  
                    uNameLen) == 0;
 
                if (bFound)  
                {
                  // Reconstruct pszFilename using szTemp
                  // Replace device path with DOS path
                  TCHAR szTempFile[MAX_PATH];
                  _stprintf(szTempFile,
                            TEXT("%s%s"),
                            szDrive,
                            pszFilename+uNameLen);
                  _tcsncpy(pszFilename, szTempFile, MAX_PATH);
                }
              }
            }
 
            // Go to the next NULL character.
            while (*p++);
          } while (!bFound && *p); // end of string
        }
      }
      bSuccess = TRUE;
      UnmapViewOfFile(pMem);
    }  
 
    CloseHandle(hFileMap);
  }
  printf("File name is %s\n", pszFilename);
  return(bSuccess);
 



----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 02:07 14-04-2005
zeleniy



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
В книге Программирование в WIN 32API на Visual basic, написано что для Windows 9X надо использовать функцию ToolHelp.
 
Да еще надо привести разницу между  дескриптором процесса (process handle) и идентификатором процесса (process id).
Дескриптор действует в пределах своего процесса, идентификатор работает на системном уровне.
у каждого процесса только один идентификатор, но может быть несколько дескрипторов.
 
И про получение идентификатора - не существет известного способа, определить идентификтор процесса, кроме как получить список всех процессов и выбрать из него тот который требуется.

Всего записей: 777 | Зарегистр. 07-12-2001 | Отправлено: 08:29 14-04-2005
Delphist

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Тык нада просто смотреть Platform SDK - часть MSDN
Tool Help Library - пашет под  
Client: Included in Windows XP, Windows 2000 Professional, Windows Me, Windows 98, and Windows 95.
Server: Included in Windows Server 2003 and Windows 2000 Server.
Header: Declared in Tlhelp32.h.
Library: Use Kernel32.lib.
Там есть пример по пробежке по списку процессов  
и можно найти Id по Handle и наоборот.
 

Всего записей: 114 | Зарегистр. 14-01-2003 | Отправлено: 11:55 14-04-2005
OldGopher



Silver Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Delphist
Да не сработает перечисление всех Id.  
 
Имеется дескриптор Процесса2 в адресном пространстве Процесса1. Ну, и как сопоставить его с набором Id?  
Ведь дескрипторов, как уже замечалось, может быть много, и они могут пересекаться. Т.е. в разных АП могут быть численно совпадающие дескрипторы...
 
В Windows NT4+ есть хорошая функция ZwQueryInformationProcess.
Надо найти подобную в Windows 98+...
 
ShIvADeSt
Вспомнили...  
А если файл пустой, нулевой длины? Слетит Ваш метод. Да и в Windows 98/ME не работает...
 
В MSDN до сих пор вроде как этот код валялется. Я недано лазал...
 
А GetProcessId... да, только с SP1 появилась. Она как раз и вызывает native API группы Zw. Толку то...

Всего записей: 3802 | Зарегистр. 25-10-2001 | Отправлено: 22:28 14-04-2005
ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
OldGopher

Цитата:
А если файл пустой, нулевой длины? Слетит Ваш метод. Да и в Windows 98/ME не работает...  
 
В MSDN до сих пор вроде как этот код валялется. Я недано лазал...

Вчера туда пытался зайти удалили его Поэтому только и привел код. А если файл пустой, то можно туда записать один байт (хэндл то мы имеем) получить путь, и потом обратно этот байт удалить
Насколько я знаю, многие хорошие функции которые есть NT и выше, почему то отсутсвуют в 9х

----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 02:22 15-04-2005
zeleniy



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
OldGopher
 

Цитата:
Ведь дескрипторов, как уже замечалось, может быть много, и они могут пересекаться. Т.е. в разных АП могут быть численно совпадающие дескрипторы...  

Пусть имеется 3 процесса:
Процесс1,
Процесс2,
Процесс3.
В процессе1 у нас имеется дескриптор некоего процесса мы не знаем какого.
Делаем перечисление процессов и видим что дескриптор принадлежит как процессу2 так и процессу3. Что тогда ? Тут надо уже думать как делать отбор процессов.
 
 
 
Добавлено:
Еще можно посмотреть примеры вот здесь может что поможет.
http://www.rsdn.ru/article/qna/baseserv/enumproc.xml

Всего записей: 777 | Зарегистр. 07-12-2001 | Отправлено: 12:35 15-04-2005
OldGopher



Silver Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
zeleniy
Он не может принадлежать двум процессам внутри одного АП. Другое дело, что в общем поле памяти (условно - всех процессов) могут бытьсовпадающие дескрипторы.
 
Проще всего так: возьмите в тестовой программе вызовете функцию OpenProcess на саомого себя (со своим Id), сдублируйте дескриптор с помощью DuplicateHandle, а потом попробуйте найти Id по дублю, игнорируя то, что он заведомо - Вашего процесса.  
 
Все - под Windows 98 или МЕ. Под NT4+ - очевидно... а под XP/SP1+ даже документированно.
 
 
Добавлено:
ShIvADeSt
Я не дообъяснил задачу. Все происодит внутри системных API хуков. Я не могу что-то писать в файлы, т.к. это некорректно внутри реентерабельной зоны.  
 
Касательно нехватки части API в легких Windows, это от того, что эти Windows - порождение 16-ти битного кода. Их системная виртуальная машина - 16-тибитная. Microsoft не решилась лишить юзеров возможности играть в старые игры, и вот, родилась гибридная линия 95/98/МЕ...
 
Потом поумнели, сделали XP Home и ликвидировали 95+ линию. Но у конечных пользователей в Америке скопилось много дешевых рабочих станций. А мне карячиться...
 
Забавно. Статью ликвидировали, но в поисковой системе она еще осталась.  
Может, ее редактируют?

Всего записей: 3802 | Зарегистр. 25-10-2001 | Отправлено: 18:25 15-04-2005
Открыть новую тему     Написать ответ в эту тему

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Получить Process ID по Process Handle


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru