Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2011.12.18;
Скачать: [xml.tar.bz2];

Вниз

Как правильней получить список процессов?   Найти похожие ветки 

 
WanderBuild   (2009-01-23 13:10) [0]

Нашел в сети несколько примеров, остановился на двух, оба они делают одно и то же (возвращают список процессов), но разными методами.
Какой на ВАШ профессиональный взгляд метод, более правильно использовать?
Код первого примера:

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
       FileName := ProcessFileNameByPID(ProcEntry.th32ProcessID, True);
       if FileName = "" then FileName := ProcEntry.szExeFile;
      Form1.ListBox1.Items.AddObject(FileName, Pointer(ProcEntry.th32ProcessID));
      NextProc := Process32Next(SnapProcHandle, ProcEntry);
    end;
  finally
    CloseHandle(SnapProcHandle);
  end;


Код второго примера:

EnumProcesses(@PIDArray, SizeOf(PIDArray), cb);
 ProcCount := cb div SizeOf(DWORD);
 for I := 0 to ProcCount - 1 do
 begin
   hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PIDArray[I]);
   if not (hProcess=0) then
   begin
     EnumProcessModules(hProcess, @hMod, SizeOf(hMod), cb);
     GetModuleFilenameEx(hProcess, hMod, ModuleName, SizeOf(ModuleName));
     Form1.ListBox1.Items.Add(ModuleName);
     CloseHandle(hProcess);
   end;
 end;


И второй вопрос: как определить пользователя, под которым работает тот или иной процесс?


 
multiflex   (2009-01-23 13:59) [1]

раз http://msdn.microsoft.com/en-us/library/ms682623(VS.85).aspx
два http://gocoding.com/page.php?al=process_username


 
Сергей М. ©   (2009-01-23 14:00) [2]

http://www.delphisources.ru/pages/faq/base/get_run_processes.html


 
WanderBuild   (2009-01-23 14:45) [3]

Спасибо, мужики, за реально лаконичные ответы :)
насколько я увидел в обоих примерах используется код, аналогичный моему второму примеру.
Просто интересно узнать, имеет ли право на жизнь первый мой пример, поскольку результатом его выполнения является список, аналогичный второму примеру, т.е. они оба работают.

Да, еще интересный момент:
процессы с именем csrss.exe и winlogon.exe оба примера возвращают вот в таком загадочном виде (остальные нормально)
\??\С:\Windows\System32\csrss.exe
\??\С:\Windows\System32\winlogon.exe
вот то, что выделил жирным, никто не знает что это за муть?


 
Сергей М. ©   (2009-01-23 15:56) [4]


> они оба работают


2-й не будет работать под Win9x/Me


 
WanderBuild   (2009-01-23 16:15) [5]

>>2-й не будет работать под Win9x/Me
ну этих мамонтов я думаю уже не встречу в этой жизни, так что не критично. Просто интересно, там же список добывается совершенно иным способом (CreateToolhelp32Snapshot).

И по поводу артифактов \??\ ни у кого мыслей нет?


 
clickmaker ©   (2009-01-23 16:39) [6]

> И по поводу артифактов \??\

насколько я помню, это эквивалент \Device\Harddrive0


 
clickmaker ©   (2009-01-23 16:43) [7]

вернее даже \Device\Harddrive0\Partition1


 
Игорь Шевченко ©   (2009-01-23 17:11) [8]


> И по поводу артифактов \??\ ни у кого мыслей нет?


пишется артефакт

мысль есть - ?? это корень пространства имен DOS-устройств диспетчера объектов Windows

Легче стало ?


 
Игорь Шевченко ©   (2009-01-23 17:12) [9]


> вернее даже \Device\Harddrive0\Partition1


неа


 
Eraser ©   (2009-01-23 17:35) [10]

> [0] WanderBuild   (23.01.09 13:10)


> И второй вопрос: как определить пользователя, под которым
> работает тот или иной процесс?

способов получения списка процессов еще, как минимум 2, это доступных из user-mode, возможно и еще есть.
в вашем случае полезнее способ с использованием WTSEnumerateProcesses.


 
clickmaker ©   (2009-01-23 17:35) [11]

> Игорь Шевченко ©   (23.01.09 17:12)

ну хоть первое слово угадал - Device -)


 
clickmaker ©   (2009-01-23 17:36) [12]

> способов получения списка процессов еще, как минимум 2,
> это доступных из user-mode

ага, еще через WMI можно


 
WanderBuild   (2009-01-23 18:05) [13]

Всем спасибо за быстрый отклик и ответы, считаю вопрос исчерпанным.

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


 
Игорь Шевченко ©   (2009-01-23 18:44) [14]

