目的:
偶建了一个Service Application 欲在OnStart事件函数ServiceStart()中调用ShellExecute()打开ie
问题:
ShellExecute()已在OnCreate实践函数ServiceCreate()中调试成功 但加载成服务后后却无法执行
敬请指教!
偶建了一个Service Application 欲在OnStart事件函数ServiceStart()中调用ShellExecute()打开ie
问题:
ShellExecute()已在OnCreate实践函数ServiceCreate()中调试成功 但加载成服务后后却无法执行
敬请指教!
就是说为了测试ShellExcute() 在ServiceCreate()中是可以的
但是放到ServiceStart()里面 加载并启动服务是没有反应的
在ServiceStart()里面执行的是以LocalSystem的身份运行的,可能导致ShellExcute()的时候一些应用程序出错.
建议使用CreateProcessAsUser等函数来创建子进程打开ie
再CreateProcessAsUser应该没问题的.(如果在系统未Logon的情况下,可能某些配置文件,或注册表中的某些值仍然不可以访问.)PS : 你使用ShellExcute后不能执行返回的代码是多少? 如果 >= 32 说明是那个应用程序自己有问题,在新的环境中不能正常初始化,然后退出了. 否则可能是权限方面的原因导致你无法创建应用程序.
procedure DoneServiceDeskTop;{$INCLUDE Config.inc}implementationuses
Windows, SysUtils, Common;const
DefaultWindowStation = 'WinSta0';
DefaultDesktop = 'Default';
var
hwinstaSave: HWINSTA;
hdeskSave: HDESK;
hwinstaUser: HWINSTA;
hdeskUser: HDESK;function InitServiceDesktop: boolean;
var
dwThreadId: DWORD;
begin
{$IFDEF DEBUG}CreateLog('InitServiceDesktop');{$ENDIF}
dwThreadId := GetCurrentThreadID;
// Ensure connection to service window station and desktop, and
// save their handles.
hwinstaSave := GetProcessWindowStation;
hdeskSave := GetThreadDesktop(dwThreadId);
hwinstaUser := OpenWindowStation(DefaultWindowStation, FALSE, MAXIMUM_ALLOWED);
if hwinstaUser = 0 then
begin
{$IFDEF DEBUG}CreateLog('OpenWindowStation failed' + SysErrorMessage(GetLastError)){$ENDIF};
Result := false;
exit;
end; if not SetProcessWindowStation(hwinstaUser) then
begin
{$IFDEF DEBUG}CreateLog('SetProcessWindowStation failed'){$ENDIF};
Result := false;
exit;
end; hdeskUser := OpenDesktop(DefaultDesktop, 0, FALSE, MAXIMUM_ALLOWED);
if hdeskUser = 0 then
begin
{$IFDEF DEBUG}CreateLog('OpenDesktop failed'){$ENDIF};
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
Result := false;
exit;
end;
Result := SetThreadDesktop(hdeskUser);
if not Result then
{$IFDEF DEBUG}CreateLog('SetThreadDesktop' + SysErrorMessage(GetLastError)){$ENDIF};
end;procedure DoneServiceDeskTop;
begin
{$IFDEF DEBUG}CreateLog('DoneServiceDesktop');{$ENDIF}
// Restore window station and desktop.
SetThreadDesktop(hdeskSave);
SetProcessWindowStation(hwinstaSave);
if hwinstaUser <> 0 then
CloseWindowStation(hwinstaUser);
if hdeskUser <> 0 then
CloseDesktop(hdeskUser);
end;initialization
InitServiceDesktop;finalization
DoneServiceDesktop;
end.
试一下将这个单元放到主单元的uses列中,作用是取得service对当前桌面环境的读取权限,另外将service的Interactive设为true。。
感谢 tigerhohoo
感谢楼上的兄弟们