Re[3]: Узнать имя процеса по hwnd
От: Danchik Украина  
Дата: 19.02.08 12:22
Оценка: 9 (1)
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, _Ursus_, Вы писали:


_U_>>Во-первых, нет такого понятия, как "имя процесса". То, что показывает TaskMgr — это имя исполняемого модуля. Получить его можно, перечисляя все процессы в системе (NtQuerySystemInformation(), Process32First()/Process32Next() — выбирайте по вкусу), в этом списке будет и интересующий вас процесс


А>Точнее поставлю вопрос. Как по HWND, не просто перечисляя все процессы в системе, а имея конкретный HWND окна узнать имя исполняющего модуля?


Конкретный ответ, таких способов нет


Дальше разжевывать или проявите смекалку?
Узнать имя процеса по hwnd
От: Аноним  
Дата: 19.02.08 08:00
Оценка:
Доброго времи суток форумчане! Вопрос следующий: как узнать имя процеса по hwnd. Просматрел многие форумы и не нашёл ответа, только узнал как получить имя класса, заголовок окна, PID процесса. Хотелось бы узнать как получить имя процесса как в диспечере задач(имя образа).

20.02.08 13:04: Перенесено модератором из 'Delphi & Builder' — Hacker_Delphi
Re: Узнать имя процеса по hwnd
От: _Ursus_  
Дата: 19.02.08 08:18
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Доброго времи суток форумчане! Вопрос следующий: как узнать имя процеса по hwnd. Просматрел многие форумы и не нашёл ответа, только узнал как получить имя класса, заголовок окна, PID процесса. Хотелось бы узнать как получить имя процесса как в диспечере задач(имя образа).


Во-первых, нет такого понятия, как "имя процесса". То, что показывает TaskMgr — это имя исполняемого модуля. Получить его можно, перечисляя все процессы в системе (NtQuerySystemInformation(), Process32First()/Process32Next() — выбирайте по вкусу), в этом списке будет и интересующий вас процесс
Re[2]: Узнать имя процеса по hwnd
От: Аноним  
Дата: 19.02.08 11:06
Оценка:
Здравствуйте, _Ursus_, Вы писали:

_U_>Во-первых, нет такого понятия, как "имя процесса". То, что показывает TaskMgr — это имя исполняемого модуля. Получить его можно, перечисляя все процессы в системе (NtQuerySystemInformation(), Process32First()/Process32Next() — выбирайте по вкусу), в этом списке будет и интересующий вас процесс


Точнее поставлю вопрос. Как по HWND, не просто перечисляя все процессы в системе, а имея конкретный HWND окна узнать имя исполняющего модуля?
Re[3]: Узнать имя процеса по hwnd
От: Rook Россия http://www.alsedi.com
Дата: 19.02.08 20:56
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Точнее поставлю вопрос. Как по HWND, не просто перечисляя все процессы в системе, а имея конкретный HWND окна узнать имя исполняющего модуля?
Никак, только перебором.

Просто Process ID получить можно: GetWindowThreadProcessId(HWND, @PID);

Но для того чтобы получить имя процесса придется использовать перебор, либо загонять PID и имя процесса (образа в Vista) в массив и идти по индексам, хотя это, на мой взгляд, муторно в Delphi. Плюс снятие снапшота и перебор, если реализовать его правильно, будет затрачивать незначительное процессорное время.
Alex
Re[4]: Узнать имя процеса по hwnd
От: Lexus_  
Дата: 20.02.08 09:34
Оценка:
Здравствуйте, Rook, Вы писали:

R>Никак, только перебором.


R>Просто Process ID получить можно: GetWindowThreadProcessId(HWND, @PID);

PID по hwnd я могу получить, спасибо. Вот встаёт тогда вопрос как можно получить по PID(если по HWND муторно) получить имя исполняемого модуля?
Пишу на Билдере. Вот такой у меня код получился.
//узнать ПИД процесса
unsigned long* pPid; //LPDWORD
void *hg; //HGLOBAL

hg = GlobalAlloc(GMEM_SHARE,sizeof(unsigned long));
pPid = (unsigned long *)GlobalLock(hg);

GetWindowThreadProcessId(win,pPid);

Но как теперь из этого всего получить имя запускаемого модуля(как в диспетчере задач имя образа). Подскажите кто сможет с примером, а то уже третий день не могу найти нигде. Извините за тупость, но может кто подскажет с примером на Builder.
Заранее благодарен.
Re[4]: Узнать имя процеса по hwnd
От: Macr0s Россия  
Дата: 20.02.08 10:18
Оценка:
Здравствуйте, Danchik, Вы писали:

D>

D>Дальше разжевывать или проявите смекалку?


Еще вариант:

GetWindowThreadProcessId — получили ID процесса.
OpenProcess — открыли процесс и получили его хэндл
GetProcessImageFileName — получаем имя процесса

