@msdn=http://search.microsoft.com/search/results.aspx?qu=$$$ @pinvoke=http://pinvoke.net/$$$.htm Summary: This Terminal Services API call lists all local and remote sessions for a given server, including their state (e.g. connected, disconnected) and type (local, RDP). It is the basis for the output of qwinsta.exe. !!!!C# Signature: [DllImport("wtsapi32.dll", SetLastError=true)] static extern int WTSEnumerateSessions( System.IntPtr hServer, int Reserved, int Version, ref System.IntPtr ppSessionInfo, ref int pCount); [DllImport("wtsapi32.dll", SetLastError=true)] static extern void WTSEnumerateSessions( System.IntPtr hServer, ref System.IntPtr ppSessionInfo, ref int pCount) { WTSEnumerateSessions(hServer,0,1,ppSessionInfo,pCount); } !!!!Powershell Signature: $wtsenumsig = @' [DllImport("wtsapi32.dll", SetLastError=true)] public static extern int WTSEnumerateSessions( System.IntPtr hServer, int Reserved, int Version, ref System.IntPtr ppSessionInfo, ref int pCount); '@ !!!!C# Example // Note the VB example will give you the first entry of the array n times where n is the size of the array using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace TerminalServices { class TSManager { [DllImport("wtsapi32.dll", SetLastError=true)] static extern IntPtr WTSOpenServer([MarshalAs(UnmanagedType.LPStr)] String pServerName); [DllImport("wtsapi32.dll")] static extern void WTSCloseServer(IntPtr hServer); [DllImport("wtsapi32.dll", SetLastError=true)] static extern Int32 WTSEnumerateSessions( IntPtr hServer, [MarshalAs(UnmanagedType.U4)] Int32 Reserved, [MarshalAs(UnmanagedType.U4)] Int32 Version, ref IntPtr ppSessionInfo, [MarshalAs(UnmanagedType.U4)] ref Int32 pCount); [DllImport("wtsapi32.dll")] static extern void WTSFreeMemory(IntPtr pMemory); [StructLayout(LayoutKind.Sequential)] private struct WTS_SESSION_INFO { public Int32 SessionID; [MarshalAs(UnmanagedType.LPStr)] public String pWinStationName; public WTS_CONNECTSTATE_CLASS State; } public enum WTS_CONNECTSTATE_CLASS { WTSActive, WTSConnected, WTSConnectQuery, WTSShadow, WTSDisconnected, WTSIdle, WTSListen, WTSReset, WTSDown, WTSInit } public static IntPtr OpenServer(String Name) { IntPtr server = WTSOpenServer(Name); return server; } public static void CloseServer(IntPtr ServerHandle) { WTSCloseServer(ServerHandle); } public static List<String> ListSessions(String ServerName) { IntPtr server = IntPtr.Zero; List<String> ret = new List<string>(); server = OpenServer(ServerName); try { IntPtr ppSessionInfo = IntPtr.Zero; Int32 count = 0; Int32 retval = WTSEnumerateSessions(server, 0, 1, ref ppSessionInfo, ref count); Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO)); Int64 current = (int)ppSessionInfo; if (retval != 0) { for (int i = 0; i < count; i++) { WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)current, typeof(WTS_SESSION_INFO)); current += dataSize; ret.Add(si.SessionID + " " + si.State + " " + si.pWinStationName); } WTSFreeMemory(ppSessionInfo); } } finally { CloseServer(server); } return ret; } } } !!!!Powershell Example $server = "vmtermsrv" $messageTitle = "FooBar" $message = "This is a test... This is only a test" $timeout = 60; $wtssig = @' namespace mystruct { using System; using System.Runtime.InteropServices; [StructLayout(LayoutKind.Sequential)] public struct WTS_SESSION_INFO { public Int32 SessionID; [MarshalAs(UnmanagedType.LPStr)] public String pWinStationName; public WTS_CONNECTSTATE_CLASS State; } public enum WTS_CONNECTSTATE_CLASS { WTSActive, WTSConnected, WTSConnectQuery, WTSShadow, WTSDisconnected, WTSIdle, WTSListen, WTSReset, WTSDown, WTSInit } } '@ add-type $wtssig $wtsenumsig = @' [DllImport("wtsapi32.dll", SetLastError=true)] public static extern int WTSEnumerateSessions( System.IntPtr hServer, int Reserved, int Version, ref System.IntPtr ppSessionInfo, ref int pCount); '@ $wtsopensig = @' [DllImport("wtsapi32.dll", SetLastError=true)] public static extern IntPtr WTSOpenServer(string pServerName); '@ $wtsSendMessagesig = @' [DllImport("wtsapi32.dll", SetLastError = true)] public static extern bool WTSSendMessage( IntPtr hServer, [MarshalAs(UnmanagedType.I4)] int SessionId, String pTitle, [MarshalAs(UnmanagedType.U4)] int TitleLength, String pMessage, [MarshalAs(UnmanagedType.U4)] int MessageLength, [MarshalAs(UnmanagedType.U4)] int Style, [MarshalAs(UnmanagedType.U4)] int Timeout, [MarshalAs(UnmanagedType.U4)] out int pResponse, bool bWait); '@ $wtsenum = add-type -MemberDefinition $wtsenumsig -Name PSWTSEnumerateSessions -Namespace GetLoggedOnUsers -PassThru $wtsOpen = add-type -MemberDefinition $wtsopensig -name PSWTSOpenServer -Namespace GetLoggedOnUsers -PassThru $wtsmessage = Add-Type -MemberDefinition $wtsSendMessagesig -name PSWTSSendMessage -Namespace GetLoggedOnUsers -PassThru [long]$count = 0 [long]$ppSessionInfo = 0 $server = $wtsOpen::WTSOpenServer($server) [long]$retval = $wtsenum::WTSEnumerateSessions($server,0,1,[ref]$ppSessionInfo,[ref]$count) $datasize = [system.runtime.interopservices.marshal]::SizeOf([System.Type][mystruct.WTS_SESSION_INFO]) $Responses = @() if ($retval -ne 0){ for ($i = 0; $i -lt $count; $i++){ $element = [system.runtime.interopservices.marshal]::PtrToStructure($ppSessionInfo + ($datasize * $i),[System.type][mystruct.WTS_SESSION_INFO]) $element $resp = "" $wtsmessage::WTSSendMessage($server, $element.SessionID,$messageTitle,$messageTitle.Length,$message,$message.Length,0,$timeout,[ref]$resp,$true) $responses += $resp; } } $responses !!!!VB Signature: <DllImport("wtsapi32.dll", _ bestfitmapping:=True, _ CallingConvention:=CallingConvention.StdCall, _ CharSet:=CharSet.Auto, _ EntryPoint:="WTSEnumerateSessions", _ setlasterror:=True, _ ThrowOnUnmappableChar:=True)> _ Private Shared Function WTSEnumerateSessions( _ ByVal hServer As IntPtr, _ <MarshalAs(UnmanagedType.U4)> _ ByVal Reserved As Int32, _ <MarshalAs(UnmanagedType.U4)> _ ByVal Version As Int32, _ ByRef ppSessionInfo As IntPtr, _ <MarshalAs(UnmanagedType.U4)> _ ByRef pCount As Int32) As Int32 End Function !!!!User-Defined Types: Private Enum WTS_CONNECTSTATE_CLASS WTSActive WTSConnected WTSConnectQuery WTSShadow WTSDisconnected WTSIdle WTSListen WTSReset WTSDown WTSInit End Enum <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _ Private Structure WTS_SESSION_INFO Dim SessionID As Int32 'DWORD integer Dim pWinStationName As String ' integer LPTSTR - Pointer to a null-terminated string containing the name of the WinStation for this session Dim State As WTS_CONNECTSTATE_CLASS End Structure !!!!Notes: None. !!!!Tips & Tricks: Please add some! !!!!Sample Code: Option Explicit On Option Strict On Imports System.Runtime.InteropServices Public Class ManagedWTSAPI Private Enum WTS_CONNECTSTATE_CLASS WTSActive WTSConnected WTSConnectQuery WTSShadow WTSDisconnected WTSIdle WTSListen WTSReset WTSDown WTSInit End Enum <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _ Private Structure WTS_SESSION_INFO Dim SessionID As Int32 'DWORD integer Dim pWinStationName As String ' integer LPTSTR - Pointer to a null-terminated string containing the name of the WinStation for this session Dim State As WTS_CONNECTSTATE_CLASS End Structure Friend Structure strSessionsInfo Dim SessionID As Integer Dim StationName As String Dim ConnectionState As String End Structure <DllImport("wtsapi32.dll", _ bestfitmapping:=True, _ CallingConvention:=CallingConvention.StdCall, _ CharSet:=CharSet.Auto, _ EntryPoint:="WTSEnumerateSessions", _ setlasterror:=True, _ ThrowOnUnmappableChar:=True)> _ Private Shared Function WTSEnumerateSessions( _ ByVal hServer As IntPtr, _ <MarshalAs(UnmanagedType.U4)> _ ByVal Reserved As Int32, _ <MarshalAs(UnmanagedType.U4)> _ ByVal Vesrion As Int32, _ ByRef ppSessionInfo As IntPtr, _ <MarshalAs(UnmanagedType.U4)> _ ByRef pCount As Int32) As Int32 End Function <DllImport("wtsapi32.dll")> _ Private Shared Sub WTSFreeMemory(ByVal pMemory As IntPtr) End Sub <DllImport("wtsapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _ Private Shared Function WTSOpenServer(ByVal pServerName As String) As IntPtr End Function <DllImport("wtsapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _ Private Shared Sub WTSCloseServer(ByVal hServer As IntPtr) End Sub Friend Function GetSessions(ByVal ServerName As String) As strSessionsInfo() Dim ptrOpenedServer As IntPtr Dim RetVal As strSessionsInfo() Try ptrOpenedServer = WTSOpenServer(ServerName) Dim FRetVal As Int32 Dim ppSessionInfo As IntPtr = IntPtr.Zero Dim Count As Int32 = 0 Try FRetVal = WTSEnumerateSessions(ptrOpenedServer, 0, 1, ppSessionInfo, Count) If FRetVal <> 0 Then Dim sessionInfo() As WTS_SESSION_INFO = New WTS_SESSION_INFO(Count) {} Dim i As Integer Dim DataSize = Marshal.SizeOf(New WTS_SESSION_INFO) Dim current As Int64 current = ppSessionInfo.ToInt64 For i = 0 To Count - 1 ' Step i + 1 sessionInfo(i) = CType(Marshal.PtrToStructure(New IntPtr(current), GetType(WTS_SESSION_INFO)), WTS_SESSION_INFO) current = current + DataSize Next WTSFreeMemory(ppSessionInfo) Dim tmpArr(sessionInfo.GetUpperBound(0)) As strSessionsInfo For i = 0 To tmpArr.GetUpperBound(0) tmpArr(i).SessionID = sessionInfo(i).SessionID tmpArr(i).StationName = sessionInfo(i).pWinStationName tmpArr(i).ConnectionState = GetConnectionState(sessionInfo(i).State) Next ReDim sessionInfo(-1) RetVal = tmpArr Else Throw New ApplicationException("No data retruned") End If Catch ex As Exception Throw New Exception(ex.Message & vbCrLf & System.Runtime.InteropServices.Marshal.GetLastWin32Error) End Try Catch ex As Exception Throw New Exception(ex.Message) Exit Function Finally WTSCloseServer(ptrOpenedServer) End Try Return RetVal End Function Private Function GetConnectionState(ByVal State As WTS_CONNECTSTATE_CLASS) As String Dim RetVal As String Select Case State Case WTS_CONNECTSTATE_CLASS.WTSActive RetVal = "Active" Case WTS_CONNECTSTATE_CLASS.WTSConnected RetVal = "Connected" Case WTS_CONNECTSTATE_CLASS.WTSConnectQuery RetVal = "Query" Case WTS_CONNECTSTATE_CLASS.WTSDisconnected RetVal = "Disconnected" Case WTS_CONNECTSTATE_CLASS.WTSDown RetVal = "Down" Case WTS_CONNECTSTATE_CLASS.WTSIdle RetVal = "Idle" Case WTS_CONNECTSTATE_CLASS.WTSInit RetVal = "Initializing." Case WTS_CONNECTSTATE_CLASS.WTSListen RetVal = "Listen" Case WTS_CONNECTSTATE_CLASS.WTSReset RetVal = "reset" Case WTS_CONNECTSTATE_CLASS.WTSShadow RetVal = "Shadowing" Case Else RetVal = "Unknown connect state" End Select Return RetVal End Function End Class !!!!Alternative Managed API: Cassia on google code: https://code.google.com/p/cassia/ Documentation: WTSEnumerateSessions@msdn on MSDN
Edit wtsapi32.wtsenume...
You do not have permission to change this page. If you feel this is in error, please send feedback with the contact link on the main page.