我知道!我不应该从 Windows 服务运行 GUI 应用程序,但这是我应该完成的要求。将来自网络的不同代码放在一起,我有以下过程。由于 CreateProcessAsUser,我在日志中看到访问冲突错误。我尝试过不同的设置但没有运气。知道这段代码有什么问题吗?
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;
顺便说一句,WTSQueryUserToken 是从 JEDI API 库使用的,定义为:
function WTSQueryUserToken(SessionId: ULONG; var phToken: THandle): BOOL; stdcall;
最佳答案
第三个参数必须是指向可修改字符串的指针,如 MSDN 上所述:
The Unicode version of this function, CreateProcessAsUserW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.
字符串文字存储在只读存储器中。试试这个:
var
CmdLine: string;
....
CmdLine := 'notepad.exe';
UniqueString(CmdLine); // make modifiable;
....
if not CreateProcessAsUser(..., PChar(CmdLine), ...) then
// handle error
关于delphi - 从服务运行应用程序,CreateProcessAsUser 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33989658/