亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

CreateProcessAsUser 進程以 -1073741502 退出

CreateProcessAsUser 進程以 -1073741502 退出

C#
皈依舞 2021-07-09 16:00:35
我有一個服務,負責在用戶登錄和控制臺會話連接后啟動/監視用戶會話中的交互過程。服務設置為自動啟動,以便在用戶登錄之前啟動并運行。第一次登錄時一切正常,我正確啟動/重新啟動了用戶進程。發生的情況是,如果用戶退出并重新登錄,服務將不再能夠正確啟動用戶進程。CreateProcessAsUser 沒有返回錯誤,但是一旦用戶進程啟動,它就會以 -1073741502 (0xC0000142) 退出代碼退出。如果我重新啟動該服務,則它再次能夠啟動用戶進程而不會出現任何錯誤。如果需要,我可以發布該服務如何創建用戶進程的完整來源。
查看完整描述

2 回答

?
開滿天機

TA貢獻1786條經驗 獲得超13個贊

我看到您正在啟動提升的流程。我將此添加到我的測試服務中,它仍然可以正常工作。


但我認為問題可能出在這一行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)

{

    DWORD err = GetLastError ();

    return err;

}


// Launch notepad as currently logged-on user

DWORD LaunchProcess (DWORD SessionId, const char **failed_operation)

{

    HANDLE hToken;

    BOOL ok = WTSQueryUserToken (SessionId, &hToken);

    if (!ok)

        return report_error (*failed_operation = "WTSQueryUserToken");


    void *environment = NULL;

    ok = CreateEnvironmentBlock (&environment, hToken, TRUE);


    if (!ok)

    {

        CloseHandle (hToken);

        return report_error (*failed_operation = "CreateEnvironmentBlock");

    }


    TOKEN_LINKED_TOKEN lto;

    DWORD nbytes;

    ok = GetTokenInformation (hToken, TokenLinkedToken, &lto, sizeof (lto), &nbytes);


    if (ok)

    {

        CloseHandle (hToken);

        hToken = lto.LinkedToken;

    }


    STARTUPINFO si = { sizeof (si) } ;

    PROCESS_INFORMATION pi = { } ;

    si.lpDesktop = "winsta0\\default";


    // Do NOT want to inherit handles here, surely

    DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS | /* CREATE_NEW_CONSOLE | */ CREATE_UNICODE_ENVIRONMENT;

    ok = CreateProcessAsUser (hToken, "c:\\windows\\system32\\notepad.exe", NULL, NULL, NULL, FALSE,

        dwCreationFlags, environment, NULL, &si, &pi);


    DestroyEnvironmentBlock (environment);

    CloseHandle (hToken);


    if (!ok)

        return report_error (*failed_operation = "CreateProcessAsUser");


    CloseHandle (pi.hThread);

    CloseHandle (pi.hProcess);

    return 0;

}


// Determine the session ID of the currently logged-on user

DWORD GetCurrentSessionId ()

{

    WTS_SESSION_INFO *pSessionInfo;

    DWORD n_sessions = 0;

    BOOL ok = WTSEnumerateSessions (WTS_CURRENT_SERVER, 0, 1, &pSessionInfo, &n_sessions);

    if (!ok)

        return 0;


    DWORD SessionId = 0;


    for (DWORD i = 0; i < n_sessions; ++i)

    {

        if (pSessionInfo [i].State == WTSActive)

        {

            SessionId = pSessionInfo [i].SessionId;

            break;

        }

    }


    WTSFreeMemory (pSessionInfo);

    return SessionId;

}



#define SERVICE_NAME __T ("demo_service")


bool quit;


// CtrlHandler callback

DWORD WINAPI CtrlHandler (DWORD dwControl, DWORD  dwEventType, LPVOID lpEventData, LPVOID lpContext)

{

    if (dwControl == SERVICE_CONTROL_STOP)

        quit = true;

    return NO_ERROR;

}


// SvcMain callback

VOID WINAPI SvcMain (DWORD dwArgc, LPTSTR *lpszArgv)

{

    // Register for callbacks

    SERVICE_STATUS_HANDLE sh = RegisterServiceCtrlHandlerEx (SERVICE_NAME, CtrlHandler, NULL);


    // Tell the SCM that we are up and running

    SERVICE_STATUS ss = { };

    ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS;

    ss.dwCurrentState = SERVICE_RUNNING;

    ss.dwControlsAccepted = SERVICE_ACCEPT_STOP;

    SetServiceStatus (sh, &ss);


    TCHAR buf [256];

    const TCHAR *title = __T ("(c) 2018 Contoso Corporation");


    while (!quit)

    {

        DWORD response = IDOK;


        DWORD SessionId = GetCurrentSessionId ();

        if (SessionId == 0)

        {

            Sleep (2000);

            continue;

        }


        // Pop-up a message on the screen of the currently logged-on user (session 1)

        _stprintf (buf, __T ("Ready to launch..., SessionId = %d"), SessionId);

        WTSSendMessage (WTS_CURRENT_SERVER_HANDLE, SessionId, (TCHAR *) title, _tcslen (title),

            buf, _tcslen (buf), MB_OKCANCEL, 0, &response, TRUE);

        if (response == IDCANCEL)

            break;


        const char *failed_operation = "";

        DWORD dwResult = LaunchProcess (SessionId, &failed_operation);


        // Report results

        _stprintf (buf, __T ("LaunchProcess returned %lx from %s"), dwResult, failed_operation);

        WTSSendMessage (WTS_CURRENT_SERVER_HANDLE, SessionId, (char *) title, _tcslen (title),

            buf, _tcslen (buf), MB_OK, 0, &response, TRUE);


        FILE *logfile = fopen ("g:\\temp\\service.log", "at");

        if (logfile)

        {

            fprintf (logfile, "%s\n", buf);

            fclose (logfile);

        }

    }


    // Tell the SCM we are going away and exit

    ss.dwCurrentState = SERVICE_STOPPED;

    SetServiceStatus (sh, &ss);

}



// main

int main (void)

{

    SERVICE_TABLE_ENTRY DispatchTable [] = 

    { 

        { SERVICE_NAME, SvcMain }, 

        { NULL, NULL } 

    }; 


    // This call returns when the service has stopped. 

    // The process should simply terminate when the call returns.

    StartServiceCtrlDispatcher (DispatchTable);

    return 0;

}



查看完整回答
反對 回復 2021-07-17
?
慕蓋茨4494581

TA貢獻1850條經驗 獲得超11個贊

錯誤是STATUS_DLL_INIT_FAILED這意味著DLL缺少動態加載。也許您指定了錯誤的工作目錄并且某些調用LoadLibrary("lib_with_no_path.dll")失敗了?

如果您查看 .dll 文件,您應該能夠看到缺少哪個 DLL Event Viewer。


查看完整回答
反對 回復 2021-07-17
  • 2 回答
  • 0 關注
  • 574 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號