Avatar billede nca Juniormester
30. juni 2001 - 15:30 Der er 3 kommentarer og
1 løsning

Læse teksten i et DOS-vindue

Når jeg udfører kommandoen:

memo1.Lines.add(Screen(GetStdHandle(Std_Output_Handle),0,0,2000));

får jeg at vide, at handleren er ugyldig (Fejlkode 6).

Her er den procedure, der bliver kaldt:

function Screen(ConsoleOutput: THandle; const X, Y, Length: DWORD): String;
var
  ReadCoord: TCoord;
  NumberOfCharsRead: DWORD;
begin
  ReadCoord.X := X;
  ReadCoord.Y := Y;
  SetLength(Result, Length);
  if not ReadConsoleOutputCharacter(ConsoleOutput, PChar(Result), Length,
    ReadCoord, NumberOfCharsRead) then
    RaiseLastWin32Error;
  SetLength(Result, NumberOfCharsRead);
end;

Er der én der kan finde en løsning eller har en anden måde at læse indholdet fra et dosvindue, medens dos-programmet kører? Pipning af output til en tekst-fil kan ikke bruges, da programmet først skriver til filen, når det bliver lukket.
Avatar billede ziron Nybegynder
30. juni 2001 - 16:49 #1
prøv at se her:

http://www.eksperten.dk/spm/72187

/ZIRON
Avatar billede nca Juniormester
01. juli 2001 - 19:49 #2
Når jeg afvikler koden fra spm 72187 på Win98 og DOS-programmet venter på et input, låser Delphi-programmet hele maskinen.

Jeg har fundet nedenstående kode på nettet. Dette program virker både under Win98 og WinNT.
Jeg har selv forsøgt at sende tekst til DOS-programmet, men kan ikke finde ud af at få emuleret et tryk på RETURN-tasten.

Hvis én kan løse det problem, så er der stadig point at hente.
Avatar billede nca Juniormester
01. juli 2001 - 19:50 #3
Her er så koden :-)
Write-knappen er min egen tilføjelse og det eneste der ikke virker!!

unit csUnit1;

interface

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

type
  TForm1 = class(TForm)
    btnStart: TButton;
    btnStop: TButton;
    btnGrab: TButton;
    Memo1: TMemo;
    btnWrite: TButton;
   
    procedure btnStartClick(Sender: TObject);
    procedure btnStopClick(Sender: TObject);
    procedure btnGrabClick(Sender: TObject);
    procedure btnWriteClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1 : TForm1;
  hConsole : THandle;
  ProcessInfo : TProcessInformation;

implementation

{$R *.DFM}

// uses Console;

type
  cInfo = array[1..MAXINT div SizeOf(TCharInfo)] of TCharInfo;
  pcInfo = ^cInfo;

procedure TForm1.btnStartClick(Sender: TObject);
var
  zAppName:array[0..512] of char;
  zCurDir:array[0..255] of char;
  WorkDir:String;
  StartupInfo:TStartupInfo;
begin
  btnStart.Enabled := false;
  if AllocConsole then
  begin
    StrPCopy(zAppName,\'command.com /c dir\');
    WorkDir := \'c:\\\';
    StrPCopy(zCurDir,WorkDir);
    FillChar(StartupInfo,Sizeof(StartupInfo),#0);
    StartupInfo.cb := Sizeof(StartupInfo);
    StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
    StartupInfo.wShowWindow := SW_SHOWDEFAULT;
    if 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_SEPARATE_WOW_VDM 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
    begin
      SetConsoleTitle(PChar(\'Test Console Application\'));
      hConsole := GetStdHandle(STD_OUTPUT_HANDLE);
      btnStop.Enabled := true;
      btnGrab.Enabled := true;
      btnWrite.Enabled := true;
    end
    else
    begin
      btnStart.Enabled := true;
    end;
  end;
end;

procedure TForm1.btnStopClick(Sender: TObject);
var ProcessResult : dword; //integer;
begin
  try
    WaitforSingleObject(ProcessInfo.hProcess,INFINITE); //wait for DOS process
    GetExitCodeProcess(ProcessInfo.hProcess,ProcessResult);
    CloseHandle( ProcessInfo.hProcess );
    CloseHandle( ProcessInfo.hThread );
    CloseHandle(hConsole);
    FreeConsole;
    btnStop.Enabled := false;
    btnGrab.Enabled := false;
    btnWrite.Enabled := false;
    btnStart.Enabled := true;
  except
  end;
end;

procedure TForm1.btnGrabClick(Sender: TObject);
var
  hConOut : THandle;
  Dest : TCoord;
  csbi : TConsoleScreenBufferInfo; // used to get screen size
  i, j : integer;
  s : string;
  GrabBuff : pcInfo;
begin
  btnGrab.Enabled := false;
  Dest.X := 0;
  Dest.Y := 0;
  try
    hConOut := GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleScreenBufferInfo(hConOut, csbi);
    SetLength(s, csbi.dwMaximumWindowSize.X + 1);
    GetMem(GrabBuff, csbi.dwMaximumWindowSize.X *
csbi.dwMaximumWindowSize.Y * sizeof(TCharInfo));
    try
      // read the screen rectangle into the buffer
      ReadConsoleOutput(hConOut, // output buffer
                        GrabBuff, // buffer that receives data
                        csbi.dwMaximumWindowSize, // col/row size of destination buffer
                        Dest, // upper-left cell to write data to
                        csbi.srWindow); // screen buffer rectangle to read from
      //copy text data from pCharInfo to memo
      Memo1.Clear;
      for i := 0 to csbi.dwMaximumWindowSize.Y - 1 do
      begin
        s := \'\';
        for j := 1 to csbi.dwMaximumWindowSize.X do
          s := s +
              GrabBuff^[i*csbi.dwMaximumWindowSize.X + j].AsciiChar;
        Memo1.Lines.Add(s);
      end;
    finally
      freemem(GrabBuff);
    end;
  finally
    btnGrab.Enabled := true;
  end;
end;

procedure TForm1.btnWriteClick(Sender: TObject);
begin
  writeln(\'Y\'+chr(13));
end;

end.
Avatar billede nca Juniormester
24. juli 2001 - 09:04 #4
Jeg har løst problemet ad anden vej.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester