-1
請幫我看看爲什麼代碼(由FWN在此topic中編寫)檢索帶有遠程桌面服務API的終端服務上的用戶登錄時間無法正常工作 - 每次都是wtsinfo 。登錄時間返回不同的Int64值。 這裏是修改後的代碼:使用遠程桌面服務API在終端服務上檢索用戶登錄時間
RDPInfo.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace RDP
{
public enum WTS_INFO_CLASS
{
WTSInitialProgram,
WTSApplicationName,
WTSWorkingDirectory,
WTSOEMId,
WTSSessionId,
WTSUserName,
WTSWinStationName,
WTSDomainName,
WTSConnectState,
WTSClientBuildNumber,
WTSClientName,
WTSClientDirectory,
WTSClientProductId,
WTSClientHardwareId,
WTSClientAddress,
WTSClientDisplay,
WTSSessionInfo,
WTSClientProtocolType,
}
public enum WTS_CONNECTSTATE_CLASS
{
WTSActive,
WTSConnected,
WTSConnectQuery,
WTSShadow,
WTSDisconnected,
WTSIdle,
WTSListen,
WTSReset,
WTSDown,
WTSInit,
}
public class RDPInfo
{
[DllImport("wtsapi32.dll")]
static extern IntPtr WTSOpenServer([MarshalAs(UnmanagedType.LPStr)] String pServerName);
[DllImport("wtsapi32.dll")]
static extern void WTSCloseServer(IntPtr hServer);
[DllImport("wtsapi32.dll")]
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);
[DllImport("Wtsapi32.dll")]
static extern bool WTSQuerySessionInformation(System.IntPtr hServer, int sessionId, WTS_INFO_CLASS wtsInfoClass, out System.IntPtr ppBuffer, out uint pBytesReturned);
[StructLayout(LayoutKind.Sequential)]
private struct WTS_SESSION_INFO
{
public Int32 SessionID;
[MarshalAs(UnmanagedType.LPStr)]
public String pWinStationName;
public WTS_CONNECTSTATE_CLASS State;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct WTSINFO
{
[MarshalAs(UnmanagedType.I8)]
public Int64 LogonTime;
}
public static IntPtr OpenServer(String Name)
{
IntPtr server = WTSOpenServer(Name);
return server;
}
public static void CloseServer(IntPtr ServerHandle)
{
WTSCloseServer(ServerHandle);
}
public static List<RDPSession> ListUsers(String ServerName)
{
List<RDPSession> List = new List<RDPSession>();
WTSINFO wtsinfo = new WTSINFO();
IntPtr serverHandle = IntPtr.Zero;
List<String> resultList = new List<string>();
serverHandle = OpenServer(ServerName);
IntPtr SessionInfoPtr = IntPtr.Zero;
IntPtr userPtr = IntPtr.Zero;
IntPtr domainPtr = IntPtr.Zero;
IntPtr clientNamePtr = IntPtr.Zero;
IntPtr wtsinfoPtr = IntPtr.Zero;
IntPtr clientDisplayPtr = IntPtr.Zero;
try
{
Int32 sessionCount = 0;
Int32 retVal = WTSEnumerateSessions(serverHandle, 0, 1, ref SessionInfoPtr, ref sessionCount);
Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));
Int32 currentSession = (int)SessionInfoPtr;
uint bytes = 0;
if (retVal != 0)
{
for (int i = 0; i < sessionCount; i++)
{
WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)currentSession, typeof(WTS_SESSION_INFO));
currentSession += dataSize;
WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSUserName, out userPtr, out bytes);
WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSDomainName, out domainPtr, out bytes);
WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSClientName, out clientNamePtr, out bytes);
WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSSessionInfo, out wtsinfoPtr, out bytes);
RDPSession temp = new RDPSession();
temp.Client = Marshal.PtrToStringAnsi(clientNamePtr);
temp.Server = ServerName;
temp.UserName = Marshal.PtrToStringAnsi(userPtr);
temp.Domain = Marshal.PtrToStringAnsi(domainPtr);
temp.ConnectionState = si.State;
temp.SessionId = si.SessionID;
//WTSINFO dt = (WTSINFO)Marshal.PtrToStructure((System.IntPtr)currentSession, typeof(WTSINFO));
//DateTime date = new DateTime(dt.LogonTime);
//temp.sessionInfo = date;
wtsinfo = (WTSINFO)Marshal.PtrToStructure(wtsinfoPtr, typeof(WTSINFO));
temp.sessionInfo = wtsinfo.LogonTime;
List.Add(temp);
WTSFreeMemory(clientNamePtr);
WTSFreeMemory(userPtr);
WTSFreeMemory(domainPtr);
WTSFreeMemory(wtsinfoPtr);
}
WTSFreeMemory(SessionInfoPtr);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
}
finally
{
Marshal.Release(SessionInfoPtr);
Marshal.Release(userPtr);
Marshal.Release(domainPtr);
Marshal.Release(clientNamePtr);
//Marshal.Release(wtsinfoPtr);
CloseServer(serverHandle);
}
return List;
}
}
public class RDPSession
{
public string UserName;
public string Domain;
public int SessionId;
public string Client;
public string Server;
public WTS_CONNECTSTATE_CLASS ConnectionState;
//public RDP.RDPInfo.WTSINFO sessionInfo;
public Int64 sessionInfo;
}
}
的Program.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RDP
{
class Program
{
static void Main(string[] args)
{
List<RDPSession> ServerList = new List<RDPSession>();
ServerList = RDPInfo.ListUsers("SERVERNAME");
foreach (RDPSession item in ServerList)
{
Console.WriteLine("{0,-15} {1,-15} {2,-35} {3,-40}", item.UserName, item.ConnectionState, item.Client, item.sessionInfo);
}
}
P.S.因爲我認爲我需要從此獲得來自WTSINFO的LogonTime article
P.S.S.我已經從WTS_INFO_CLASS enumeration加入WTSINFO structure和WTS_CLIENT_DISPLAY structure。 WTS_CLIENT_DISPLAY得到正確的答案。但WTSINFO每次返回不同Int64值。你能幫我解決嗎?如何將其轉換爲DateTime?謝謝。
也許你沒有找到願意調試你的代碼的人。 –
也許吧,但這不是我的代碼,我也不十分明白它是如何工作的。這是'QuerySessionInformation.ps1'的更新版本'由Ryan Ries編寫,2013年1月,在MSDN和Stackoverflow的幫助下。 – fapw