Один момент: GetProcessImageFileName Requires Psapi.dll.
Перед тем, как улучшиться, ситуация ухудшается. (из законов Мерфи)
Re[5]: Узнать имя процеса по hwnd
От: Hacker_Delphi Россия  
Дата: 20.02.08 10:47
Оценка:
Здравствуйте, Lexus_, Вы писали:

L_>Но как теперь из этого всего получить имя запускаемого модуля(как в диспетчере задач имя образа). Подскажите кто сможет с примером, а то уже третий день не могу найти нигде. Извините за тупость, но может кто подскажет с примером на Builder.


Уже 20 раз за последнее время пробегало в форуме WinAPI да и тебе уже говорили:

Конкретный ответ, таких способов нет

GetWindowThreadProcessId — взяли процес — уже сделано...

CreateToolhelp32Snapshot — вызвали с TH32CS_SNAPPROCESS
Process32First — получили первый процес
Process32Next — следующий и тд

Дальше разжевывать или проявите смекалку?

... << RSDN@Home 1.2.0 alpha rev. 790>>
Если при компиляции и исполнении вашей программы не происходит ни одной ошибки — это ошибка компилятора :)))
Re[5]: Узнать имя процеса по hwnd
От: Rook Россия http://www.alsedi.com
Дата: 20.02.08 13:08
Оценка:
Здравствуйте, Lexus_, Вы писали:
L_>Но как теперь из этого всего получить имя запускаемого модуля(как в диспетчере задач имя образа). Подскажите кто сможет с примером, а то уже третий день не могу найти нигде. Извините за тупость, но может кто подскажет с примером на Builder.
L_>Заранее благодарен.

Под билдер не могу, могу под дельфи. Но переписать, насколько я помню, не трудно и билдер умеет работать с паскалевскими файлами.

Я использую вот это, но не рекомендую использовать для циклических операций будет съедать много процессорного времени. Ружна оптимизация снятия снапшотов, она самая ресурсоёмкая получилась:

function RunningProcessesList(const List: TStrings; FullPath: Boolean): Boolean;
  
function ProcessFileName(PID: DWORD): string;
  var
    Handle: THandle;
  begin
    Result := '';
    Handle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PID);
    if Handle <> 0 then
      try
        SetLength(Result, MAX_PATH);
        if FullPath then
        begin
          if GetModuleFileNameEx(Handle, 0, PChar(Result), MAX_PATH) > 0 then
            SetLength(Result, StrLen(PChar(Result)))
          else
            Result := '';
        end
        else
        begin
          if GetModuleBaseNameA(Handle, 0, PChar(Result), MAX_PATH) > 0 then
            SetLength(Result, StrLen(PChar(Result)))
          else
            Result := '';
        end;
      finally
        CloseHandle(Handle);
      end;
  end;
  
function BuildListTH: Boolean;
  var
    SnapProcHandle: THandle;
    ProcEntry: TProcessEntry32;
    NextProc: Boolean;
    FileName: string;
  begin
    SnapProcHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    Result := (SnapProcHandle <> INVALID_HANDLE_VALUE);
    if Result then
      try
        ProcEntry.dwSize := SizeOf(ProcEntry);
        NextProc := Process32First(SnapProcHandle, ProcEntry);
        while NextProc do
        begin
          if ProcEntry.th32ProcessID = 0 then
          begin
            FileName := RsSystemIdleProcess;
          end
          else
          begin
            if IsWin2k or IsWinXP then
            begin
              FileName := ProcessFileName(ProcEntry.th32ProcessID);
              if FileName = '' then
                FileName := ProcEntry.szExeFile;
            end
            else
            begin
              FileName := ProcEntry.szExeFile;
              if not FullPath then
                FileName := ExtractFileName(FileName);
            end;
          end;
          List.AddObject(FileName, Pointer(ProcEntry.th32ProcessID));
          NextProc := Process32Next(SnapProcHandle, ProcEntry);
        end;
      finally
        CloseHandle(SnapProcHandle);
      end;
  end;
  
function BuildListPS: Boolean;
  var
    PIDs: array [0..1024] of DWORD;
    Needed: DWORD;
    I: Integer;
    FileName: string;
  begin
    Result := EnumProcesses(@PIDs, SizeOf(PIDs), Needed);
    if Result then
    begin
      for I := 0 to (Needed div SizeOf(DWORD)) - 1 do
      begin
        case PIDs[I] of
          0:
            FileName := RsSystemIdleProcess;
          2:
            if IsWinNT4 then
              FileName := RsSystemProcess
            else
              FileName := ProcessFileName(PIDs[I]);
            8:
            if IsWin2k or IsWinXP then
              FileName := RsSystemProcess
            else
              FileName := ProcessFileName(PIDs[I]);
            else
              FileName := ProcessFileName(PIDs[I]);
        end;
        if FileName <> '' then
          List.AddObject(FileName, Pointer(PIDs[I]));
      end;
    end;
  end;
