Willy Denoyette
8/23/2003 10:30:00 AM
Johannes wrote:
|| the problem is that in winxp every local user can be
|| logged on. And you can get this information with your
|| programm,but i want to know who''s dektop is on the top or
|| if no user is active (maybe logged on) and you can just
|| see the logon screen! And i think windows has to know it,
|| so how can i get this information?
|| Johannes
Ok I see, you are talking about Terminal Server info (Fast user switching on XP).
Nothing built-in in the FCL, so Pinvoke is the message (note the same can be acomplished using WMI and the Management classes).
Here is a console sample using the WTS API''s (and PInvoke):
//Begin source
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Security;
namespace WTSsessions
{
// Using Wtsapi32 (only available on Windows Server 2003 and XP)
// Get Session information using Terminal server API''s
// Requirements: see SDK docs
using HANDLE = System.IntPtr;
class Class1
{
static void Main(string[] args)
{
TerminalServer WTSinfo = new TerminalServer();
WTSinfo.GetSessionInfo();
}
}
class TerminalServer
{
[DllImport("wtsapi32", CharSet=CharSet.Auto, SetLastError=true), SuppressUnmanagedCodeSecurityAttribute]
static extern bool WTSEnumerateSessions (
HANDLE hServer, // Handle to a terminal server (from WTSOpenServer)
int Reserved, // dmust be 0
uint Version, // must be 1
ref IntPtr ppSessionInfo, // pointer to pointer to Processinfo
ref int pCount // no. of processes
);
[DllImport("wtsapi32", CharSet=CharSet.Auto, SetLastError=true), SuppressUnmanagedCodeSecurityAttribute]
static extern bool WTSQuerySessionInformation (
HANDLE hServer, // Handle to a terminal server (from WTSOpenServer)
uint sessionId, //
int WTSInfoClass, //
ref IntPtr ppBuffer, // pointer to pointer to returned info
ref int bCount // no. of bytes returned
);
[DllImport("wtsapi32", SetLastError=true), SuppressUnmanagedCodeSecurityAttribute]
static extern IntPtr WTSOpenServer (
string ServerName // Server name (NETBIOS)
);
[DllImport("wtsapi32", SetLastError=true), SuppressUnmanagedCodeSecurityAttribute]
static extern void WTSCloseServer (
HANDLE hServer // Handle obtained by WTSOpenServer
);
[DllImport("wtsapi32", SetLastError=true), SuppressUnmanagedCodeSecurityAttribute]
static extern void WTSFreeMemory (
IntPtr pMemory );
[StructLayout(LayoutKind.Sequential)]
struct WTSSessionInfo
{
internal uint SessionId;
[MarshalAs(UnmanagedType.LPTStr)] internal string pWinStationName;
internal uint State;
}
enum WTSConnectState
{
Active,
Connected,
ConnectQuery,
Shadow,
Disconnected,
Idle,
Listen,
Reset,
Down,
Init
}
enum WTSInfoClass
{
InitialProgram,
ApplicationName,
WorkingDirectory,
OEMId,
SessionId,
UserName,
WinStationName,
DomainName,
ConnectState,
ClientBuildNumber,
ClientName,
ClientDirectory,
ClientProductId,
ClientHardwareId,
ClientAddress,
ClientDisplay,
ClientProtocolType
}
public void GetSessionInfo()
{
HANDLE hServer = IntPtr.Zero;
IntPtr pInfo = IntPtr.Zero;
IntPtr pInfoSave = IntPtr.Zero;
WTSSessionInfo WTSsi; // Reference to ProcessInfo struct
IntPtr ppBuffer = IntPtr.Zero;
int bCount = 0;
int count = 0;
int iPtr = 0;
try
{
hServer = WTSOpenServer("scenic");
if(hServer == IntPtr.Zero)
Console.WriteLine(Marshal.GetLastWin32Error());
if (WTSEnumerateSessions(hServer, 0, 1, ref pInfo, ref count))
{
pInfoSave = pInfo;
Console.WriteLine("Number of sessions :{0}", count);
for(int n = 0; n < count; n++)
{
WTSsi = (WTSSessionInfo) Marshal.PtrToStructure(pInfo, typeof(WTSSessionInfo) );
iPtr = (int)(pInfo) + Marshal.SizeOf(WTSsi);
pInfo = (IntPtr)(iPtr);
Console.WriteLine(WTSsi.SessionId + "\t" + WTSsi.pWinStationName + "\t" + (WTSConnectState)WTSsi.State );
if(WTSQuerySessionInformation(hServer, WTSsi.SessionId, (int)WTSInfoClass.UserName, ref ppBuffer, ref bCount))
Console.WriteLine("User: {0}", Marshal.PtrToStringAuto(ppBuffer));
if(WTSQuerySessionInformation(hServer, WTSsi.SessionId, (int)WTSInfoClass.DomainName, ref ppBuffer, ref bCount))
Console.WriteLine("Domain: {0}", Marshal.PtrToStringAuto(ppBuffer));
if(WTSQuerySessionInformation(hServer, WTSsi.SessionId, (int)WTSInfoClass.WinStationName, ref ppBuffer, ref bCount))
Console.WriteLine("Windowstation: {0}",Marshal.PtrToStringAuto(ppBuffer));
}
}
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
// Free memory used
WTSFreeMemory(pInfoSave);
// Close server handle
WTSCloseServer(hServer);
}
}
}
}
// End source
Willy.