Eros
Eros

Reputation: 469

Manage Network user session from Delphi

Hi to everybody I've a question about managing user session on the network with Delphi. I've a server on which there are many sessions of RDP and frequently they became non usable and I need to connect to the servers and disconnect the user session via Tap manager. So I thought to create a simple application that show all the active session and can be used to disconnect any one of then. I've tried the way to see the processes that are active on the server using WMIService.ExecQuery('SELECT * FROM Win32_Process...) but I can't find. the way to obtain the users that can be visible on the task manager (as you can see from the attached image

enter image description here

I've also find the command Query User that can be execute from command prompt, but my question is this: there is a way to obtain this list inside Delphi in ordered to disconnect users?

Upvotes: 0

Views: 977

Answers (1)

Highball
Highball

Reputation: 51

I don't have delphi to test, but in freepascal this should do what you're wanting and is delphi compatible. The only dependency is the jedi windows library which comes bundled with fpc. for delphi (if it's not included) you can find the code here, https://sourceforge.net/projects/jedi-apilib/

Basically, below we query sessions, print them out (including the user name), and show the code that could terminate a session (XXX is the sessionId that you want to terminate)

{$Mode delphi}

//example for: https://stackoverflow.com/questions/60100489/manage-network-user-session-from-delphi

program rdp_sessions;
uses
  JwaWindows;

var
  LSessions : PWTS_SESSION_INFO;
  LCount, LReturnBytes: DWORD;
  I: Integer;
  LBuffer: Pointer;
  LUser : String;
begin
  //enumerates the session list
  // doc -> https://learn.microsoft.com/en-us/windows/win32/api/wtsapi32/nf-wtsapi32-wtsenumeratesessionsa
  WTSEnumerateSessions(
    WTS_CURRENT_SERVER_HANDLE, //current server
    0, //reserverd, must be 0
    1, //must be 1
    LSessions,
    LCount
  );

  WriteLn(LCount, ' sessions found');

  for I := 0 to Pred(LCount) do
  begin
    //doc -> https://learn.microsoft.com/en-us/windows/win32/api/wtsapi32/nf-wtsapi32-wtsquerysessioninformationa?redirectedfrom=MSDN
    WTSQuerySessionInformation(
      WTS_CURRENT_SERVER_HANDLE,
      LSessions^.SessionId,
      WTS_INFO_CLASS.WTSUserName,
      LBuffer,
      LReturnBytes
    );

    //greater than zero determines success
    if LReturnBytes > 0 then
    begin
      LUser := PChar(LBuffer);
      WTSFreeMemory(LBuffer); //cleanup
    end
    else
      WriteLn('WTSQuerySessionInformation failed with ', GetLastError);

    //output results to screen
    WriteLn('id:', LSessions^.SessionId, ' stationName:', LSessions^.pWinStationName, ' userName:', LUser);

    //next session
    Inc(LSessions);
  end;

  //terminates a specified session
  // doc-> https://learn.microsoft.com/en-us/windows/win32/api/wtsapi32/nf-wtsapi32-wtsdisconnectsession?redirectedfrom=MSDN
  WTSDisconnectSession(
    WTS_CURRENT_SERVER_HANDLE,
    XXX, //this is the session id that is printed out above from enumerate
    False //false = async, true = block until disconnect
  );

  //wait for input
  ReadLn;
end.

Upvotes: 2

Related Questions