小弟写了一个Delphi服务,服务的作用是定时重启、关闭某个 .exe 程序,,
用了  ShellExecute 与 WinExec('notepad.exe', SW_SHOWNORMAL) 都始终无法启动程序。请问各位大佬有什么好的办法,可以实现小弟的功能呢?

解决方案 »

  1.   

    系统未启动前服务就可以加载。而此时服务执行ShellExecute 与 WinExec肯定失败。
      

  2.   


    UNICODE_STRING = record
    Length: Word;
    MaximumLength: Word;
    Buffer: PWideChar;
    end;POBJECT_ATTRIBUTES = ^OBJECT_ATTRIBUTES;
    OBJECT_ATTRIBUTES = record
    Length: DWORD;
    RootDirectory: THANDLE;
    ObjectName: PUNICODE_STRING;
    Attributes: DWORD;
    SecurityDescriptor: Pointer;
    SecurityQualityOfService: Pointer;
    end;PSECURITY_QUALITY_OF_SERVICE=^SECURITY_QUALITY_OF_SERVICE;
    SECURITY_QUALITY_OF_SERVICE=packed record
    Length:Cardinal;
    ImpersonationLevel:Word;
    ContextTrackingMode:Word;
    EffectiveOnly:LongBool;
    end;function CopyToken(SourceToken,DesiredAccess:Cardinal;ImpersonationLevel:Word):Cardinal;
    var sqos:SECURITY_QUALITY_OF_SERVICE;oa:OBJECT_ATTRIBUTES;
    begin
    sqos.Length:=SizeOf(SECURITY_QUALITY_OF_SERVICE);
    sqos.ImpersonationLevel:=ImpersonationLevel;
    sqos.ContextTrackingMode:=0;
    sqos.EffectiveOnly:=False;
    FillChar(oa,SizeOf(OBJECT_ATTRIBUTES),0);
    oa.Length:=SizeOf(OBJECT_ATTRIBUTES);
    oa.SecurityQualityOfService:=@sqos;
    NtDuplicateToken(SourceToken,DesiredAccess,@oa,False,1,@Result);
    end;
    function ExecuteInActiveSession(CmdLine:WideString;ResumeAfterCreation:Boolean=True;ReserveHandle:Boolean=False):PROCESS_INFORMATION;
    var hMyToken,hToken,SessionId:Cardinal;SI:STARTUPINFOW;
    begin
    NtOpenProcessToken($FFFFFFFF,TOKEN_ALL_ACCESS,@hMyToken);
    hToken:=CopyToken(hMyToken,MAXIMUM_ALLOWED,1);
    NtClose(hMyToken);
    SessionId:=WTSGetActiveConsoleSessionId;
    NtSetInformationToken(hToken,TokenSessionId,@SessionId,4);
    ZeroMemory(@SI,SizeOf(_STARTUPINFOA));
    SI.cb:=SizeOf(_STARTUPINFOA);
    SI.dwFlags:=STARTF_FORCEOFFFEEDBACK;
    SI.lpDesktop:=PWideChar(WideString('WinSta0\Default'));
    CreateProcessAsUserW(hToken,nil,PWideChar(CmdLine),nil,nil,False,4,nil,nil,SI,Result);
    NtClose(hToken);
    if ResumeAfterCreation then NtResumeThread(Result.hThread,nil);
    if not ReserveHandle then begin
    NtClose(Result.hProcess);
    NtClose(Result.hThread);
    end;
    end;
      

  3.   

    写一个批处理 a.bat,
    %1notepad.exe /install /silent
    net start "服务名称"程序中打开批处理 WinExec(pchar(a.bat),SW_SHOWNORMAL);
      

  4.   

    NtDuplicateToken?没导出怎么用?
    还是要设置服务与桌面交互才行
      

  5.   

    这样就不用设置与桌面交互,ntdll.dll导出了NtDuplicateToken,只需要声明一下即可
      

  6.   

    恩,可以在服务中创建桌面进程,显示指定Default桌面(服务是winlogon桌面),也就是你说的办法
      

  7.   

    服务的桌面叫Service-0x0-3e7$之类的,这里关键是会话隔离的问题
    在windows vista以上交互式服务受到了阻碍
      

  8.   

    更正一下,服务的窗口站的名字类似于Service-0x0-3e7$,桌面的名字还是Default