Jak pobrac wszystkie odpalone procesy, wraz z nazwą użytkownika i domeny

lofix

Jest to przykład programu (aplikacja konsolowa)

program EnumAppOwners;
 
{$APPTYPE CONSOLE}
 
uses
  SysUtils, Windows, PSAPI;
 
function SIDType(peUse: SID_NAME_USE): String;
begin
  Case peUse of
    SidTypeUser: Result := 'Uzytkownik';
    SidTypeGroup: Result := 'Grupa';
    SidTypeDomain: Result := 'Domena';
    SidTypeAlias: Result := 'Alias';
    SidTypeWellKnownGroup: Result := 'Znana grupa';
    SidTypeDeletedAccount: Result := 'Skasowane konto';
    SidTypeInvalid: Result := 'Niepoprawne';
    SidTypeUnknown: Result := 'Nieznane';
  else
    Result := 'Oops';
  end;
end;
 
function EnumerateWindows(hWnd: HWND; lParam: LPARAM): BOOL; stdcall;
var hAccessToken: THandle;
    hThread: THandle;
    ProcessID: DWord;
    hProcess: THandle;
    ModName: array[0..MAX_PATH] of char;
    UserToken: PSIDAndAttributes;
    InfoBufferSize: DWORD;
    dwInfoBufferSize: DWORD;
    vName, vDomain: PChar;
    cbName, cbDomain: DWORD;
    peUse: SID_NAME_USE;
begin
  Result := True;
  hThread := GetWindowThreadProcessId(hWnd, @ProcessID);
  hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, ProcessID);
  if (GetModuleFileNameEx(hProcess, 0, ModName, SizeOf(ModName))   0) then Write(ModName, ' - ');
  if OpenProcessToken(hProcess, TOKEN_QUERY, hAccessToken) then
    begin
      UserToken := nil;
      GetTokenInformation(hAccessToken, TokenUser, UserToken, 0, InfoBufferSize);
      GetMem(UserToken, InfoBufferSize);
      if GetTokenInformation(hAccessToken, TokenUser, UserToken, InfoBufferSize, dwInfoBufferSize) then
        begin
          cbName := 0;
          cbDomain := 0;
          vName := nil;
          vDomain := nil;
          LookupAccountSid(nil, UserToken.Sid, vName, cbName, vDomain, cbDomain, peUse);
          if (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
            begin
              GetMem(vName, cbName);
              GetMem(vDomain, cbDomain);
              if LookupAccountSid(nil, UserToken.Sid, vName, cbName, vDomain, cbDomain, peUse) then
                begin
                  WriteLn('Uzytkownik: ', vName, ', Domena: ', vDomain, ', Typ: ', SidType(peUse));
                end
                  else
                begin
                  WriteLn(SysErrorMessage(GetLastError));
                end;
            end
          else
            begin
              WriteLn(SysErrorMessage(GetLastError));
            end;
        end
      else
        begin
          WriteLn(SysErrorMessage(GetLastError));
        end;
      FreeMem(UserToken);
      CloseHandle(hAccessToken);
    end
  else
    begin
      WriteLn(SysErrorMessage(GetLastError));
    end;
  CloseHandle(hProcess);
  WriteLn;
end;
 
begin
  EnumWindows(@EnumerateWindows, 0);
  ReadLn;
end.

2 komentarzy

Niestety to działa tylko dla 1 użytkownia w przypdku innych procesów innych użytkowników to nic nie wyświtla (testowane na terminal serwerze)

Hmm... Może mi ktoś wyjaśnić, dlaczego w

EnumWindows(@EnumerateWindows, 0);

zgłasza mi błąd, że potrzebna jest zmienna (Variable required)? Nawet jeśli zadeklaruję zmienną i przypiszę jej wartość 0, a następnie wywołam tą funkcję, to dostaję ten sam błąd...