执行带有参数的命令行可执行文件并等待错误代码(整数)?

发布于 2024-10-10 07:40:09 字数 149 浏览 10 评论 0原文

有谁知道调用命令行可执行文件的函数,允许向其传递参数(特别是字符串列表或字符串列表,并等待执行完成并返回错误代码(整数)?

我正在调用的可执行文件是delphi 应用程序,它返回一个错误代码,我没有编写该应用程序,并且我没有以任何方式修改它的源代码

Does anyone know of a function to call a commandline executable, allowing to pass it parameters (particularly a stringlist, or list of strings somehow, and waiting for execution to complete and return an error code (integer)?

The executable i am calling is a delphi app, which returns an error code. I did not write the app, and i do not have source to modify it in any way

thanx

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绾颜 2024-10-17 07:40:10

这是我使用的代码。您应该能够在这里找到您需要的东西:

uses
  Windows, ShellAPI;

type
  TMethod = procedure of object;

procedure WaitUntilSignaled(Handle: THandle; const ProcessMessages: TMethod);
begin
  if Assigned(ProcessMessages) then begin
    ProcessMessages;//in case there are any messages are already waiting in the queue
    while MsgWaitForMultipleObjects(1, Handle, False, INFINITE, QS_ALLEVENTS)=WAIT_OBJECT_0+1 do begin
      ProcessMessages;
    end;
  end else begin
    WaitForSingleObject(Handle, INFINITE);
  end;
end;

function DefaultShellExecuteInfo(const Action, Filename, Parameters, Directory: string): TShellExecuteInfo;
begin
  ZeroMemory(@Result, SizeOf(Result));
  Result.cbSize := SizeOf(TShellExecuteInfo);
  Result.fMask := SEE_MASK_NOCLOSEPROCESS;
  if Assigned(Application.MainForm) then begin
    Result.Wnd := Application.MainFormHandle;
  end;
  Result.lpVerb := PChar(Action);
  Result.lpFile := PChar(Filename);
  Result.lpParameters := PChar(Parameters);
  Result.lpDirectory := PChar(Directory);
  Result.nShow := SW_SHOWNORMAL;
end;

function MyShellExecute(const ShellExecuteInfo: TShellExecuteInfo; out ExitCode: DWORD; Wait: Boolean; const ProcessMessages: TMethod): Boolean; overload;
begin
  Result := ShellExecuteEx(@ShellExecuteInfo);
  if Result and (ShellExecuteInfo.hProcess<>0) then begin
    Try
      if Wait then begin
        WaitUntilSignaled(ShellExecuteInfo.hProcess, ProcessMessages);
        GetExitCodeProcess(ShellExecuteInfo.hProcess, ExitCode);
      end;
    Finally
      CloseHandle(ShellExecuteInfo.hProcess);
    End;
  end;
end;

function MyShellExecute(const ShellExecuteInfo: TShellExecuteInfo; out ExitCode: DWORD; const ProcessMessages: TMethod): Boolean; overload;
begin
  Result := MyShellExecute(ShellExecuteInfo, ExitCode, True, ProcessMessages);
end;

function MyShellExecute(const ShellExecuteInfo: TShellExecuteInfo; Wait: Boolean; const ProcessMessages: TMethod): Boolean; overload;
var
  ExitCode: DWORD;
begin
  Result := MyShellExecute(ShellExecuteInfo, ExitCode, Wait, ProcessMessages);
end;

type
  TShellExecuteMessageHandler = record
  public
    procedure ProcessMessages;
  end;

procedure TShellExecuteMessageHandler.ProcessMessages;
begin
  Application.ProcessMessages;
  if Application.Terminated then begin
    Abort;
  end;
end;

function MyShellExecute(const Action, Filename, Parameters, Directory: string; Wait: Boolean): Boolean; overload;
var
  MessageHandler: TShellExecuteMessageHandler;
begin
  Try
    Result := MyShellExecute(
      DefaultShellExecuteInfo(Action, FileName, Parameters, Directory),
      Wait,
      MessageHandler.ProcessMessages
    );
  Except
    on EAbort do begin
      Result := False;//the wait has been terminated before the process signaled
    end;
  End;
end;

This is the code that I use. You should be able to find what you need in here:

uses
  Windows, ShellAPI;

type
  TMethod = procedure of object;

procedure WaitUntilSignaled(Handle: THandle; const ProcessMessages: TMethod);
begin
  if Assigned(ProcessMessages) then begin
    ProcessMessages;//in case there are any messages are already waiting in the queue
    while MsgWaitForMultipleObjects(1, Handle, False, INFINITE, QS_ALLEVENTS)=WAIT_OBJECT_0+1 do begin
      ProcessMessages;
    end;
  end else begin
    WaitForSingleObject(Handle, INFINITE);
  end;
end;

function DefaultShellExecuteInfo(const Action, Filename, Parameters, Directory: string): TShellExecuteInfo;
begin
  ZeroMemory(@Result, SizeOf(Result));
  Result.cbSize := SizeOf(TShellExecuteInfo);
  Result.fMask := SEE_MASK_NOCLOSEPROCESS;
  if Assigned(Application.MainForm) then begin
    Result.Wnd := Application.MainFormHandle;
  end;
  Result.lpVerb := PChar(Action);
  Result.lpFile := PChar(Filename);
  Result.lpParameters := PChar(Parameters);
  Result.lpDirectory := PChar(Directory);
  Result.nShow := SW_SHOWNORMAL;
end;

function MyShellExecute(const ShellExecuteInfo: TShellExecuteInfo; out ExitCode: DWORD; Wait: Boolean; const ProcessMessages: TMethod): Boolean; overload;
begin
  Result := ShellExecuteEx(@ShellExecuteInfo);
  if Result and (ShellExecuteInfo.hProcess<>0) then begin
    Try
      if Wait then begin
        WaitUntilSignaled(ShellExecuteInfo.hProcess, ProcessMessages);
        GetExitCodeProcess(ShellExecuteInfo.hProcess, ExitCode);
      end;
    Finally
      CloseHandle(ShellExecuteInfo.hProcess);
    End;
  end;
end;

function MyShellExecute(const ShellExecuteInfo: TShellExecuteInfo; out ExitCode: DWORD; const ProcessMessages: TMethod): Boolean; overload;
begin
  Result := MyShellExecute(ShellExecuteInfo, ExitCode, True, ProcessMessages);
end;

function MyShellExecute(const ShellExecuteInfo: TShellExecuteInfo; Wait: Boolean; const ProcessMessages: TMethod): Boolean; overload;
var
  ExitCode: DWORD;
begin
  Result := MyShellExecute(ShellExecuteInfo, ExitCode, Wait, ProcessMessages);
end;

type
  TShellExecuteMessageHandler = record
  public
    procedure ProcessMessages;
  end;

procedure TShellExecuteMessageHandler.ProcessMessages;
begin
  Application.ProcessMessages;
  if Application.Terminated then begin
    Abort;
  end;
end;

function MyShellExecute(const Action, Filename, Parameters, Directory: string; Wait: Boolean): Boolean; overload;
var
  MessageHandler: TShellExecuteMessageHandler;
begin
  Try
    Result := MyShellExecute(
      DefaultShellExecuteInfo(Action, FileName, Parameters, Directory),
      Wait,
      MessageHandler.ProcessMessages
    );
  Except
    on EAbort do begin
      Result := False;//the wait has been terminated before the process signaled
    end;
  End;
end;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文