begin
  if IsWin3X or IsWinNT4 then
    Result := BuildListPS
  else
    Result := BuildListTH;
end;

function GetProcessNameFromWnd(Wnd: HWND): string;
var
  List: TStringList;
  PID: DWORD;
  I: Integer;
begin
  Result := '';
  if IsWindow(Wnd) then
  begin
    PID := INVALID_HANDLE_VALUE;
    GetWindowThreadProcessId(Wnd, @PID);
    List := TStringList.Create;
    try
      if RunningProcessesList(List, True) then
      begin
        I := List.IndexOfObject(Pointer(PID));
        if I > -1 then
          Result := List[I];
      end;
    finally
      List.Free;
    end;
  end;
end;


вызов через filename := GetProcessNameFromWnd(window_handle);
Alex
Re[6]: Узнать имя процеса по hwnd
От: Lexus_  
Дата: 21.02.08 10:00
Оценка:
R>Под билдер не могу, могу под дельфи. Но переписать, насколько я помню, не трудно и билдер умеет работать с паскалевскими файлами.
Ну вот, это почти то, что надо. Вот опять проблемка. Я так уже пытался сделать, но получается какае-то ерунда.
Вот мой код

unsigned long* pPid; //LPDWORD
void *hg; //HGLOBAL
HWND hWnd;
// получаю HWND текущего активного окна в виндовс
hWnd = GetForegroundWindow();

hg = GlobalAlloc(GMEM_SHARE,sizeof(unsigned long));
pPid = (unsigned long *)GlobalLock(hg);
//узнаю PID текущего окна в виндовс
GetWindowThreadProcessId(hWnd,pPid);

DWORD PID;
HANDLE MyHandle;
//беру указатель процесса на данный ПИД
MyHandle = OpenProcess(PROCESS_QUERY_INFORMATION || PROCESS_VM_READ, false, PID);
char s[MAX_PATH];

//пытаюсь прочитать по указателю с помошью вот этой функции имя,
//но получается ерунда. Насколько я понял, то дело в том,
//что эта функция получает указатель на модуль(первый параметр), а я ей передаю указатель но процесс
// а вот функция GetModuleFileNameExА(то что надо, насколько я понял надо). Для неё надо подключить библиотеку Psapi.h, но после подключения этой библиотеки компилятор ругается на
[Linker Error] Unresolved external 'GetModuleFileNameExA' referenced from D:\ПАПКА\ASDF.OBJ
GetModuleFileName(MyHandle, s, MAX_PATH);
В переменной s получается набор беспорядочный знаков.
Может кто подскажет как использовать данную функцию GetModuleFileNameExA (msdn посмотрел, но ничего там не нашёл).
Rook, Вы писали свой код, а вы подключали какие либо библиотеки для использования функциями GetModuleFileNameEx или GetModuleBaseNameA?
Re[6]: Узнать имя процеса по hwnd
От: Lexus_  
Дата: 21.02.08 12:16
Оценка:
Здравствуйте, Rook, Вы писали:

R>Под билдер не могу, могу под дельфи. Но переписать, насколько я помню, не трудно и билдер умеет работать с паскалевскими файлами.


R>Я использую вот это, но не рекомендую использовать для циклических операций будет съедать много процессорного времени. Ружна оптимизация снятия снапшотов, она самая ресурсоёмкая получилась:


Спасибо Вас за помощь. Наконец-то разобрался
Вот привожу мой код на С++(писал на Билдере), может кому пригодится:

AnsiString GetProcessName(HWND hWnd)
{
//PID -процесса
unsigned long * PID;
//указатель на процесс
HANDLE hProc;
//имя процесса
char ProcessName[80];
//указатель на модуль
HMODULE ahMod [10];
DWORD dwNeeded;
void *hg; //HGLOBAL

hg = GlobalAlloc(GMEM_SHARE,sizeof(unsigned long));
PID = (unsigned long *)GlobalLock(hg);

//получить ПИД процесса
GetWindowThreadProcessId(hWnd,PID);

//по ПИД получить указатель на процесс
hProc = OpenProcess (PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,
FALSE,
*PID); // PID должен быть обьявлен как DWORD
if (hProc)
{
if (EnumProcessModules (hProc,
ahMod,
sizeof(ahMod),
&dwNeeded))
{
if (GetModuleBaseName (hProc,
ahMod[0],
ProcessName,
sizeof(ProcessName)))
{
return ProcessName;
}
else
{
return "";
}
}
CloseHandle (hProc);
}
}


Пример вызовы(узнать имя процесса активного окна)
GetProcessName(GetForegroundWindow()));
Возвращает переменную с именем типа AnsiString
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.