Q&A

  • call한 도스 프로그램이 종료되는 때를 어떻게 아는지...
도스 프로그램을 call하여 실행한 다음

call한 도스 프로그램이 종료되는 때를 어떻게 알 수 있는지요.



4  COMMENTS
  • Profile
    구창민 1999.08.05 08:04
    홍성원 께서 말씀하시기를...

    > 도스 프로그램을 call하여 실행한 다음

    > call한 도스 프로그램이 종료되는 때를 어떻게 알 수 있는지요.

    >



    홍성원님 안녕하세요?

    아래는 프로그램의 실행이 끝나기를 기다리는 소스인데,

    도움이 될런지 모르겠습니다.

    그럼 즐거운 프로그래밍 하세요~



    procedure SomeProc;

    var

    ProgramHandle : THandle;

    begin

    ProgramHandle := WinExec('C:특정프로그램.exe', SW_SHOWNORMAL);



    {프로그램이 종료될 때까지 반복}

    while GetModuleusage(ProgramHandle) <> 0 do application.processmessages;

    end;





  • Profile
    홍성원 1999.08.06 01:35
    구창민 께서 말씀하시기를...

    > 홍성원 께서 말씀하시기를...

    > > 도스 프로그램을 call하여 실행한 다음

    > > call한 도스 프로그램이 종료되는 때를 어떻게 알 수 있는지요.

    > >

    >

    > 홍성원님 안녕하세요?

    > 아래는 프로그램의 실행이 끝나기를 기다리는 소스인데,

    > 도움이 될런지 모르겠습니다.

    > 그럼 즐거운 프로그래밍 하세요~

    >

    > procedure SomeProc;

    > var

    > ProgramHandle : THandle;

    > begin

    > ProgramHandle := WinExec('C:특정프로그램.exe', SW_SHOWNORMAL);

    >

    > {프로그램이 종료될 때까지 반복}

    > while GetModuleusage(ProgramHandle) <> 0 do application.processmessages;

    > end;

    >

    >



    GetModuleusage();에서 에러가 납니다. (Delphi 3을 사용하고 있구요)

    Win32에 관련된 것이라고 생각되는 Help file들을 뒤져 보아도

    GetModuleusage()에 관한 내용은 찾을 수가 없었습니다.



    왜 에러가 나는지 알려주세요.



    그리고 다른 방법은 혹시 없나요?

  • Profile
    구창민 1999.08.06 02:48
    > GetModuleusage();에서 에러가 납니다. (Delphi 3을 사용하고 있구요)

    > Win32에 관련된 것이라고 생각되는 Help file들을 뒤져 보아도

    > GetModuleusage()에 관한 내용은 찾을 수가 없었습니다.

    >

    > 왜 에러가 나는지 알려주세요.

    >

    > 그리고 다른 방법은 혹시 없나요?



    홍성원님~ 구창민입니다.

    찾아보니 32비트체계에서 GetModuleusage() API가 없어진거 같습니다.

    아래는 32비트 체제에서 프로그램을 실행시키고 끝날때 까지

    기다리다 알아내는 함수입니다.





    unit Unit1;



    interface



    uses

    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

    StdCtrls, ShellApi;



    type

    TForm1 = class(TForm)

    Button1: TButton;

    procedure Button1Click(Sender: TObject);

    private

    { Private declarations }

    public

    { Public declarations }

    end;



    var

    Form1: TForm1;



    implementation



    {$R *.DFM}

    function WinExecAndWait32(FileName : PChar; CommandLine : PChar;

    Visibility : Integer) : Integer;

    var

    zAppName:array[0..512] of char;

    zCurDir:array[0..255] of char;

    WorkDir:ShortString;

    StartupInfo:TStartupInfo;

    ProcessInfo:TProcessInformation;

    begin

    StrCopy(zAppName, FileName);

    StrCat(zAppName, CommandLine);

    GetDir(0, WorkDir);

    StrPCopy(zCurDir, WorkDir);

    FillChar(StartupInfo, Sizeof(StartupInfo),#0);

    StartupInfo.cb := Sizeof(StartupInfo);

    StartupInfo.dwFlags := STARTF_USESHOWWINDOW;

    StartupInfo.wShowWindow := Visibility;

    if not CreateProcess(nil,

    zAppName, { pointer to command line string }

    nil, { pointer to process security attributes}

    nil, { pointer to thread security attributes }

    false, { handle inheritance flag }

    CREATE_NEW_CONSOLE or { creation flags }

    NORMAL_PRIORITY_CLASS,

    nil, { pointer to new environment block }

    nil, { pointer to current directory name }

    StartupInfo, { pointer to STARTUPINFO }

    ProcessInfo) then { pointer to PROCESS_INF }

    Result := -1

    else begin

    WaitforSingleObject(ProcessInfo.hProcess,INFINITE);

    GetExitCodeProcess(ProcessInfo.hProcess,Result);

    end;

    end;





    procedure TForm1.Button1Click(Sender: TObject);

    var ret: integer;

    begin

    //노트패드를 실행시키고 끝나면 OK 라는 문자를 찍는다.

    while WinExecAndWait32('notepad.exe', '', 1) <> 0 do

    Application.ProcessMessages;

    ShowMessage('OK~');

    end;



    end.



  • Profile
    홍성원 1999.08.06 05:25
    구창민 께서 말씀하시기를...

    > > GetModuleusage();에서 에러가 납니다. (Delphi 3을 사용하고 있구요)

    > > Win32에 관련된 것이라고 생각되는 Help file들을 뒤져 보아도

    > > GetModuleusage()에 관한 내용은 찾을 수가 없었습니다.

    > >

    > > 왜 에러가 나는지 알려주세요.

    > >

    > > 그리고 다른 방법은 혹시 없나요?

    >

    > 홍성원님~ 구창민입니다.

    > 찾아보니 32비트체계에서 GetModuleusage() API가 없어진거 같습니다.

    > 아래는 32비트 체제에서 프로그램을 실행시키고 끝날때 까지

    > 기다리다 알아내는 함수입니다.

    >

    >

    > unit Unit1;

    >

    > interface

    >

    > uses

    > Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

    > StdCtrls, ShellApi;

    >

    > type

    > TForm1 = class(TForm)

    > Button1: TButton;

    > procedure Button1Click(Sender: TObject);

    > private

    > { Private declarations }

    > public

    > { Public declarations }

    > end;

    >

    > var

    > Form1: TForm1;

    >

    > implementation

    >

    > {$R *.DFM}

    > function WinExecAndWait32(FileName : PChar; CommandLine : PChar;

    > Visibility : Integer) : Integer;

    > var

    > zAppName:array[0..512] of char;

    > zCurDir:array[0..255] of char;

    > WorkDir:ShortString;

    > StartupInfo:TStartupInfo;

    > ProcessInfo:TProcessInformation;

    > begin

    > StrCopy(zAppName, FileName);

    > StrCat(zAppName, CommandLine);

    > GetDir(0, WorkDir);

    > StrPCopy(zCurDir, WorkDir);

    > FillChar(StartupInfo, Sizeof(StartupInfo),#0);

    > StartupInfo.cb := Sizeof(StartupInfo);

    > StartupInfo.dwFlags := STARTF_USESHOWWINDOW;

    > StartupInfo.wShowWindow := Visibility;

    > if not CreateProcess(nil,

    > zAppName, { pointer to command line string }

    > nil, { pointer to process security attributes}

    > nil, { pointer to thread security attributes }

    > false, { handle inheritance flag }

    > CREATE_NEW_CONSOLE or { creation flags }

    > NORMAL_PRIORITY_CLASS,

    > nil, { pointer to new environment block }

    > nil, { pointer to current directory name }

    > StartupInfo, { pointer to STARTUPINFO }

    > ProcessInfo) then { pointer to PROCESS_INF }

    > Result := -1

    > else begin

    > WaitforSingleObject(ProcessInfo.hProcess,INFINITE);

    > GetExitCodeProcess(ProcessInfo.hProcess,Result);

    > end;

    > end;

    >

    >

    > procedure TForm1.Button1Click(Sender: TObject);

    > var ret: integer;

    > begin

    > //노트패드를 실행시키고 끝나면 OK 라는 문자를 찍는다.

    > while WinExecAndWait32('notepad.exe', '', 1) <> 0 do

    > Application.ProcessMessages;

    > ShowMessage('OK~');

    > end;

    >

    > end.

    >



    답변 감사드립니다.



    처음 답변에서 에러가 나서 저도 나름대로 찾아보았는데,

    구창민 님의 [리다이렉션]에서 힌트를 얻어 시도해보았습니다.



    결론은... 성공하였습니다.



    도스 프로그램의 실행시간이 22초 가량되는데 [리다이렉션]의

    function에서 output file을 생성하면 실행시간이 4배 정도로

    길어지더군요. 그래서 output file을 생성하지 않도록 function을

    약간 수정하였더니 원하는 대로 실행이 되었습니다.



    감사합니다.