我正在尝试从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
答案 0 :(得分:4)
ERROR_FILE_NOT_FOUND
强烈建议无法找到可执行文件。换句话说,问题出在lpApplicationName
或lpCommandLine
上。来自documentation:
lpApplicationName
参数可以是NULL
。在这种情况下,模块名称必须是lpCommandLine
字符串中第一个以空格分隔的标记。如果您使用的是包含空格的长文件名,请使用带引号的字符串来指示文件名结束的位置以及参数的开头;否则,文件名不明确。 [...]如果文件名不包含扩展名,则附加.exe。
如果lpApplicationName
为空,则lpCommandLine
必须以您要运行的程序开头。如果程序的路径包含空格,则路径必须用引号括起来。
如果lpApplicationName
为null,则可以通过将其值粘贴到命令提示符中来测试lpCommandLine
是否有效。