猿问

CreateProcessAsUser 进程以 -1073741502 退出

我有一个服务,负责在用户登录和控制台会话连接后启动/监视用户会话中的交互过程。服务设置为自动启动,以便在用户登录之前启动并运行。第一次登录时一切正常,我正确启动/重新启动了用户进程。

发生的情况是,如果用户退出并重新登录,服务将不再能够正确启动用户进程。CreateProcessAsUser 没有返回错误,但是一旦用户进程启动,它就会以 -1073741502 (0xC0000142) 退出代码退出。

如果我重新启动该服务,则它再次能够启动用户进程而不会出现任何错误。

如果需要,我可以发布该服务如何创建用户进程的完整来源。


皈依舞
浏览 497回答 2
2回答

开满天机

我看到您正在启动提升的流程。我将此添加到我的测试服务中,它仍然可以正常工作。但我认为问题可能出在这一行GetLinkedTokeIfRequiered():Marshal.Release(LINKED_TOKEN_INFO);那显然应该是:Marshal.FreeHGlobal(LINKED_TOKEN_INFO);解决这个问题,它可能会起作用。事实上,我很惊讶它没有崩溃。对我来说并不容易,挖掘这个。C# 互操作不是我的强项。为了 OP 的利益,我的测试服务的完整源代码是用 C++ 编写的,它可以工作:#include <windows.h>#include <wtsapi32.h>#include <userenv.h>#include <tchar.h>#include <stdio.h>#pragma comment (lib, "user32.lib")#pragma comment (lib, "wtsapi32.lib")#pragma comment (lib, "userenv.lib")#pragma comment (lib, "advapi32.lib")DWORD report_error (const char *operation){&nbsp; &nbsp; DWORD err = GetLastError ();&nbsp; &nbsp; return err;}// Launch notepad as currently logged-on userDWORD LaunchProcess (DWORD SessionId, const char **failed_operation){&nbsp; &nbsp; HANDLE hToken;&nbsp; &nbsp; BOOL ok = WTSQueryUserToken (SessionId, &hToken);&nbsp; &nbsp; if (!ok)&nbsp; &nbsp; &nbsp; &nbsp; return report_error (*failed_operation = "WTSQueryUserToken");&nbsp; &nbsp; void *environment = NULL;&nbsp; &nbsp; ok = CreateEnvironmentBlock (&environment, hToken, TRUE);&nbsp; &nbsp; if (!ok)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; CloseHandle (hToken);&nbsp; &nbsp; &nbsp; &nbsp; return report_error (*failed_operation = "CreateEnvironmentBlock");&nbsp; &nbsp; }&nbsp; &nbsp; TOKEN_LINKED_TOKEN lto;&nbsp; &nbsp; DWORD nbytes;&nbsp; &nbsp; ok = GetTokenInformation (hToken, TokenLinkedToken, &lto, sizeof (lto), &nbytes);&nbsp; &nbsp; if (ok)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; CloseHandle (hToken);&nbsp; &nbsp; &nbsp; &nbsp; hToken = lto.LinkedToken;&nbsp; &nbsp; }&nbsp; &nbsp; STARTUPINFO si = { sizeof (si) } ;&nbsp; &nbsp; PROCESS_INFORMATION pi = { } ;&nbsp; &nbsp; si.lpDesktop = "winsta0\\default";&nbsp; &nbsp; // Do NOT want to inherit handles here, surely&nbsp; &nbsp; DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS | /* CREATE_NEW_CONSOLE | */ CREATE_UNICODE_ENVIRONMENT;&nbsp; &nbsp; ok = CreateProcessAsUser (hToken, "c:\\windows\\system32\\notepad.exe", NULL, NULL, NULL, FALSE,&nbsp; &nbsp; &nbsp; &nbsp; dwCreationFlags, environment, NULL, &si, &pi);&nbsp; &nbsp; DestroyEnvironmentBlock (environment);&nbsp; &nbsp; CloseHandle (hToken);&nbsp; &nbsp; if (!ok)&nbsp; &nbsp; &nbsp; &nbsp; return report_error (*failed_operation = "CreateProcessAsUser");&nbsp; &nbsp; CloseHandle (pi.hThread);&nbsp; &nbsp; CloseHandle (pi.hProcess);&nbsp; &nbsp; return 0;}// Determine the session ID of the currently logged-on userDWORD GetCurrentSessionId (){&nbsp; &nbsp; WTS_SESSION_INFO *pSessionInfo;&nbsp; &nbsp; DWORD n_sessions = 0;&nbsp; &nbsp; BOOL ok = WTSEnumerateSessions (WTS_CURRENT_SERVER, 0, 1, &pSessionInfo, &n_sessions);&nbsp; &nbsp; if (!ok)&nbsp; &nbsp; &nbsp; &nbsp; return 0;&nbsp; &nbsp; DWORD SessionId = 0;&nbsp; &nbsp; for (DWORD i = 0; i < n_sessions; ++i)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (pSessionInfo [i].State == WTSActive)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SessionId = pSessionInfo [i].SessionId;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; WTSFreeMemory (pSessionInfo);&nbsp; &nbsp; return SessionId;}#define SERVICE_NAME __T ("demo_service")bool quit;// CtrlHandler callbackDWORD WINAPI CtrlHandler (DWORD dwControl, DWORD&nbsp; dwEventType, LPVOID lpEventData, LPVOID lpContext){&nbsp; &nbsp; if (dwControl == SERVICE_CONTROL_STOP)&nbsp; &nbsp; &nbsp; &nbsp; quit = true;&nbsp; &nbsp; return NO_ERROR;}// SvcMain callbackVOID WINAPI SvcMain (DWORD dwArgc, LPTSTR *lpszArgv){&nbsp; &nbsp; // Register for callbacks&nbsp; &nbsp; SERVICE_STATUS_HANDLE sh = RegisterServiceCtrlHandlerEx (SERVICE_NAME, CtrlHandler, NULL);&nbsp; &nbsp; // Tell the SCM that we are up and running&nbsp; &nbsp; SERVICE_STATUS ss = { };&nbsp; &nbsp; ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS;&nbsp; &nbsp; ss.dwCurrentState = SERVICE_RUNNING;&nbsp; &nbsp; ss.dwControlsAccepted = SERVICE_ACCEPT_STOP;&nbsp; &nbsp; SetServiceStatus (sh, &ss);&nbsp; &nbsp; TCHAR buf [256];&nbsp; &nbsp; const TCHAR *title = __T ("(c) 2018 Contoso Corporation");&nbsp; &nbsp; while (!quit)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; DWORD response = IDOK;&nbsp; &nbsp; &nbsp; &nbsp; DWORD SessionId = GetCurrentSessionId ();&nbsp; &nbsp; &nbsp; &nbsp; if (SessionId == 0)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Sleep (2000);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // Pop-up a message on the screen of the currently logged-on user (session 1)&nbsp; &nbsp; &nbsp; &nbsp; _stprintf (buf, __T ("Ready to launch..., SessionId = %d"), SessionId);&nbsp; &nbsp; &nbsp; &nbsp; WTSSendMessage (WTS_CURRENT_SERVER_HANDLE, SessionId, (TCHAR *) title, _tcslen (title),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buf, _tcslen (buf), MB_OKCANCEL, 0, &response, TRUE);&nbsp; &nbsp; &nbsp; &nbsp; if (response == IDCANCEL)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; const char *failed_operation = "";&nbsp; &nbsp; &nbsp; &nbsp; DWORD dwResult = LaunchProcess (SessionId, &failed_operation);&nbsp; &nbsp; &nbsp; &nbsp; // Report results&nbsp; &nbsp; &nbsp; &nbsp; _stprintf (buf, __T ("LaunchProcess returned %lx from %s"), dwResult, failed_operation);&nbsp; &nbsp; &nbsp; &nbsp; WTSSendMessage (WTS_CURRENT_SERVER_HANDLE, SessionId, (char *) title, _tcslen (title),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buf, _tcslen (buf), MB_OK, 0, &response, TRUE);&nbsp; &nbsp; &nbsp; &nbsp; FILE *logfile = fopen ("g:\\temp\\service.log", "at");&nbsp; &nbsp; &nbsp; &nbsp; if (logfile)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fprintf (logfile, "%s\n", buf);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fclose (logfile);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; // Tell the SCM we are going away and exit&nbsp; &nbsp; ss.dwCurrentState = SERVICE_STOPPED;&nbsp; &nbsp; SetServiceStatus (sh, &ss);}// mainint main (void){&nbsp; &nbsp; SERVICE_TABLE_ENTRY DispatchTable [] =&nbsp;&nbsp; &nbsp; {&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; { SERVICE_NAME, SvcMain },&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; { NULL, NULL }&nbsp;&nbsp; &nbsp; };&nbsp;&nbsp; &nbsp; // This call returns when the service has stopped.&nbsp;&nbsp; &nbsp; // The process should simply terminate when the call returns.&nbsp; &nbsp; StartServiceCtrlDispatcher (DispatchTable);&nbsp; &nbsp; return 0;}

慕盖茨4494581

错误是STATUS_DLL_INIT_FAILED这意味着DLL缺少动态加载。也许您指定了错误的工作目录并且某些调用LoadLibrary("lib_with_no_path.dll")失败了?如果您查看 .dll 文件,您应该能够看到缺少哪个 DLL&nbsp;Event Viewer。
随时随地看视频慕课网APP
我要回答