Конференция "WinAPI" » Как достоверно определить что программа запущена из планировщика?
 
  • DremLIN.Ru (18.03.10 09:18) [0]
    Пишу программу, которая в зависимости от условий, определяемых при запуске, должно инициализироваться и работаеть в 3-х режимах:

    1. Как системная служба
    2. Как обычное Forms-приложение;
    3. Как консольное приложение.
    В коде проекта:

     if IsInstalling() or IsStartAsService() then
       RunAsService()
     else
     if IsStartAsConsole() or IsStartAsSchedulerTask() then
       RunAsConsole()
     else
       RunAsApplication();



    Первый пункт решился при помощи недавнего обсуждения:
    http://pda.delphimaster.net/?id=1239772550&n=5&p=2

    Второй пункт - если ни одно условие не соблюдается;

    Третий пункт - если родительский процесс - cmd.exe или планировщик.

    С определением запуска из консольного интерпритатора - проблем нет.

    function IsStartAsConsole(): Boolean;
    begin
     ConSDTIn  := GetStdHandle(STD_INPUT_HANDLE);
     ConSTDOut := GetStdHandle(STD_OUTPUT_HANDLE);

     Result := (ConSDTIn <> 0);
    //  Result := Result or (ConSTDOut <> 0); // WinXp - Not Zero
    end;


    А вот с планировщиком - непонятно. Дело в том что в разных версиях виндовс имя родительского процесса приложения, запущенного из-под планировщика, разное (определено опытным путем):

    function IsStartAsSchedulerTask(): Boolean;
    var
     ParentProcess: string;
    begin
     ParentProcess := ParentProcName;
     Result := False;
     Result := Result or AnsiSameText(ParentProcName, 'svchost.exe'); //WinXPsp3En
     Result := Result or AnsiSameText(ParentProcName, 'winlogon.exe'); //W2ksp3Ru
     Result := Result or AnsiSameText(ParentProcName, 'taskeng.exe'); // Win7ProRu
    end;



    Справочно:

    function IsStartAsService(): Boolean;
    begin
     Result := AnsiSameText(ParentProcName(), 'services.exe');
    end;

    // Решение взято: http://www.delphimaster.ru/cgi-bin/http://pda.delphimaster.net/?id=1239772550&n=5&p=2
    function ParentProcName: string;
    const
    ProcessBasicInformation = 0;
    var
    Info: PROCESS_BASIC_INFORMATION;
    dwProcessHandle: dword;
    ProcessName: string;
    Hndl: THandle;
    begin
    Result:= 'noname';
    dwProcessHandle:= GetCurrentProcess;
    if NtQueryInformationProcess(dwProcessHandle, ProcessBasicInformation, @Info, SizeOf(Info), nil) = NO_ERROR
      then begin
        Hndl:= OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, Info.uInheritedFromUniqueProcessId);
        if Hndl <> 0 then
          try
            SetLength(ProcessName, MAX_PATH);
            if GetModuleBaseNameA(Hndl, 0, PChar(ProcessName), MAX_PATH) > 0
              then Result:= PChar(ProcessName);
          finally
            CloseHandle(Hndl);
          end;
      end;
    end;



    В связи с вышеперечисленным вопрос: А нетли универсального, достоверного, не зависящего от версии виндовс, способо определения запуска приложения из-под планировщика виндовс (Task Scheduler)?

    PS:
    Приходит в голову просто при создании задачи использовать аргументы командной строки, и тем самым не использовать автоматическое распознование...
    Я понимаю, что в принципе - это самое простое и быстрое решение проблемы :)

    Но, тем не менее, интересует сабжевый вопрос...

    Спасибо.
  • Leonid Troyanovsky © (18.03.10 11:43) [1]

    > DremLIN.Ru   (18.03.10 09:18)

    > Пишу программу, которая в зависимости от условий, определяемых
    > при запуске, должно инициализироваться и работаеть в 3-х
    > режимах:
    >
    > 1. Как системная служба
    > 2. Как обычное Forms-приложение;
    > 3. Как консольное приложение.

    Не нужно, IMHO, никакое  автоматическое распознование,
    а нужна служба и два клиента: консоль и гуи.

    --
    Regards, LVT.
  • DremLIN.Ru (20.03.10 00:21) [2]

    > Не нужно, IMHO, никакое  автоматическое распознование,а
    > нужна служба и два клиента: консоль и гуи.

    Кому не нужно? Вам?
    К существу заданного вопроса это не относится.

    У меня проблема решена не красиво и не универсально, но на целевой машинке - все распознается и работает корректно.

    Хотя вопрос уже представляет собой скорее академический интерес...
  • Leonid Troyanovsky © (20.03.10 10:49) [3]

    > DremLIN.Ru   (20.03.10 00:21) [2]

    > К существу заданного вопроса это не относится.

    Это заблуждение.

    --
    Regards, LVT.
 
Конференция "WinAPI" » Как достоверно определить что программа запущена из планировщика?
Есть новые Нет новых   [134432   +18][b:0][p:0.002]