目的:
偶建了一个Service Application 欲在OnStart事件函数ServiceStart()中调用ShellExecute()打开ie
问题:
ShellExecute()已在OnCreate实践函数ServiceCreate()中调试成功 但加载成服务后后却无法执行
敬请指教!

解决方案 »

  1.   

    ShellExecute()在你的ServiceExecute过程可以执行吗?
      

  2.   

    To: hkbarton
    就是说为了测试ShellExcute() 在ServiceCreate()中是可以的
    但是放到ServiceStart()里面 加载并启动服务是没有反应的
      

  3.   

    在serviceCreate的时候你是以Administrator身份执行的服务程序,因此ShellExcute()生成的子进程也有Administrator的权限.
    在ServiceStart()里面执行的是以LocalSystem的身份运行的,可能导致ShellExcute()的时候一些应用程序出错.
    建议使用CreateProcessAsUser等函数来创建子进程打开ie
      

  4.   

    To:tigerhohoo如果我用./Administrator的身份登录呢
      

  5.   

    使用./Administrator 做为参数调用 LogonUser
     再CreateProcessAsUser应该没问题的.(如果在系统未Logon的情况下,可能某些配置文件,或注册表中的某些值仍然不可以访问.)PS : 你使用ShellExcute后不能执行返回的代码是多少? 如果 >= 32 说明是那个应用程序自己有问题,在新的环境中不能正常初始化,然后退出了. 否则可能是权限方面的原因导致你无法创建应用程序.
      

  6.   

    我也不是很清楚了,也许 tigerhohoo 兄弟说的是对的喔
      

  7.   

    unit ServiceDesktop;interfacefunction InitServiceDesktop: boolean;
    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。。
      

  8.   

    感谢 tonylk 代码学习中
    感谢 tigerhohoo
    感谢楼上的兄弟们