以System用户运行的系统及服务,无法显示界面

在开发守护进程时,遇到一个问题,发了一天时间,才找到问题的思路。特记录下:

[问题]

将A.exe注册为服务,通过执行WinExec("B.exe的完整路径"{非注册服务}, SW_HIDE),启动B.exe时,在任务管理器中也存在相应进程,但是**无法显示界面**,这是什么原因?

[原因]

因为A.exe是系统权限,它在session 0,而B.exe他是session1.当A程序运行在session0,也就是系统服务窗口,所以你当前桌面上是看不到的。这种情况你需要用CreateProcessAsUser()API等方式模拟当前登陆用户方式。

[解决方案]

virtual bool DoStart(int tryInterval, int tryTime) {
int error;
bool result;
HANDLE hToken = NULL;
HANDLE hDupedToken = NULL;
// HANDLE hUserToken = NULL;

PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

STARTUPINFO si;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = L"winsta0\\default";

SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));

sa.nLength = sizeof(SECURITY_ATTRIBUTES);

DWORD dwSessionId, winlogonPid;

// Loag the client on to the local computer
dwSessionId = WTSGetActiveConsoleSessionId();

/
// Find the FSI.SnifferClient.UI.exe process
/
PROCESSENTRY32 procEntry;

HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap == INVALID_HANDLE_VALUE) {
return false;
}

procEntry.dwSize = sizeof(PROCESSENTRY32);

if (!Process32First(hSnap, &procEntry)) {
error = GetLastError();
return false;
}

do {
char output[256];
WCHAR* wc = procEntry.szExeFile;
sprintf(output, "%ws", wc);

if (_stricmp(output, "winlogon.exe") == 0) {
// We found a winlogon process...
// make sure it's running in the console session
DWORD fsiSnifferClientSessId = 0;
if (ProcessIdToSessionId(procEntry.th32ProcessID, &fsiSnifferClientSessId)
&& fsiSnifferClientSessId == dwSessionId) {
winlogonPid = procEntry.th32ProcessID;
break;
}
}
} while (Process32Next(hSnap, &procEntry));

HANDLE hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, winlogonPid);

if (!::OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY
| TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID
| TOKEN_READ | TOKEN_WRITE, &hToken)) {
error = GetLastError();
return false;
}

TOKEN_PRIVILEGES tp;
LUID luid;
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
error = GetLastError();
return false;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

result = DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hDupedToken);
SetTokenInformation(hDupedToken, TokenSessionId, (void*)dwSessionId, sizeof(DWORD));

if (!AdjustTokenPrivileges(hDupedToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES)NULL, NULL)) {
error = GetLastError();
return false;
}

if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) {
error = GetLastError();
return false;
}

string ClientAppPath = ""; // APP的完整路径
Util::GetRegValue(GetSubKey().c_str(), "AppPath", ClientAppPath);

ClientAppPath += "\\xxx.exe"; 

LPVOID pEnv = NULL;
DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;

if (CreateEnvironmentBlock(&pEnv, hDupedToken, TRUE)) {
dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
}

result = CreateProcessAsUser(
hDupedToken,
ConvertCharToLPWSTR(ClientAppPath.c_str()),
NULL,
NULL,
NULL,
FALSE,
dwCreationFlags,
pEnv,
NULL,
&si,
&pi);

CloseHandle(hProcess);
CloseHandle(hDupedToken);

CloseHandle(hToken);

int ret;
do {
Sleep(tryInterval);
ExeInfo info;
info.ProcessName = GetExeName();
ret = FindProcess(info);
} while (--tryTime && (ret != 1));
return ret == 1;
}

参考链接:

(1) https://blog.csdn.net/findsafety/article/details/45971161

(2) https://www.codeproject.com/Articles/18367/Launch-your-application-in-Vista-under-the-local-s

(3) http://ask.csdn.net/questions/192521

(4) https://blog.csdn.net/tpriwwq/article/details/45221301

(5) https://blog.csdn.net/theone10211024/article/details/14001943

(6) https://blog.csdn.net/jeanphorn/article/details/45745739

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值