运行 来自服务的应用程序,CreateProcessAsUser 失败
Run Application from Service, CreateProcessAsUser Fails
我知道!我不应该 运行 来自 Windows 服务的 GUI 应用程序,但这是我应该按照要求完成的。将 Web 上的不同代码放在一起,我有以下过程。由于 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
我知道!我不应该 运行 来自 Windows 服务的 GUI 应用程序,但这是我应该按照要求完成的。将 Web 上的不同代码放在一起,我有以下过程。由于 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