공지

[질문]델파이에서 윈도우의 커맨드(command,cmd) 명령어를 실행하여 그 결과값을 Memo1 에 출력하고 싶습니다.

고폴 2019. 1. 18. 09:13

[질문]델파이에서 윈도우의 커맨드(command,cmd) 명령어를 실행하여 그 결과값을 Memo1 에 출력하고 싶습니다.


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Edit1: TEdit;
    procedure Edit1KeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
function GetDosOutput(CommandLine: string; Work: string = 'C:\'): string;  { Run a DOS program and retrieve its output dynamically while it is running. }
var
  SecAtrrs: TSecurityAttributes;
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  StdOutPipeRead, StdOutPipeWrite: THandle;
  WasOK: Boolean;
  pCommandLine: array[0..255] of AnsiChar;
  BytesRead: Cardinal;
  WorkDir: string;
  Handle: Boolean;
begin
  Result := '';
  with SecAtrrs do begin
    nLength := SizeOf(SecAtrrs);
    bInheritHandle := True;
    lpSecurityDescriptor := nil;
  end;
  CreatePipe(StdOutPipeRead, StdOutPipeWrite, @SecAtrrs, 0);
  try
    with StartupInfo do
    begin
      FillChar(StartupInfo, SizeOf(StartupInfo), 0);
      cb := SizeOf(StartupInfo);
      dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
      wShowWindow := SW_HIDE;
      hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdin
      hStdOutput := StdOutPipeWrite;
      hStdError := StdOutPipeWrite;
    end;
    WorkDir := Work;
    Handle := CreateProcess(nil, PChar('cmd.exe /C ' + CommandLine),
                            nil, nil, True, 0, nil,
                            PChar(WorkDir), StartupInfo, ProcessInfo);
    CloseHandle(StdOutPipeWrite);
    if Handle then
      try
        repeat
          WasOK := windows.ReadFile(StdOutPipeRead, pCommandLine, 255, BytesRead, nil);
          if BytesRead > 0 then
          begin
            pCommandLine[BytesRead] := #0;
            Result := Result + pCommandLine;
          end;
        until not WasOK or (BytesRead = 0);
        WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
      finally
        CloseHandle(ProcessInfo.hThread);
        CloseHandle(ProcessInfo.hProcess);
      end;
  finally
    CloseHandle(StdOutPipeRead);
  end;
end;

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_RETURN then
  begin
    memo1.text := GetDosOutput(edit1.text);
  end;
end;

end.

>> 1. 개발/실행 플랫폼 
>>   (1) OS : 
>>   (2) 개발툴 : 
>>   (3) 사용 Database : 
>> 
>> 2. 개발 중인 프로그램 
>> 
>> 3. 질문 내용 
>>  
>>  ShellExecute 를 이용하여 CMD 창을 여는 것은 익히 알고 있습니다.
>>  하지만 그 열린 CMD창에서 어떠한 도스 명령 (예를 들어 dir/w 라던지..)을
>>  실행시켜 그 출력되는 값을 델파이의 메모장에 옮겨와 출력하고 싶습니다만
>>  이게 과연 가능한지 궁금합니다.
>>  현재 제가 알고 있는 지식으로는 
>>  C:\Windows\dir/w >> filelist.txt
>>  이런식으로 파일로 저장하여 그 파일을 불러오는 방법밖엔 생각이 안나네요.
>>  물론 단순히 파일리스트 얻어오는 dir/w 같은 명령이야 파일로 저장하여 그 파일을
>>  메모장에서 읽어올수도 있지만
>>  netstat 등을 이용하여 주기적인 시간을 설정하여 계속 배출되는 값을 읽어와야하는 경우에는
>>  다른 방법을 사용해야 할 것 같아요.
>> 
>>  정리하자면 
>>  꼭 CMD 창을 열지 않고
>>  도스 명령어를 실행하여 그 결과값을 메모장에 뿌리고 싶습니다.
>> 
>>