Назад |
|
Скачай демонстрационный проект (26,1 кб)
Наконец последний способ, который мы тут рассмотрим – это использование Terminal Services API. Наверное ты знаешь, что в Windows имеется сервер терминалов. То есть на одной машине могут одновременно работать несколько пользователей. Применительно к локальной машине с Windows XP это выражается в наличии технологии Fast User Switching - быстрого переключения пользователей. Это в общем-то эмуляция многопользовательского режима. Пользователей как бы подключено несколько, а работать может все равно только один. Но процессы, запущенные другими пользователями, все равно остаются в памяти. Чтобы убедиться жми Alt-Ctrl-Del. Появится диспетчер задач. На его вкладке процессы внизу есть галочка «Отображать процессы всех пользователей». Взведи ее и увидишь все запущенные процессы и имена запустивших их пользователей. Для работы с сервером терминалов и существует библиотека Terminal Services API. Вся она находится в Wtsapi32.dll и существует начиная с Microsoft Windows NT 4.0 SP4 Terminal Server Edition. Эта библиотека пользуется другой либой - winsta.dll, и для получения процессов импортирует из нее недокументированные функции WinStationGetAllProcesses и WinStationEnumerateProcesses, которые для своей работы используют RPC (rpcrt4.dll). Дальше в механизмы удаленного вызова процедур мы лезть не будем, т.к. оно нам и не надо :) .
Для нашей задачи понадобится только одна функция WTSEnumerateProcesses:
|
После вызова WTSEnumerateProcesses надо обязательно вызывать WTSFreeMemory, чтобы освободить память занятую под массив структур, т.к. Винда это за тебя не сделает и будет неслабая утечка ресурсов. Для получения более подробной информации о сессии используй функцию WTSQuerySessionInformation.
unit Sample6;
interface
uses Classes;
function FillProcessesList(var slProcesses: TStringList): Boolean;
implementation
uses Windows, SysUtils;
const
WTS_CURRENT_SERVER_HANDLE = 0;
type
PWTS_PROCESS_INFO = ^WTS_PROCESS_INFO;
WTS_PROCESS_INFO = packed record
SessionId: DWORD;
ProcessId: DWORD;
pProcessName: PChar;
pUserSid: PSID;
end;
function WTSEnumerateProcesses(hServer: THandle; Reserved,Version: DWORD;
var ppProcessInfo: PWTS_PROCESS_INFO;
var Count: DWORD): BOOL; stdcall;
external 'wtsapi32.dll'
name 'WTSEnumerateProcessesA';
procedure WTSFreeMemory(pMemory: Pointer); stdcall;
external 'wtsapi32.dll'
name 'WTSFreeMemory';
function FillProcessesList(var slProcesses: TStringList): Boolean;
var
Count, i: DWORD;
pProcessInfo, pCur: PWTS_PROCESS_INFO;
sProcessName: String;
begin
if WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE,
0,1,pProcessInfo,Count)then
begin
for i := 0 to Count - 1 do
begin
pCur := Ptr(DWORD(pProcessInfo) + (i * SizeOf(WTS_PROCESS_INFO)));
if Length(pCur.pProcessName) = 0 then sProcessName := '<íåèçâåñòíî>'
else sProcessName := pCur.pProcessName;
slProcesses.Add('Name: ' + sProcessName +
' PID: ' + IntToStr(pCur.ProcessId) +
' Session ID: ' + IntToStr(pCur.SessionId));
end;
WTSFreeMemory(pProcessInfo);
Result := True;
end
else
Result := False;
end;
end.
Есть конечно же и другие способы получения списка
процессов. Например, здесь не рассмотрена
WMI.
Но для начала, я думаю, тебе и этих хватит :) . За сим позволь откланяться.
Назад |
|
(с) tripsin aka
Орехов Роман, 2006 г.,
tripsin@yandex.ru