Имена, начинающиеся с \??\ (или с \Device\..) называются ядерными именами, потому как внутре ядро работает именно с такими именами и ни с какими другими.

Тем не менее, почему именно у этих двух процессов такие имена исполняемых файлов - потому что первый (csrss.exe) запускается процессом smss.exe, а второй (winlogon.exe) запускается процессом csrss.exe.
Отличительная особенность этих процессов состоит в том, что они не используют подсистему Win32 для запуска процессов - в случае smss.exe ее еще не существует, а в случае csrss.exe - он мало того, что ее инициализирует, так еще является и серверной ее частью (в частности, отрабатывает CreateProcess).

Поэтому в этих процессах используются только вызовы функций Native API, которые отличаются тем, что не понимают в качестве имен файлов строки, начинающиеся на C:\, D:\ и так далее. Зато они понимают имена, которые содержатся в пространстве имен диспетчера объектов Windows (он к тому времени уже проинициализирован, ядерные имена для пути к разделам диска прописаны, драйверы для дисков установлены, в общем, есть все данные, чтобы по ядерному имени добраться до файла).

Собственно, такое имя можно получить и из привычного имени файла, вызвав RtlPathNameToNtPathName, и, соответственно, наоборот, из ядерного имени файла можно получить (не всегда) привычное.


 
WanderBuild   (2009-01-26 09:16) [15]

>>Игорь Шевченко - а теперь огромное спасибо за крайне интересную и весьма редкую информацию. И ещё раз извините.


 
имя   (2009-09-15 15:02) [16]

Удалено модератором


 
Игорь ©   (2009-09-15 16:15) [17]


> WanderBuild   (23.01.09 13:10)  
>
> И второй вопрос: как определить пользователя, под которым
> работает тот или иной процесс?


type
 TWinStationGetProcessSid = function(hServer: Cardinal;
   ProcessId: Cardinal;
   ProcessStartTime: _FILETIME;
   pProcessUserSid: PByte;
   var dwSidSize: Cardinal): Boolean; stdcall;

var
 _WinStationGetProcessSid: TWinStationGetProcessSid;

function _GetOSVersion: Cardinal;
var
 OSVersionInfo: TOSVersionInfo;
begin
 Result:= 0;
 FillChar(OSVersionInfo, Sizeof(OSVersionInfo), 0);
 OSVersionInfo.dwOSVersionInfoSize:= SizeOf(OSVersionInfo);
 if GetVersionEx(OSVersionInfo) then
 begin
   if OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT then
   begin
     if OSVersionInfo.dwMajorVersion = 5 then
     begin
       if OSVersionInfo.dwMinorVersion = 0 then
         Result:= 50
       else if OSVersionInfo.dwMinorVersion = 2 then
         Result:= 52
       else if OSVersionInfo.dwMinorVersion = 1 then
         Result:= 51
     end;
     if OSVersionInfo.dwMajorVersion = 6 then
     begin
       if OSVersionInfo.dwMinorVersion = 0 then
         Result:= 60
       else if OSVersionInfo.dwMinorVersion = 1 then
         Result:= 61;
     end;
   end;
 end;
end;

function _EnablePrivilege(Privilege: string): Boolean;
var
 TokenHandle: THandle;
 TokenPrivileges: TTokenPrivileges;
 ReturnLength: Cardinal;
begin
 Result:= False;
 if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, TokenHandle) then
 begin
   LookupPrivilegeValue(nil, PChar(Privilege), TokenPrivileges.Privileges[0].Luid);
   TokenPrivileges.PrivilegeCount:= 1;
   TokenPrivileges.Privileges[0].Attributes:= SE_PRIVILEGE_ENABLED;
   if AdjustTokenPrivileges(TokenHandle, False, TokenPrivileges, 0, nil, ReturnLength) then
     Result:= True;
 end;
end;

function _GetProcessUserAndDomainName_1(PID: DWORD; var UserName: string; var DomainName: string): Boolean;
type
 TOKEN_USER = record
   User: TSidAndAttributes;
 end;
 PTOKEN_USER = ^TOKEN_USER;
 TTOKEN_USER = TOKEN_USER;
var
 hToken: THandle;
 cbBuf: Cardinal;
 ptiUser: PTOKEN_USER;
 snu: SID_NAME_USE;
 Domain, User: array[0..1024] of Char;
 chUser: DWORD;
 chDomain: DWORD;
 hProcess: THandle;
