Skip to content

Commit 9c15c9d

Browse files
feat: try to get session id via WTSEnumerateSessions when in the remote session
1 parent 702edca commit 9c15c9d

File tree

1 file changed

+72
-4
lines changed

1 file changed

+72
-4
lines changed

ProcessGuard.Common/Utility/ApplicationLoader.cs

+72-4
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,17 @@ public struct PROCESS_INFORMATION
4040
public uint dwThreadId;
4141
}
4242

43+
[StructLayout(LayoutKind.Sequential)]
44+
private struct WTS_SESSION_INFO
45+
{
46+
public readonly uint SessionID;
47+
48+
[MarshalAs(UnmanagedType.LPStr)]
49+
public readonly string pWinStationName;
50+
51+
public readonly WTS_CONNECTSTATE_CLASS State;
52+
}
53+
4354
#endregion
4455

4556
#region Enumerations
@@ -76,6 +87,20 @@ private enum SW : int
7687
SW_FORCEMINIMIZE = 11,
7788
}
7889

90+
private enum WTS_CONNECTSTATE_CLASS
91+
{
92+
WTSActive,
93+
WTSConnected,
94+
WTSConnectQuery,
95+
WTSShadow,
96+
WTSDisconnected,
97+
WTSIdle,
98+
WTSListen,
99+
WTSReset,
100+
WTSDown,
101+
WTSInit
102+
}
103+
79104
#endregion
80105

81106
#region Constants
@@ -117,6 +142,12 @@ private extern static bool DuplicateTokenEx(IntPtr ExistingTokenHandle, uint dwD
117142
[DllImport("wtsapi32.dll", SetLastError = true)]
118143
private static extern uint WTSQueryUserToken(uint SessionId, ref IntPtr phToken);
119144

145+
[DllImport("wtsapi32.dll", SetLastError = true)]
146+
private static extern int WTSEnumerateSessions(IntPtr hServer, int Reserved, int Version, ref IntPtr ppSessionInfo, ref int pCount);
147+
148+
[DllImport("wtsapi32.dll", SetLastError = false)]
149+
public static extern void WTSFreeMemory(IntPtr memory);
150+
120151
#endregion
121152

122153
/// <summary>
@@ -140,11 +171,10 @@ public static bool StartProcessInSession0(string applicationFullPath, string sta
140171
{
141172
procInfo = new PROCESS_INFORMATION();
142173

143-
// 获取当前正在使用的系统用户的session id,每一个登录到系统的用户都有一个唯一的session id
174+
// 使用两种方法获取当前正在使用的系统用户的session id,每一个登录到系统的用户都有一个唯一的session id
144175
// 这一步是为了可以正确在当前登录的用户界面启动程序
145-
uint dwSessionId = WTSGetActiveConsoleSessionId();
146-
147-
if (WTSQueryUserToken(dwSessionId, ref hPToken) == 0)
176+
if (WTSQueryUserToken(WTSGetActiveConsoleSessionId(), ref hPToken) == 0 &&
177+
WTSQueryUserToken(GetSessionIdFromEnumerateSessions(), ref hPToken) == 0)
148178
{
149179
return false;
150180
}
@@ -210,6 +240,44 @@ out procInfo // 用于接收新创建的进程的信息
210240
return result;
211241
}
212242

243+
/// <summary>
244+
/// Get session id via WTSEnumerateSessions
245+
/// </summary>
246+
/// <returns></returns>
247+
private static uint GetSessionIdFromEnumerateSessions()
248+
{
249+
var pSessionInfo = IntPtr.Zero;
250+
try
251+
{
252+
var sessionCount = 0;
253+
254+
// Get a handle to the user access token for the current active session.
255+
if (WTSEnumerateSessions(IntPtr.Zero, 0, 1, ref pSessionInfo, ref sessionCount) != 0)
256+
{
257+
var arrayElementSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));
258+
var current = pSessionInfo;
259+
260+
for (var i = 0; i < sessionCount; i++)
261+
{
262+
var si = (WTS_SESSION_INFO)Marshal.PtrToStructure(current, typeof(WTS_SESSION_INFO));
263+
current += arrayElementSize;
264+
265+
if (si.State == WTS_CONNECTSTATE_CLASS.WTSActive)
266+
{
267+
return si.SessionID;
268+
}
269+
}
270+
}
271+
272+
return uint.MaxValue;
273+
}
274+
finally
275+
{
276+
WTSFreeMemory(pSessionInfo);
277+
CloseHandle(pSessionInfo);
278+
}
279+
}
280+
213281
/// <summary>
214282
/// 执行命令行并且获取输出的内容(包括输出内容和错误内容)
215283
/// </summary>

0 commit comments

Comments
 (0)