我有这个问题发生过一次,我仍然不知道如何解决它。我有一个Windows服务,当服务运行时,它首先需要模拟登录用户(活动用户)加载保存在用户应用程序数据文件夹中的一些路径和设置。我使用的代码在每次有新用户登录到Windows时都能很好地工作,除非服务得到错误模拟的地方,并且模拟了系统会话而不是实际的会话。正如我所说,这只发生过一次,但我无法真正说出原因。WTSGetActiveConsoleSessionId返回系统会话
这是怎么了检查什么活动会话并冒充是如何完成的:
首先在服务调用
WTSGetActiveConsoleSessionId();
然后检查检测登录事件是查询的活动会话ID如果会话是活动的,通过调用WTSQuerySessionInformation(连接的),如下所示:
WTS_CONNECTSTATE_CLASS wts_connect_state = WTSDisconnected;
WTS_CONNECTSTATE_CLASS* ptr_wts_connect_state = NULL;
DWORD bytes_returned = 0;
if (::WTSQuerySessionInformation(
WTS_CURRENT_SERVER_HANDLE,
session_id,
WTSConnectState,
reinterpret_cast<LPTSTR*>(&ptr_wts_connect_state),
&bytes_returned))
{
ASSERT(bytes_returned == sizeof(*ptr_wts_connect_state));
wts_connect_state = *ptr_wts_connect_state;
::WTSFreeMemory(ptr_wts_connect_state);
return (WTSActive == wts_connect_state);
}
其中SESSION_ID是会话ID由WTSG返回etActiveConsoleSessionId()。
然后我查询使用用户令牌WTSQueryUserToken
那么如果成功的服务调用GetTokenInformation
如下:
DWORD neededSize = 0;
HANDLE *realToken = new HANDLE;
if(GetTokenInformation(hImpersonationToken, (::TOKEN_INFORMATION_CLASS) TokenLinkedToken, realToken, sizeof(HANDLE), &neededSize))
{
CloseHandle(hImpersonationToken);
hImpersonationToken = *realToken;
}
其中hImpersonationToken是GetTokenInformation
如果所有检索到的令牌上面的成功就叫
DuplicateTokenEx(hImpersonationToken,
0,
NULL,
SecurityImpersonation,
TokenPrimary,
phUserToken);
CloseHandle(hImpersonationToken);
,如果它成功,那么它与检索到的令牌
ImpersonateLoggedOnUser(phUserToken);
我的服务模拟写入日志文件,并根据记录所有以前调用在成功的情况又冒充服后加载的系统配置文件,而不是的用户。
现在这个问题发生了一次,当我重新启动我的机器,但我甚至不再重现它,我一直在努力数周。
我不确定系统配置文件会话如何成为活动会话。我只是想知道如果我在那里做错了什么,不知道我在查询会话信息时是否使用了错误的信息类。
还想知道是否有可能确定查询的会话是否实际上是系统会话之前模拟与返回的令牌才可以再次重试模拟?
正如我所说的,所有提到的调用都有他们的返回对象和代码在移动到下一步之前被检查,所以他们没有来自调用的任何错误,因为它不应该继续模拟,但它做到了:(
希望得到任何帮助可能...谢谢。