begin
 Result:= False;
 UserName:= "";
 DomainName:= "";
 chDomain:= 1024;
 chUser:= 1024;
 hProcess:= OpenProcess(MAXIMUM_ALLOWED, False, PID);
 if hProcess <> 0 then
 begin
   if OpenProcessToken(hProcess, MAXIMUM_ALLOWED, hToken) then
   begin
     try
       GetTokenInformation(hToken, TokenUser, nil, 0, cbBuf);
       GetMem(ptiUser, cbBuf);
       if GetTokenInformation(hToken, TokenUser, ptiUser, cbBuf, cbBuf) then
       begin
         if LookupAccountSid(nil, ptiUser.User.Sid, User, chUser, Domain, chDomain, snu) then
         begin
           UserName:= User;
           DomainName:= Domain;
         end;
       end;
       FreeMem(ptiUser);
     finally
       CloseHandle(hToken);
     end;
   end;
 end;
end;

function _GetProcessUserAndDomainName_2(PID: DWORD; var UserName: string; var DomainName: string): Boolean;
var
 hProcess: THandle;
 lpCreationTime, lpExitTime, lpKernelTime, lpUserTime: _FILETIME;
 pProcessUserSid: Pointer;
 User, Domain: PChar;
 cbUser, cbDomain: Cardinal;
 dwSidSize: Cardinal;
 CreateTime: TSystemTime;
begin
 Result:= False;
 UserName:= "";
 DomainName:= "";
 if _GetOSVersion >= 60 then
   hProcess:= OpenProcess($1000, False, PID)
 else
   hProcess:= OpenProcess(MAXIMUM_ALLOWED, False, PID);
 if hProcess <> 0 then
 begin
   try
     dwSidSize:= 0;
     GetProcessTimes(hProcess, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime);
     FileTimeToSystemTime(lpCreationTime, CreateTime);
     _WinStationGetProcessSid(0, PID, lpCreationTime, nil, dwSidSize);
     GetMem(pProcessUserSid, dwSidSize);
     if _WinStationGetProcessSid(0, PID, lpCreationTime, pProcessUserSid, dwSidSize) then
     begin
       cbUser:= 0;
       cbDomain:= 0;
       LookupAccountSid(nil, pProcessUserSid, nil, cbUser, nil, cbDomain, dwSidSize);
       GetMem(User, cbUser);
       GetMem(Domain, cbDomain);
       Result:= LookupAccountSid(nil, pProcessUserSid, User, cbUser, Domain, cbDomain, dwSidSize);
       SetLength(UserName, cbUser);
       SetLength(DomainName, cbDomain);
       lstrcpy(PChar(UserName), User);
       lstrcpy(PChar(DomainName), Domain);
       FreeMem(User);
       FreeMem(Domain);
     end;
     FreeMem(pProcessUserSid);
   finally
     CloseHandle(hProcess);
   end;
 end;
end;

function _GetProcessUserAndDomainName(PID: DWORD; var UserName: string; var DomainName: string): Boolean;
begin
 if _GetOSVersion > 50 then
   Result:= _GetProcessUserAndDomainName_2(PID, UserName, DomainName)
 else
   Result:= _GetProcessUserAndDomainName_1(PID, UserName, DomainName); //Windows 20000
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 _EnablePrivilege("SeDebugPrivilege");
 if _GetOSVersion > 50 then
   @_WinStationGetProcessSid:= GetProcAddress(LoadLibrary("winsta.dll"), "WinStationGetProcessSid");
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 User, Domain: String;
begin
 _GetProcessUserAndDomainName(1156, User, Domain);
 ShowMessage(Domain + "\" + User);
end;


 
brother ©   (2009-09-16 04:24) [18]

> а теперь огромное спасибо за крайне интересную и весьма
> редкую информацию.

вот те еще бонусом:)
http://www.lookinfo.org/2007/08/05/jetapy_zagruzki_windows_xp.html


 
AntiZOG   (2009-09-17 18:09) [19]


> SnapProcHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,
>  0);


Работает в WOW64, показывает как 64-битные процессы, так и 32-битные.

Второй в WOW64 показывает только 32-х битные.



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2011.12.18;
Скачать: [xml.tar.bz2];

Наверх









Память: 0.65 MB
Время: 0.027 c
2-1315739001
я
2011-09-11 15:03
2011.12.18
ftGraphic, DBGrid,ClientDataSet,DataSource


2-1315609282
RAD
2011-09-10 03:01
2011.12.18
Последовательность вычисления параметров


15-1314544353
alexdn
2011-08-28 19:12
2011.12.18
Переименовать файл в винде


1-1277298765
granulated
2010-06-23 17:12
2011.12.18
EInvalidPointer после выхода из функции.


4-1252399230
Jeyson
2009-09-08 12:40
2011.12.18
одно и тоже консольное приложение работает по разному





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский