[英]Run Application from Service, CreateProcessAsUser Fails
I know! 我知道! I shouldn't run a GUI application from a Windows service, but this is what I should accomplish as a requirement.
我不应该从Windows服务运行GUI应用程序,但这是我应完成的。 Putting different codes from around the Web together, I have the following procedure.
将来自Web的不同代码放在一起,我有以下过程。 I see Access Violation error in log, as a result of CreateProcessAsUser.
由于CreateProcessAsUser,我在日志中看到访问冲突错误。 I have tries different settings with no luck.
我尝试了其他设置,但是没有运气。 Any idea what is wrong with this code?
知道此代码有什么问题吗?
procedure TMyService.RunApp;
var
SessionID: DWORD;
UserToken: THandle;
CmdLine: PChar;
si: _STARTUPINFOW;
pi: _PROCESS_INFORMATION;
begin
SessionId:= WtsGetActiveConsoleSessionID;
if SessionID = $FFFFFFFF then Exit;
if WTSQueryUserToken(SessionID, UserToken) then begin
CmdLine:= 'notepad.exe';
ZeroMemory(@si, SizeOf(si));
si.cb := SizeOf(si);
SI.lpDesktop := PChar('winsta0\Default');
SI.dwFlags := STARTF_USESHOWWINDOW;
SI.wShowWindow := SW_SHOWNORMAL;
ZeroMemory(@pi, SizeOf(pi));
try
CreateProcessAsUser(UserToken, nil, CmdLine, nil, nil, False,
0, nil, nil, si, pi);
except on E: Exception do
// Log exception ...
end;
CloseHandle(UserToken);
end else begin
// Log GetLastError ...
end;
end;
BTW, WTSQueryUserToken is used from JEDI API Library and is defined as: 顺便说一句,JEDI API库使用了WTSQueryUserToken,它的定义为:
function WTSQueryUserToken(SessionId: ULONG; var phToken: THandle): BOOL; stdcall;
The third parameter must be a pointer to a modifiable string, as documented on MSDN: 第三个参数必须是指向可修改字符串的指针,如MSDN上所述:
The Unicode version of this function, CreateProcessAsUserW, can modify the contents of this string.
此函数的Unicode版本CreateProcessAsUserW可以修改此字符串的内容。 Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string).
因此,该参数不能是指向只读存储器的指针(例如const变量或文字字符串)。 If this parameter is a constant string, the function may cause an access violation.
如果此参数是常量字符串,则该函数可能会导致访问冲突。
A string literal is stored in read only memory. 字符串文字存储在只读存储器中。 Try this instead:
尝试以下方法:
var
CmdLine: string;
....
CmdLine := 'notepad.exe';
UniqueString(CmdLine); // make modifiable;
....
if not CreateProcessAsUser(..., PChar(CmdLine), ...) then
// handle error
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.