@@ -40,6 +40,17 @@ public struct PROCESS_INFORMATION
40
40
public uint dwThreadId ;
41
41
}
42
42
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
+
43
54
#endregion
44
55
45
56
#region Enumerations
@@ -76,6 +87,20 @@ private enum SW : int
76
87
SW_FORCEMINIMIZE = 11 ,
77
88
}
78
89
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
+
79
104
#endregion
80
105
81
106
#region Constants
@@ -117,6 +142,12 @@ private extern static bool DuplicateTokenEx(IntPtr ExistingTokenHandle, uint dwD
117
142
[ DllImport ( "wtsapi32.dll" , SetLastError = true ) ]
118
143
private static extern uint WTSQueryUserToken ( uint SessionId , ref IntPtr phToken ) ;
119
144
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
+
120
151
#endregion
121
152
122
153
/// <summary>
@@ -140,11 +171,10 @@ public static bool StartProcessInSession0(string applicationFullPath, string sta
140
171
{
141
172
procInfo = new PROCESS_INFORMATION ( ) ;
142
173
143
- // 获取当前正在使用的系统用户的session id,每一个登录到系统的用户都有一个唯一的session id
174
+ // 使用两种方法获取当前正在使用的系统用户的session id,每一个登录到系统的用户都有一个唯一的session id
144
175
// 这一步是为了可以正确在当前登录的用户界面启动程序
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 )
148
178
{
149
179
return false ;
150
180
}
@@ -210,6 +240,44 @@ out procInfo // 用于接收新创建的进程的信息
210
240
return result ;
211
241
}
212
242
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
+
213
281
/// <summary>
214
282
/// 执行命令行并且获取输出的内容(包括输出内容和错误内容)
215
283
/// </summary>
0 commit comments