cmd.exe и delphi

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by baz1k, 8 Jan 2007.

  1. baz1k

    baz1k Elder - Старейшина

    Joined:
    22 Aug 2006
    Messages:
    38
    Likes Received:
    21
    Reputations:
    2
    Народ, подскажите пожалуйсто! Как реализовать командную строку на делфи, например я в Edit ввожу команду dir, а ее выполнение вижу в Memo...
     
  2. Deem3n®

    Deem3n® RTFMSDN

    Joined:
    19 Sep 2005
    Messages:
    378
    Likes Received:
    153
    Reputations:
    164
    Code:
    function GetDosOutput(const CommandLine: string): string;
    
    implementation
    
    {$R *.dfm}
    
    function GetDosOutput(const CommandLine: string): string;
    var
      SA: TSecurityAttributes;
      SI: TStartupInfo;
      PI: TProcessInformation;
      StdOutPipeRead, StdOutPipeWrite: THandle;
      WasOK: Boolean;
      Buffer: array[0..255] of Char;
      BytesRead: Cardinal;
      cmdLine, Line: string;
    begin
      Application.ProcessMessages;
      with SA do
      begin
        nLength := SizeOf(SA);
        bInheritHandle := True;
        lpSecurityDescriptor := nil;
      end;
      // создаем пайп для перенаправления стандартного вывода
      CreatePipe(StdOutPipeRead, // дескриптор чтения
        StdOutPipeWrite, // дескриптор записи
        @SA, // аттрибуты безопасности
        0 // количество байт принятых для пайпа - 0 по умолчанию
        );
      try
        // Создаем дочерний процесс, используя StdOutPipeWrite в качестве стандартного вывода,
        // а так же проверяем, чтобы он не показывался на экране.
        with SI do
        begin
          FillChar(SI, SizeOf(SI), 0);
          cb := SizeOf(SI);
          dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
          wShowWindow := SW_HIDE;
          hStdInput := GetStdHandle(STD_INPUT_HANDLE); // стандартный ввод не перенаправляем
          hStdOutput := StdOutPipeWrite;
          hStdError := StdOutPipeWrite;
        end;
    
        //WorkDir := ExtractFilePath(CommandLine);
        [color=red]cmdLine := PChar('C:\\WINDOWS\\system32\\cmd.exe /C ' + CommandLine);[/color]
        //ShowMessage(cmdLine);
        WasOK := CreateProcess(nil, PChar(cmdLine), nil, nil, True, 0, nil, PChar('C:\\'), SI, PI);
    
        // Теперь, когда дескриптор получен, для безопасности закрываем запись.
        // Нам не нужно, чтобы произошло случайное чтение или запись.
        CloseHandle(StdOutPipeWrite);
        // если процесс может быть создан, то дескриптор, это его вывод
        if not WasOK then
          raise Exception.Create('Could not execute command line!')
        else
        try
            // получаем весь вывод до тех пор, пока DOS-приложение не будет завершено
          Line := '';
          repeat
              // читаем блок символов (могут содержать возвраты каретки и переводы строки)
            WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);
    
              // есть ли что-нибудь еще для чтения?
            if BytesRead > 0 then
            begin
                // завершаем буфер PChar-ом
              Buffer[BytesRead] := #0;
                // добавляем буфер в общий вывод
              Line := Line + Buffer;
            end;
          until not WasOK or (BytesRead = 0);
            // ждем, пока завершится консольное приложение
          WaitForSingleObject(PI.hProcess, INFINITE);
        finally
            // Закрываем все оставшиеся дескрипторы
          CloseHandle(PI.hThread);
          CloseHandle(PI.hProcess);
        end;
      finally
        result := Line;
        CloseHandle(StdOutPipeRead);
      end;
    end;
    
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Memo1.Text := GetDosOutput(Edit1.Text);
    end;
    Это модификация кода из статьи "StdIn, StdOut и StdErr. Перенаправление, чтение и запись", Delphi World 6. Думаю пригодится
     
    2 people like this.