我创建了一个服务程序,在服务中启动了一个外部程序,使用CreateProcess,代码如下:
function ExecApp(ComLine: PAnsiChar): THandle;
var
  FAppHandle : THandle;
  lpAppName : pchar;
  lpTitle : Pchar;
  StartInfo : TStartupInfo;
  FProcessInfo : TProcessInformation;
begin
  GetMem(lpAppName,255);
  GetMem(lpTitle,255);  StrPCopy(lpAppName,ComLine);
  StrPCopy(lpTitle,ComLine);  StartInfo.cb:=sizeof(TStartupInfo);
  StartInfo.lpReserved := NIL;
  StartInfo.lpDesktop:=NIL;
  StartInfo.lpTitle := lpTitle;
  StartInfo.dwFillAttribute := 0;
  StartInfo.cbReserved2 :=0;
  StartInfo.lpReserved2 := NIL;
  StartInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartInfo.wShowWindow := SW_SHOWNORMAL;  FProcessInfo.hProcess := 0;
  FProcessInfo.hThread := 0;
  FProcessInfo.dwProcessId := 0;
  FProcessInfo.dwThreadId := 0;
  Result:=0;
 if CreateProcess( nil,lpAppName,nil,nil,False,0,nil,nil,StartInfo,FProcessInfo)=True then
 begin
    Result:=FProcessInfo.hProcess;
    CloseHandle(FProcessInfo.hThread);
 end
end;
结果出现两个问题:
1.启动的程序只在后台运行;没有出现主窗口;
2.启动的改进程在windows的任务管理器中结束不了.
各位老大帮忙看看是什么原因啊?

解决方案 »

  1.   

    因为你这样启动后,那个程序算是你的进程中,要把你的那个进程释放掉,才能结束,或者在你的程序中将她结束,它是作为你程序的一部分了
    你改用WinExec,或shellexecute好了,肯定没问题
      

  2.   

    服务中不能调用GUI程序,就是有界面的程序
      

  3.   

    WinExec,或shellexecute
    但是利用你的方法 可以实现得
    只是在每次加载进程的时候 要做为独立的进程或者服务
      

  4.   

    服务中打开一个记事本程序,最小化!
    WinExec("Notepad.exe", SW_MINIMIZE) 肯定没问题!
      

  5.   

    to:Yssss1980 服务中是可以调用GUI程序的,我看别人实现过.
    to:dudunono 在服务里启动的进程怎样才能成为独立的进程?
    to:Kingron 这样不好吧,怎样获取另外的用户名和密码呢?
    to:GoldProgramer 试过了,还是不行,结果是一样的.
    有没可行的办法?最好详细一点
      

  6.   

    不知道你设置了服务允许与桌面交互看看有没有用。服务程序一般以system身份进行运行,没有桌面,虽然可以设置与桌面交互,但是一般的服务都没有界面,而由一个程序派生的子进程一般会继承父进程的权限,因此在系统服务里面运行的子程序不能被杀掉,另外system没有桌面,因此派生出来的进程没有桌面交互,我们看不到,但是实际上在内存运行中,因此,你要运行子进程,必须在用户登录之后,以当前用户的桌面运行程序,例如下面的代码:
    function CreateProcessWithLogonW(
      lpUsername,
      lpDomain,
      lpPassword:PWideChar;
      dwLogonFlags:dword;
      lpApplicationName: PWideChar;
      lpCommandLine: PWideChar;
      dwCreationFlags: DWORD;
      lpEnvironment: Pointer;
      lpCurrentDirectory: PWideChar;
      const lpStartupInfo: tSTARTUPINFO;
      var lpProcessInformation: TProcessInformation
    ): BOOL; stdcall; external 'advapi32.dll';procedure RunAsUser(const Domain, Username, Password, Command: string);
    var
      StartupInfo: TStartupInfo;
      ProcessInfo: TProcessInformation;
      wDomain, wUsername, wPassword, wCommand: PWideChar;
    begin
      FillChar(StartupInfo, SizeOf(StartupInfo), #0);
      StartupInfo.cb := SizeOf(StartupInfo);
      StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
      StartupInfo.wShowWindow := SW_SHOWNORMAL;  GetMem(
        wDomain,
        Length(Domain) * SizeOf(WideChar) + SizeOf(WideChar));
      GetMem(
        wUsername,
        Length(Username) * SizeOf(WideChar) + SizeOf(WideChar));
      GetMem(
        wPassword,
        Length(Password) * SizeOf(WideChar) + SizeOf(WideChar));
      GetMem(
        wCommand,
        Length(Command) * SizeOf(WideChar) + SizeOf(WideChar));  StringToWideChar(
        Domain,
        wDomain,
        Length(Domain) * SizeOf(WideChar) + SizeOf(WideChar));
      StringToWideChar(
        Username,
        wUsername,
        Length(Username) * SizeOf(WideChar) + SizeOf(WideChar));
      StringToWideChar(
        Password,
        wPassword,
        Length(Password) * SizeOf(WideChar) + SizeOf(WideChar));
      StringToWideChar(
        Command,
        wCommand,
        Length(Command) * SizeOf(WideChar) + SizeOf(WideChar));  if not CreateProcessWithLogonW(
        wUsername,
        wDomain,
        wPassword,
        0,
        nil,
        wCommand,
        0,
        nil,
        nil,
        StartupInfo,
        ProcessInfo) then RaiseLastOSError;  FreeMem(wDomain);
      FreeMem(wUsername);
      FreeMem(wPassword);
      FreeMem(wCommand);
    end;Demo:
    RunAsUser(
        'ADOMAIN',
        'bubba',
        'elroy',
        'notepad.exe c:\earl.txt');至于用户名和密码,那么你可以创建一个,也可以让用户输入或者进行配置。
      

  7.   

    可以用COM,进程外、进程内随便(没有特殊要求最好是进程内,就是以DLL形式),可以用API函数CoCreateInstance或VCL函数CreateComObject。关于怎么具体实现,那要讲的可太多了。这就看你对COM熟不熟悉了!