使用Windows服务启动提升的进程

时间:2016-05-26 17:28:03

标签: vb.net windows winapi

我正在尝试从Windows服务运行软件更新。我的服务在LocalSystem下运行。

我认为一切正常,CreateProcessAsUser行因API错误3(ERR_FILE_NOT_FOUND)而失败。

我不确定如何继续调试我的代码。我使用ProcMon来查看它是否真的找不到路径,但它确实如此,所以我想我可能错过了其他的东西。

有人看到可能的错误吗?

我正在使用WTSEnumerateSessions来获取活动会话。出于某种原因,其MachineName成员为空,但SessionID 0,所以我猜这仍然可以。

Public Function StartAppInSessionAsAdmin(ByVal uSessionID As String, ByVal uWinstationNameStrPtr As Long, ByVal uAppName As String) As Integer

    'get SessionID token
    Dim hToken&
    Dim bRet As Boolean
    bRet = WTSQueryUserToken(uSessionID, hToken)
    WriteLog "wtsqueryusertoken: " & bRet & ", htoken: " & hToken

    'we need to get the TokenLinked Token
    Dim TLT As TOKEN_LINKED_TOKEN
    Dim TLTSize&
    TLTSize = Len(TLT.LinkedToken)

    Dim hLinkedToken&
    Dim iRetSize&
    bRet = GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenLinkedToken, hLinkedToken, TLTSize, iRetSize)
    WriteLog "gettokeninformation: " & bRet & " linkedtoken: " & TOKEN_INFORMATION_CLASS.TokenLinkedToken & " linked2: " & hLinkedToken

    'Use CreateEnvironment Block with the original token to create an environment for the new program with the USER Environment
    Dim lpEB&
    bRet = CreateEnvironmentBlock(lpEB, hToken, False)
    WriteLog "Createenvblock: " & bRet

    If bRet Then

        Dim pi  As PROCESS_INFORMATION
        Dim si As STARTUPINFO
        si.lpDesktop = uWinstationNameStrPtr '  '”Winsta0\default”
        si.cb = Len(si)

        Dim lRet&
        lRet = CreateProcessAsUser( _
        hLinkedToken, _
        "", _
        uAppName, _
        0&, _
        0&, _
        0&, _
        NORMAL_PRIORITY_CLASS, _
        0&, _
        0&, _
        si, _
        pi)

        'Give user a feedback
        If lRet <> 0 Then
            WriteLog ":-) createprocessasuser succeeded!"
        Else
            WriteLog ":-( failed createprocessasuser! error: " & Err.LastDllError
        End If
    End If

    WriteLog "pstartappinsessions}"

End Function

1 个答案:

答案 0 :(得分:4)

ERROR_FILE_NOT_FOUND强烈建议无法找到可执行文件。换句话说,问题出在lpApplicationNamelpCommandLine上。来自documentation

  

lpApplicationName参数可以是NULL。在这种情况下,模块名称必须是lpCommandLine字符串中第一个以空格分隔的标记。如果您使用的是包含空格的长文件名,请使用带引号的字符串来指示文件名结束的位置以及参数的开头;否则,文件名不明确。 [...]如果文件名不包含扩展名,则附加.exe。

如果lpApplicationName为空,则lpCommandLine必须以您要运行的程序开头。如果程序的路径包含空格,则路径必须用引号括起来。

如果lpApplicationName为null,则可以通过将其值粘贴到命令提示符中来测试lpCommandLine是否有效。