На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! user posted image
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.

Соблюдайте общие правила форума

Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как запустить программу/файл? (и дождаться ее завершения)
5. Как перехватить API-функции, поставить hook? (перехват сообщений от мыши, клавиатуры - внедрение в удаленное адресное прстранство)
... (продолжение следует) ...

Внимание:
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки - бан.
Мат в разделе - бан на три месяца...

Полезные ссылки:
user posted image MSDN Library user posted image FAQ раздела user posted image Поиск по разделу user posted image Как правильно задавать вопросы


Выразить свое отношение к модераторам раздела можно здесь: user posted image Rouse_, user posted image Krid

Модераторы: Rouse_, Krid
  
> Получение имени процесса по PID , ошибка для Chrome
    Доброго дня! Коллеги, пытаюсь на Delphi XE3 и XE7 получить имя процесса по его PID.
    Нашел несколько вариантов как это сделать:
    1). сделать OpenProcess, а дальше GetModuleFileNameEx
    2). использовать GetProcessImageFileName

    Первый вариант работает для обычных приложений, но при попытке получить имя процесса браузера (Chrome, например), получаю ошибку:
    System error. Code: 299. Запрос ReadProcessMemory или WriteProcessMemory был выполнен только частично.

    Код как получаю:
    ExpandedWrap disabled
      var
        AppPath: String;
        WinH: THandle;
        PrId: Cardinal;
        hProcess: THandle;
        path: array[0..MAX_PATH - 1] of char;
        cProcName:array[0..MAX_PATH] of Char;
      begin
        WinH:= GetForegroundWindow;
        GetWindowThreadProcessID(WinH, @PrId);
       
       
        hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, PrID);
        if hProcess <> 0 then
          try
            if GetModuleFileNameEx(hProcess, 0, path, MAX_PATH) = 0 then
              RaiseLastOSError;
            AppPath := path;
            Edit5.Text:= AppPath;
          finally
            CloseHandle(hProcess)
          end
        else
          RaiseLastOSError;


    Что касается второго способа, то для него пришлось объявить:
    ExpandedWrap disabled
      function GetProcessImageFileName(hProcess:THandle; lpImageFileName:LPTSTR; nSize:DWORD):DWORD; stdcall;
       external 'PSAPI.dll' name 'GetProcessImageFileNameW';


    И использование:
    ExpandedWrap disabled
      if GetProcessImageFileName(PrId,@cProcName,MAX_PATH) <> 0 then //SizeOf(cProcName));
        begin
          AppPath := cProcName;
          Edit6.Text:= AppPath;
        end else showmessage(SysErrorMessage(GetLastError()));


    Но возвращает функция всегда 0. Сообщение об ошибке "Неверный дескриптор".

    В обоих случаях не могу сообразить, как исправить положение ((

    Мне нужно починить любой из способов, который сможет выдавать имя процесса для любого из приложений, в том числе браузеров. Буду благодарен совету по сути вопроса.
      Возможно стоит использовать вот этот способ
      ExpandedWrap disabled
        function GetModuleNameByPID(PID: Integer): String;
        var
           h: THANDLE;
           e: TPROCESSENTRY32;
        begin
           Result := '<not found>';
           h := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
           if h <> INVALID_HANDLE_VALUE then
           begin
              if Process32First(h, e) then repeat
                 if e.th32ProcessID = PID then begin
                    Result := copy(e.szExeFile, Length(e.szExeFile));
                    break;
                 end;
              until not Process32Next(h, e);
              CloseHandle(h);
           end;
        end;
      Сообщение отредактировано: macomics -
        macomics, благодарю за ответ. Но к сожалению, этот код завершается на строке:
        if Process32First(h, e) then repeat
        Process32First возвращает false.
          Тогда попробуйте константу TH32CS_SNAPALL
            Цитата macomics @

            к сожалению, аналогично. Уточню, что выполняю приложение на Вин 7 х64. Использование дальнейшее предполагается на Win 10-11
              У меня на Win 7 x64 этот способ отлично работал. Вы уверены, что у вас в системе нету программ, которые скрывают свое присутствие от taskmgr. Этим способом taskmgr получает список процессов. Он должен работать.
                SilverShield, во втором случае ты передаёшь в GetProcessImageFileName первым параметром PID, а надо handle. Т.е. тебе нужно сначала открыть процесс (как в первом случае) и полученный дескриптор передать в эту ф-цию.
                Но в любом случае, чтобы получать имена всех (почти) процессов, твоя прога должна быть запущена с правами админа.
                  Цитата SilverShield @
                  if Process32First(h, e) then repeat
                  Process32First возвращает false.

                  Надо установить поле e.dwSize = sizeof( PROCESSENTRY32 )
                  Taking a Snapshot and Viewing Processes
                    Цитата ЫукпШ @
                    Надо установить поле e.dwSize = sizeof( PROCESSENTRY32 )

                    Спасибо, что уточнили. По памяти написал функцию - мой недочет.

                    Рабочий вариант:
                    ExpandedWrap disabled
                      function GetModuleNameByPID(PID: Integer): String;
                      var
                         h: THANDLE;
                         e: TPROCESSENTRY32;
                      begin
                         Result := '<not found>';
                         h := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
                         if h <> INVALID_HANDLE_VALUE then
                         begin
                            e.dwSize := SizeOf(TPROCESSENTRY32);
                            if Process32First(h, e) then repeat
                               if e.th32ProcessID = PID then begin
                                  Result := copy(e.szExeFile, Length(e.szExeFile));
                                  break;
                               end;
                            until not Process32Next(h, e);
                            CloseHandle(h);
                         end;
                      end;
                    Сообщение отредактировано: macomics -
                      Цитата Krid @
                      во втором случае ты передаёшь в GetProcessImageFileName первым параметром PID, а надо handle.

                      Благодарю! С дескриптором работает!

                      macomics, ЫукпШ, благодарю! Этот вариант тоже работает как надо!

                      Вопрос решен!
                      1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                      0 пользователей:


                      Рейтинг@Mail.ru
                      [ Script execution time: 0,0386 ]   [ 15 queries used ]   [ Generated: 6.10.24, 08:09 GMT ]