открывать и закрывать внешнюю программу из Delphi

в моем приложении (Delphi XE10) я хочу открыть файл (RTF) с помощью пользовательского редактора по умолчанию (MSword или OpenOffice или другого) и иметь возможность закрыть этот редактор из моего приложения. Я попытался использовать приведенный ниже код, но безуспешно при закрытии редактора.

procedure TForm1.Button1Click(Sender: TObject);
var hApp : Cardinal;
begin
    hApp := StartApp('open','temp.rtf','','',sw_normal);
    anotherForm.showmodal;
    KillProcess(hApp);
end;

куда:

function StartApp(apchOperation, apchFileName, apchParameters, apchDirectory: PChar;awrdShowCmd: Word): Cardinal;
var
    lseiInfo: TShellExecuteInfo;
begin
    Result := 0;
    FillChar(lseiInfo, SizeOf(lseiInfo), Chr(0));
    lseiInfo.cbSize := SizeOf(lseiInfo);
    lseiInfo.fMask := SEE_MASK_NOCLOSEPROCESS;
    lseiInfo.lpVerb := apchOperation;
    lseiInfo.lpFile := apchFileName;
    lseiInfo.lpParameters := apchParameters;
    lseiInfo.lpDirectory := apchDirectory;
    lseiInfo.nShow := awrdShowCmd;
    if Boolean(ShellExecuteEx(@lseiInfo)) then
    Result := lseiInfo.hProcess;
end;

procedure   KillProcess(hProcess: Cardinal);
Var
  ovExitCode: LongWord;
begin
    try
        if hProcess <> 0 then begin
            GetExitCodeProcess(hProcess, ovExitCode);
            if (ovExitCode = STILL_ACTIVE) or (ovExitCode <> WAIT_OBJECT_0) then
            TerminateProcess(hProcess, ovExitCode);
            CloseHandle(hProcess);
        end;
    except
    end;
end;

Редактор открывается, но когда он должен закрыться с помощью KillProcess, ovExitCode всегда равен нулю, поэтому TerminateProcess не выполняется. Я также пытаюсь выполнить TerminateProcess в любом случае, но редактор (в данном случае MSword) не закрывается.

Не могли бы вы мне помочь ? заранее спасибо


person JimPapas    schedule 22.05.2016    source источник
comment
В общем случае это невозможно.   -  person David Heffernan    schedule 22.05.2016
comment
В документации GetExitCodeProcess вы найдете информацию о том, почему он не работает.   -  person Sertac Akyuz    schedule 22.05.2016
comment
Кроме того, ваше try...except бессмысленно.   -  person Free Consulting    schedule 22.05.2016
comment
Я узнал, что это происходит, когда активен другой экземпляр MSword.   -  person JimPapas    schedule 23.05.2016
comment
Я узнал, что это происходит, когда активен другой экземпляр MSword. Если есть только один (мое приложение), то работает нормально. Единственная проблема заключается в том, что при повторном открытии MSword предлагает восстановить предыдущий документ. Кажется, что TerminateProcess выполняет аварийное завершение. Пожалуйста, есть решение?   -  person JimPapas    schedule 23.05.2016
comment
Весь ваш подход обречен на провал. Найдите другое решение..   -  person David Heffernan    schedule 23.05.2016


Ответы (1)


Я предлагаю отказаться от подхода KillProcess и вместо этого использовать SendMessage() с WM_CLOSE. Таким образом, ваше приложение завершится "нормальным" способом. Вы можете получить дескриптор окна из дескриптора процесса, он описан здесь: https://stackoverflow.com/a/20163705/3936440< /а>

person ViRuSTriNiTy    schedule 23.05.2016
comment
Да, вы правы, но код, который вы предлагаете, написан на C, и я не могу перевести его на Delphi (я пытался, но безуспешно). - person JimPapas; 24.05.2016
comment
@JimPapas Вы уже изучили, как использовать SendMessage() в Delphi? В сети полно статей с описанием этого. - person ViRuSTriNiTy; 24.05.2016