我也到borland新闻组问了,结果如下,好象和你说的差不多,不过我不太懂,你看看: Subject: Re: How to get the output of a console application? Date: Fri, 4 May 2001 17:04:31 +0200 From: "Rick Betting" <[email protected]> Newsgroups: borland.public.delphi.winapi You can redirect the output handle. Create a pipe (Anonymous or named). Run the console app using CreateProcess. Use the next members of StartupInformation: STARTUPINFO; StartupInformation.dwFlags := STARTF_USESTDHANDLES; StartupInformation.hStdOutput := PipeHandle; StartupInformation.hStdError := GetSTDHandle(STD_ERROR_HANDLE); StartupInformation.hStdInput := GetSTDHandle(STD_INPUT_HANDLE);Now you can read the output from the pipe.--Rick Betting [email protected] (Remove AT and DOT )I don't like spammers so send your spam to [email protected]"Gary" <[email protected]> schreef in bericht news:3af28d8c$1_1@dnews... > > I want to run a console application in my windows app,and get any of its output in time(right after the output operation is done) to show it in my TMemo control. > How can I do it?
可惜需要注册。烦人~~~~~~~~~~~,给你一个Console类把: 来自JHzCode :unit uConsoleClass;interfaceuses Windows;type TConsoleControl = Class private FhStdIn : THandle; // Handle to the standard input FhStdOut : THandle; // Handle to the standard output FhStdErr : THandle; // Handle to the standard error (Output) FbConsoleAllocated : Boolean; // Creation Flag FBgAttrib : Cardinal; // Currently set BackGround Attribs. FFgAttrib : Cardinal; // Currently set ForeGround Attribs. public constructor Create; (* Creates a new consolewindow, or connects the current window *) destructor Destroy;override; (* Cleanup of the class structures *) (* Color properties: The console window does not handle the colors like known form delphi components. Each color will be created from a red,green,blue and a intensity part. In fact the resulting colors are the same as the well known 16 base colors (clwhite .. clBlack). Black ist if all flags are false, white if all flag are true. The following two functions will change the color for following writes *) procedure SetForegroundColor(bRed,bGreen,bBlue,bIntensity : Boolean); procedure SetBackgroundColor(bRed,bGreen,bBlue,bIntensity : Boolean); (* Writing functions : simple wrapper around WriteConsole *) procedure WriteText (const s : string); procedure WriteTextLine( const s : string); (* Change the Windowtitle of the command window. If the program has been executed from a CMD-box the title change is only active while the programs execution time *) procedure SetWindowTitle (const sTitle : string); (* some Cursor manipulation functions *) procedure ShowCursor ( iSize : Integer); procedure HideCursor; procedure GetCursorPos( var x,y : integer); procedure SetCursorTo(x,y : integer); (* screen operations: the screen ist the visible part of a cmd window. Behind the window there is a screenbuffer. The screenbuffer may be larger than the visible window *) procedure ClearScreen; function GetScreenLeft : integer; function GetScreenTop : Integer; function GetScreenHeight : integer; function GetScreenWidth : integer; (* screenbuffer operations *) procedure ClearBuffer; function GetBufferHeight : integer; function GetBufferWidth : integer; (* sample to read characters from then screenbuffer *) procedure GetCharAtPos(x,y : Integer;var rCharInfo : Char); end;implementation{ TConsoleControl }procedure TConsoleControl.ClearBuffer; var SBInfo : TConsoleScreenBufferInfo; ulWrittenChars : Cardinal; TopLeft : TCoord; begin TopLeft.X := 0; TopLeft.Y := 0; GetConsoleScreenBufferInfo(FhStdOut,SBInfo); FillConsoleOutputCharacter(FhStdOut,' ', SBInfo.dwSize.X * SBInfo.dwSize.Y, TopLeft, ulWrittenChars); FillConsoleOutputAttribute( FhStdOut, FOREGROUND_RED or FOREGROUND_BLUE or FOREGROUND_GREEN, (SBInfo.srWindow.Right - SBInfo.srWindow.Left) * (SBInfo.srWindow.Bottom - SBInfo.srWindow.Top), TopLeft, ulWrittenChars); end;procedure TConsoleControl.ClearScreen; var SBInfo : TConsoleScreenBufferInfo; ulWrittenChars : Cardinal; TopLeft : TCoord;begin GetConsoleScreenBufferInfo(FhStdOut,SBInfo); TopLeft.X := SBInfo.srWindow.Left; TopLeft.Y := SBInfo.srWindow.Top; FillConsoleOutputCharacter(FhStdOut,' ', (SBInfo.srWindow.Right - SBInfo.srWindow.Left) * (SBInfo.srWindow.Bottom - SBInfo.srWindow.Top), TopLeft, ulWrittenChars); FillConsoleOutputAttribute(FhStdOut,FOREGROUND_RED or FOREGROUND_BLUE or FOREGROUND_GREEN, (SBInfo.srWindow.Right - SBInfo.srWindow.Left) * (SBInfo.srWindow.Bottom - SBInfo.srWindow.Top), TopLeft, ulWrittenChars); end;constructor TConsoleControl.Create; begin inherited Create; // A process can be associated with only one console, so the AllocConsole // function fails if the calling process already has a console. FbConsoleAllocated := AllocConsole;// initializing the needed handles FhStdOut := GetStdHandle(STD_OUTPUT_HANDLE); FhStdErr := GetStdHandle(STD_ERROR_HANDLE); FhStdIn := GetStdHandle(STD_INPUT_HANDLE); end;destructor TConsoleControl.Destroy; begin if FbConsoleAllocated then FreeConsole; inherited; end;function TConsoleControl.GetBufferHeight: integer; var SBInfo : TConsoleScreenBufferInfo;begin GetConsoleScreenBufferInfo(FhStdOut,SBInfo); Result := SBInfo.dwSize.Y; end;function TConsoleControl.GetBufferWidth: integer; var SBInfo : TConsoleScreenBufferInfo;begin GetConsoleScreenBufferInfo(FhStdOut,SBInfo); Result := SBInfo.dwSize.X; end;procedure TConsoleControl.GetCharAtPos(x, y: Integer; var rCharInfo : Char); var CharInfo : array [0..10] of Char; TopLeft : TCoord; CharsRead : Cardinal; begin TopLeft.x := X; TopLeft.Y := Y; ReadConsoleOutputCharacter(FhStdOut,CharInfo,10,TopLeft,CharsRead); rCharInfo := CharInfo[0]; end;procedure TConsoleControl.GetCursorPos(var x, y: integer); var SBInfo : TConsoleScreenBufferInfo;begin GetConsoleScreenBufferInfo(FhStdOut,SBInfo); x := SBInfo.dwCursorPosition.X; y := SBInfo.dwCursorPosition.Y; end;function TConsoleControl.GetScreenHeight: integer; var SBInfo : TConsoleScreenBufferInfo;begin GetConsoleScreenBufferInfo(FhStdOut,SBInfo); Result := SBInfo.srWindow.Bottom -SBInfo.srWindow.Top; end;function TConsoleControl.GetScreenLeft: integer; var SBInfo : TConsoleScreenBufferInfo;begin GetConsoleScreenBufferInfo(FhStdOut,SBInfo); Result := SBInfo.srWindow.Left; end;function TConsoleControl.GetScreenTop: Integer; var SBInfo : TConsoleScreenBufferInfo;begin GetConsoleScreenBufferInfo(FhStdOut,SBInfo); Result := SBInfo.srWindow.Top; end;function TConsoleControl.GetScreenWidth: integer; var SBInfo : TConsoleScreenBufferInfo;begin GetConsoleScreenBufferInfo(FhStdOut,SBInfo); Result := SBInfo.srWindow.Right - SBInfo.srWindow.Left; end;procedure TConsoleControl.HideCursor; var ConsoleCursorInfo : TConsoleCursorInfo; begin GetConsoleCursorInfo(FhStdOut,ConsoleCursorInfo); if ConsoleCursorInfo.bVisible then begin ConsoleCursorInfo.bVisible := False; SetConsoleCursorInfo(FhStdOut,ConsoleCursorInfo); end; end;procedure TConsoleControl.SetBackgroundColor(bRed, bGreen, bBlue, bIntensity: Boolean);begin FBgAttrib := 0; if bRed then FBgAttrib := FBgAttrib or BACKGROUND_RED; if bGreen then FBgAttrib := FBgAttrib or BACKGROUND_GREEN; if bBlue then FBgAttrib := FBgAttrib or BACKGROUND_BLUE; if bIntensity then FBgAttrib := FBgAttrib or BACKGROUND_INTENSITY; SetConsoleTextAttribute(FhStdOut,FBgAttrib or FFgAttrib); end;procedure TConsoleControl.SetCursorTo(x, y: integer); var Coords : TCoord; SBInfo : TConsoleScreenBufferInfo;begin GetConsoleScreenBufferInfo(FhStdOut,SBInfo); if x < 0 then Exit; if y < 0 then Exit; if x > SbInfo.dwSize.X then Exit; if y > SbInfo.dwSize.Y then Exit; Coords.X := x; Coords.Y := y; SetConsoleCursorPosition(FhStdOut,Coords); end;procedure TConsoleControl.SetForegroundColor(bRed, bGreen, bBlue, bIntensity: Boolean);begin FFgAttrib := 0; if bRed then FFgAttrib := FFgAttrib or FOREGROUND_RED; if bGreen then FFgAttrib := FFgAttrib or FOREGROUND_GREEN; if bBlue then FFgAttrib := FFgAttrib or FOREGROUND_BLUE; if bIntensity then FFgAttrib := FFgAttrib or FOREGROUND_INTENSITY; SetConsoleTextAttribute(FhStdOut,FBgAttrib or FFgAttrib); end;procedure TConsoleControl.SetWindowTitle(const sTitle: string); begin SetConsoleTitle(PChar(sTitle)); end;procedure TConsoleControl.ShowCursor(iSize: Integer); var ConsoleCursorInfo : TConsoleCursorInfo; begin GetConsoleCursorInfo(FhStdOut,ConsoleCursorInfo); if (not ConsoleCursorInfo.bVisible) or ( ConsoleCursorInfo.dwSize <> iSize ) then begin ConsoleCursorInfo.bVisible := True; ConsoleCursorInfo.dwSize := iSize; SetConsoleCursorInfo(FhStdOut,ConsoleCursorInfo); end; end;procedure TConsoleControl.WriteText(const s: string); var ulLength : Cardinal; begin WriteConsole(FhStdOut,PChar(s),Length(s),ulLength,NIL); end;procedure TConsoleControl.WriteTextLine(const s: string); begin WriteText(s+#13#10); end;end.---------- end of unit uConsoleClass ----------------- sample main that simulates a "starfield" ---------- program console; {$APPTYPE CONSOLE} uses SysUtils, Windows, uConsoleClass in 'uConsoleClass.pas';var MyConsole : TConsoleControl;procedure Stars ; var x,y,w,h : Integer; x1,y1 : Integer; CharInfo: Char; i : integer; begin MyConsole.ClearScreen; x := MyConsole.GetScreenLeft; y := MyConsole.GetScreenTop; h := MyConsole.GetScreenHeight div 4; w := MyConsole.GetScreenWidth div 4; for i := 1 to 15000 do begin x1 := x+Random(w)*4; y1 := y+Random(h)*4; MyConsole.SetCursorTo(x1,y1); MyConsole.GetCharAtPos(x1,y1,CharInfo);MyConsole.SetForegroundColor(Bool(Random(2)),Bool(Random(2)),Bool(Random(2)) ,Bool(Random(2))); if (CharInfo = ' ') or (CharInfo = #0) then begin MyConsole.WriteText('.'); end else if CharInfo = '.' then begin MyConsole.WriteText('+'); end else if CharInfo = '+' then begin MyConsole.WriteText('*'); end else if CharInfo = '*' then begin MyConsole.WriteText(' '); end; sleep (5); end; end;begin MyConsole := TConsoleControl.Create; Stars ; MyConsole.Free; end. procedure TfmDbuMain.ExecuteISQL(FileName: string);const BufSize = $4000;type TPipeHandles = record hRead, hWrite: DWORD; end; procedure ClosePipe(var Pipe: TPipeHandles); begin with Pipe do begin if hRead <> 0 then CloseHandle (hRead); if hWrite <> 0 then CloseHandle (hWrite); hRead := 0; hWrite := 0; end; end; function ReadPipe(var Pipe: TPipeHandles): string; var ReadBuf: array[0..BufSize] of Char; BytesRead: Dword; begin result := ''; if PeekNamedPipe(Pipe.hRead, nil, 0, nil, @BytesRead, nil) and (BytesRead > 0) then begin ReadFile(Pipe.hRead, ReadBuf, BytesRead, BytesRead, nil); if BytesRead > 0 then begin ReadBuf[BytesRead] := #0; result := ReadBuf; end; end; end;var SecAttr : TSecurityAttributes; StartupInfo: TStartupInfo; PipeStdOut: TPipeHandles; PipeStdErr: TPipeHandles; Cmd: string; dwExitCode: DWORD; outstr: string; error_msg: string;begin SecAttr.nLength := SizeOf(SecAttr); SecAttr.lpSecurityDescriptor := nil; SecAttr.bInheritHandle := TRUE;error_msg := ''; with PipeStdOut do if not CreatePipe (hRead, hWrite, @SecAttr, BufSize) then XWinError('Ne mogu kreirati STDOUT pipe');try with PipeStdErr do if not CreatePipe (hRead, hWrite, @SecAttr, BufSize) then XWinError('Ne mogu kreirati STDERR pipe'); except ClosePipe(PipeStdOut); raise; end; try FillChar(StartupInfo,SizeOf(StartupInfo), 0); with StartupInfo do begin cb:= SizeOf(StartupInfo); dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES; hStdOutput := PipeStdOut.hWrite; hStdError := PipeStdErr.hWrite; wShowWindow := SW_HIDE; end; Cmd := FMSSQLBinnDir + 'isql.exe' + ' -S "'+dmPMXData.DBServerName+'"' + ' -U "'+'sa'+'"' + ' -P "'+''+'"' + ' -d "'+dmPMXData.DBDatabaseName+'"' + ' -w 255 -n ' + ' -i "'+FileName+'"' + ' -r1 -l 10'; if CreateProcess( nil, PChar(Cmd), nil, nil, true, DETACHED_PROCESS or NORMAL_PRIORITY_CLASS, nil, PChar(XWorkDir), StartupInfo, ProcessInformation ) then begin dwExitCode := STILL_ACTIVE; Screen.Cursor := crHourglass; bbTerminate.Enabled := true; try repeat file://WaitForSingleObject(ProcessInformation.hProcess, 0); GetExitCodeProcess(ProcessInformation.hProcess, dwExitCode); Application.ProcessMessages; outstr := ReadPipe(PipeStdOut); if outstr <> '' then begin LogStyle(ltNormal); meOutput.SelText := outstr; meOutput.Perform(EM_SCROLLCARET, 0, 0); end; outstr := ReadPipe(PipeStdErr); if outstr <> '' then begin LogStyle(ltError); meOutput.SelText := outstr; meOutput.Perform(EM_SCROLLCARET, 0, 0); if (error_msg = '') and (Pos('Msg 1105, Level 17', outstr) > 0) then begin (* Error Message text: Can't allocate space for object '%.*s' in database '%.*s' because the '%.*s' segment is full. If you ran out of space in Syslogs, dump the transaction log. Otherwise, use ALTER DATABASE or sp_extendsegment to increase the size of the segment. *) error_msg := 'Nema mjesta na segmentu baze podataka, treba pokusati isprazniti transaction log ili pove鎍ti bazu.'; end; end; until dwExitCode <> STILL_ACTIVE; if not GetExitCodeProcess(ProcessInformation.hProcess, dwExitCode) then XWinError('Ne mogu o鑙tati exit code!'); if dwExitCode <> 0 then raise Exception.Create('Exit code ' + IntToStr(dwExitCode)); finally Screen.Cursor := crDefault; bbTerminate.Enabled := false; if dwExitCode = STILL_ACTIVE then TerminateProcess(ProcessInformation.hProcess, 1); CloseHandle(ProcessInformation.hProcess); CloseHandle(ProcessInformation.hThread); ProcessInformation.hProcess := 0; end; end else XWinError('Ne mogu lansirati ' + FMSSQLBinnDir + 'isql.exe!' + #10 + 'Cmd: ' + Cmd); finally ClosePipe(PipeStdOut); ClosePipe(PipeStdErr); end;if error_msg <> '' then raise Exception.Create(error_msg); end;
如果是DOS程序,可以:
filename > out
我想要的是对于每一个输出动作,我都要及时得到,就是用我的MEMO来模仿Windows的Dos模拟器窗口,可以做到吗?
AllocConsole
CreateConsoleScreenBuffer
FillConsoleOutputAttribute
FillConsoleOutputCharacter
FlushConsoleInputBuffer
FreeConsole
GenerateConsoleCtrlEvent
GetConsoleCP
GetConsoleCursorInfo
GetConsoleMode
GetConsoleOutputCP
GetConsoleScreenBufferInfo
GetConsoleTitle
GetLargestConsoleWindowSize
GetNumberOfConsoleInputEvents
GetNumberOfConsoleMouseButtons
GetStdHandle
HandlerRoutine
PeekConsoleInput
ReadConsole
ReadConsoleInput
ReadConsoleOutput
ReadConsoleOutputAttribute
ReadConsoleOutputCharacter
ScrollConsoleScreenBuffer
SetConsoleActiveScreenBuffer
SetConsoleCP
SetConsoleCtrlHandler
SetConsoleCursorInfo
SetConsoleCursorPosition
SetConsoleMode
SetConsoleOutputCP
SetConsoleScreenBufferSize
SetConsoleTextAttribute
SetConsoleTitle
SetConsoleWindowInfo
SetStdHandle
WriteConsole
WriteConsoleInput
WriteConsoleOutput
WriteConsoleOutputAttribute
WriteConsoleOutputCharacter
Subject: Re: How to get the output of a console application?
Date: Fri, 4 May 2001 17:04:31 +0200
From: "Rick Betting" <[email protected]>
Newsgroups: borland.public.delphi.winapi You can redirect the output handle.
Create a pipe (Anonymous or named).
Run the console app using CreateProcess.
Use the next members of StartupInformation: STARTUPINFO; StartupInformation.dwFlags := STARTF_USESTDHANDLES;
StartupInformation.hStdOutput := PipeHandle;
StartupInformation.hStdError := GetSTDHandle(STD_ERROR_HANDLE);
StartupInformation.hStdInput := GetSTDHandle(STD_INPUT_HANDLE);Now you can read the output from the pipe.--Rick Betting
[email protected]
(Remove AT and DOT )I don't like spammers so send your spam to
[email protected]"Gary" <[email protected]> schreef in bericht news:3af28d8c$1_1@dnews...
>
> I want to run a console application in my windows app,and get any of its
output in time(right after the output operation is done) to show it in my
TMemo control.
> How can I do it?
打开tmp。txt就得到了内容
来自JHzCode :unit uConsoleClass;interfaceuses Windows;type
TConsoleControl = Class
private
FhStdIn : THandle; // Handle to the standard input
FhStdOut : THandle; // Handle to the standard output
FhStdErr : THandle; // Handle to the standard error (Output)
FbConsoleAllocated : Boolean; // Creation Flag
FBgAttrib : Cardinal; // Currently set BackGround Attribs.
FFgAttrib : Cardinal; // Currently set ForeGround Attribs.
public
constructor Create;
(* Creates a new consolewindow, or connects the current window *)
destructor Destroy;override;
(* Cleanup of the class structures *) (* Color properties:
The console window does not handle the colors like known form delphi
components. Each color will be created from a red,green,blue and a
intensity part. In fact the resulting colors are the same as the well
known 16 base colors (clwhite .. clBlack).
Black ist if all flags are false, white if all flag are true.
The following two functions will change the color for following
writes *) procedure SetForegroundColor(bRed,bGreen,bBlue,bIntensity : Boolean);
procedure SetBackgroundColor(bRed,bGreen,bBlue,bIntensity : Boolean); (* Writing functions :
simple wrapper around WriteConsole
*)
procedure WriteText (const s : string);
procedure WriteTextLine( const s : string); (* Change the Windowtitle of the command window. If the program has been
executed from a CMD-box the title change is only active while the
programs execution time *)
procedure SetWindowTitle (const sTitle : string); (* some Cursor manipulation functions *)
procedure ShowCursor ( iSize : Integer);
procedure HideCursor;
procedure GetCursorPos( var x,y : integer);
procedure SetCursorTo(x,y : integer); (* screen operations:
the screen ist the visible part of a cmd window. Behind the window
there
is a screenbuffer. The screenbuffer may be larger than the visible
window *)
procedure ClearScreen;
function GetScreenLeft : integer;
function GetScreenTop : Integer;
function GetScreenHeight : integer;
function GetScreenWidth : integer; (* screenbuffer operations *)
procedure ClearBuffer;
function GetBufferHeight : integer;
function GetBufferWidth : integer; (* sample to read characters from then screenbuffer *)
procedure GetCharAtPos(x,y : Integer;var rCharInfo : Char);
end;implementation{ TConsoleControl }procedure TConsoleControl.ClearBuffer;
var
SBInfo : TConsoleScreenBufferInfo;
ulWrittenChars : Cardinal;
TopLeft : TCoord;
begin
TopLeft.X := 0;
TopLeft.Y := 0;
GetConsoleScreenBufferInfo(FhStdOut,SBInfo); FillConsoleOutputCharacter(FhStdOut,' ',
SBInfo.dwSize.X * SBInfo.dwSize.Y,
TopLeft,
ulWrittenChars); FillConsoleOutputAttribute( FhStdOut,
FOREGROUND_RED or FOREGROUND_BLUE or
FOREGROUND_GREEN,
(SBInfo.srWindow.Right - SBInfo.srWindow.Left)
*
(SBInfo.srWindow.Bottom -
SBInfo.srWindow.Top),
TopLeft,
ulWrittenChars);
end;procedure TConsoleControl.ClearScreen;
var
SBInfo : TConsoleScreenBufferInfo;
ulWrittenChars : Cardinal;
TopLeft : TCoord;begin
GetConsoleScreenBufferInfo(FhStdOut,SBInfo);
TopLeft.X := SBInfo.srWindow.Left;
TopLeft.Y := SBInfo.srWindow.Top;
FillConsoleOutputCharacter(FhStdOut,' ',
(SBInfo.srWindow.Right - SBInfo.srWindow.Left)
*
(SBInfo.srWindow.Bottom - SBInfo.srWindow.Top),
TopLeft,
ulWrittenChars);
FillConsoleOutputAttribute(FhStdOut,FOREGROUND_RED or FOREGROUND_BLUE or
FOREGROUND_GREEN,
(SBInfo.srWindow.Right - SBInfo.srWindow.Left)
*
(SBInfo.srWindow.Bottom - SBInfo.srWindow.Top),
TopLeft,
ulWrittenChars);
end;constructor TConsoleControl.Create;
begin
inherited Create;
// A process can be associated with only one console, so the AllocConsole
// function fails if the calling process already has a console.
FbConsoleAllocated := AllocConsole;// initializing the needed handles
FhStdOut := GetStdHandle(STD_OUTPUT_HANDLE);
FhStdErr := GetStdHandle(STD_ERROR_HANDLE);
FhStdIn := GetStdHandle(STD_INPUT_HANDLE);
end;destructor TConsoleControl.Destroy;
begin
if FbConsoleAllocated then FreeConsole;
inherited;
end;function TConsoleControl.GetBufferHeight: integer;
var
SBInfo : TConsoleScreenBufferInfo;begin
GetConsoleScreenBufferInfo(FhStdOut,SBInfo);
Result := SBInfo.dwSize.Y;
end;function TConsoleControl.GetBufferWidth: integer;
var
SBInfo : TConsoleScreenBufferInfo;begin
GetConsoleScreenBufferInfo(FhStdOut,SBInfo);
Result := SBInfo.dwSize.X;
end;procedure TConsoleControl.GetCharAtPos(x, y: Integer; var rCharInfo : Char);
var
CharInfo : array [0..10] of Char;
TopLeft : TCoord;
CharsRead : Cardinal;
begin
TopLeft.x := X;
TopLeft.Y := Y;
ReadConsoleOutputCharacter(FhStdOut,CharInfo,10,TopLeft,CharsRead);
rCharInfo := CharInfo[0];
end;procedure TConsoleControl.GetCursorPos(var x, y: integer);
var
SBInfo : TConsoleScreenBufferInfo;begin
GetConsoleScreenBufferInfo(FhStdOut,SBInfo);
x := SBInfo.dwCursorPosition.X;
y := SBInfo.dwCursorPosition.Y;
end;function TConsoleControl.GetScreenHeight: integer;
var
SBInfo : TConsoleScreenBufferInfo;begin
GetConsoleScreenBufferInfo(FhStdOut,SBInfo);
Result := SBInfo.srWindow.Bottom -SBInfo.srWindow.Top;
end;function TConsoleControl.GetScreenLeft: integer;
var
SBInfo : TConsoleScreenBufferInfo;begin
GetConsoleScreenBufferInfo(FhStdOut,SBInfo);
Result := SBInfo.srWindow.Left;
end;function TConsoleControl.GetScreenTop: Integer;
var
SBInfo : TConsoleScreenBufferInfo;begin
GetConsoleScreenBufferInfo(FhStdOut,SBInfo);
Result := SBInfo.srWindow.Top;
end;function TConsoleControl.GetScreenWidth: integer;
var
SBInfo : TConsoleScreenBufferInfo;begin
GetConsoleScreenBufferInfo(FhStdOut,SBInfo);
Result := SBInfo.srWindow.Right - SBInfo.srWindow.Left;
end;procedure TConsoleControl.HideCursor;
var
ConsoleCursorInfo : TConsoleCursorInfo;
begin
GetConsoleCursorInfo(FhStdOut,ConsoleCursorInfo);
if ConsoleCursorInfo.bVisible then begin
ConsoleCursorInfo.bVisible := False;
SetConsoleCursorInfo(FhStdOut,ConsoleCursorInfo);
end;
end;procedure TConsoleControl.SetBackgroundColor(bRed, bGreen, bBlue,
bIntensity: Boolean);begin
FBgAttrib := 0;
if bRed then FBgAttrib := FBgAttrib or BACKGROUND_RED;
if bGreen then FBgAttrib := FBgAttrib or BACKGROUND_GREEN;
if bBlue then FBgAttrib := FBgAttrib or BACKGROUND_BLUE;
if bIntensity then FBgAttrib := FBgAttrib or BACKGROUND_INTENSITY;
SetConsoleTextAttribute(FhStdOut,FBgAttrib or FFgAttrib);
end;procedure TConsoleControl.SetCursorTo(x, y: integer);
var
Coords : TCoord;
SBInfo : TConsoleScreenBufferInfo;begin
GetConsoleScreenBufferInfo(FhStdOut,SBInfo);
if x < 0 then Exit;
if y < 0 then Exit;
if x > SbInfo.dwSize.X then Exit;
if y > SbInfo.dwSize.Y then Exit; Coords.X := x;
Coords.Y := y;
SetConsoleCursorPosition(FhStdOut,Coords);
end;procedure TConsoleControl.SetForegroundColor(bRed, bGreen, bBlue,
bIntensity: Boolean);begin
FFgAttrib := 0;
if bRed then FFgAttrib := FFgAttrib or FOREGROUND_RED;
if bGreen then FFgAttrib := FFgAttrib or FOREGROUND_GREEN;
if bBlue then FFgAttrib := FFgAttrib or FOREGROUND_BLUE;
if bIntensity then FFgAttrib := FFgAttrib or FOREGROUND_INTENSITY;
SetConsoleTextAttribute(FhStdOut,FBgAttrib or FFgAttrib);
end;procedure TConsoleControl.SetWindowTitle(const sTitle: string);
begin
SetConsoleTitle(PChar(sTitle));
end;procedure TConsoleControl.ShowCursor(iSize: Integer);
var
ConsoleCursorInfo : TConsoleCursorInfo;
begin
GetConsoleCursorInfo(FhStdOut,ConsoleCursorInfo);
if (not ConsoleCursorInfo.bVisible) or
( ConsoleCursorInfo.dwSize <> iSize ) then begin
ConsoleCursorInfo.bVisible := True;
ConsoleCursorInfo.dwSize := iSize;
SetConsoleCursorInfo(FhStdOut,ConsoleCursorInfo);
end;
end;procedure TConsoleControl.WriteText(const s: string);
var
ulLength : Cardinal;
begin
WriteConsole(FhStdOut,PChar(s),Length(s),ulLength,NIL);
end;procedure TConsoleControl.WriteTextLine(const s: string);
begin
WriteText(s+#13#10);
end;end.---------- end of unit uConsoleClass ----------------- sample main that simulates a "starfield" ----------
program console;
{$APPTYPE CONSOLE}
uses
SysUtils,
Windows,
uConsoleClass in 'uConsoleClass.pas';var
MyConsole : TConsoleControl;procedure Stars ;
var
x,y,w,h : Integer;
x1,y1 : Integer;
CharInfo: Char;
i : integer;
begin
MyConsole.ClearScreen;
x := MyConsole.GetScreenLeft;
y := MyConsole.GetScreenTop;
h := MyConsole.GetScreenHeight div 4;
w := MyConsole.GetScreenWidth div 4;
for i := 1 to 15000 do begin
x1 := x+Random(w)*4;
y1 := y+Random(h)*4;
MyConsole.SetCursorTo(x1,y1);
MyConsole.GetCharAtPos(x1,y1,CharInfo);MyConsole.SetForegroundColor(Bool(Random(2)),Bool(Random(2)),Bool(Random(2))
,Bool(Random(2)));
if (CharInfo = ' ') or (CharInfo = #0) then begin
MyConsole.WriteText('.');
end
else if CharInfo = '.' then begin
MyConsole.WriteText('+');
end
else if CharInfo = '+' then begin
MyConsole.WriteText('*');
end
else if CharInfo = '*' then begin
MyConsole.WriteText(' ');
end;
sleep (5);
end;
end;begin
MyConsole := TConsoleControl.Create;
Stars ;
MyConsole.Free;
end.
procedure TfmDbuMain.ExecuteISQL(FileName: string);const
BufSize = $4000;type
TPipeHandles = record
hRead,
hWrite: DWORD;
end; procedure ClosePipe(var Pipe: TPipeHandles);
begin
with Pipe do
begin
if hRead <> 0 then CloseHandle (hRead);
if hWrite <> 0 then CloseHandle (hWrite);
hRead := 0;
hWrite := 0;
end;
end; function ReadPipe(var Pipe: TPipeHandles): string;
var
ReadBuf: array[0..BufSize] of Char;
BytesRead: Dword;
begin
result := '';
if PeekNamedPipe(Pipe.hRead, nil, 0, nil, @BytesRead, nil) and
(BytesRead > 0) then
begin
ReadFile(Pipe.hRead, ReadBuf, BytesRead, BytesRead, nil);
if BytesRead > 0 then
begin
ReadBuf[BytesRead] := #0;
result := ReadBuf;
end;
end;
end;var
SecAttr : TSecurityAttributes;
StartupInfo: TStartupInfo;
PipeStdOut: TPipeHandles;
PipeStdErr: TPipeHandles;
Cmd: string;
dwExitCode: DWORD; outstr: string;
error_msg: string;begin
SecAttr.nLength := SizeOf(SecAttr);
SecAttr.lpSecurityDescriptor := nil;
SecAttr.bInheritHandle := TRUE;error_msg := ''; with PipeStdOut do
if not CreatePipe (hRead, hWrite, @SecAttr, BufSize) then
XWinError('Ne mogu kreirati STDOUT pipe');try
with PipeStdErr do
if not CreatePipe (hRead, hWrite, @SecAttr, BufSize) then
XWinError('Ne mogu kreirati STDERR pipe');
except
ClosePipe(PipeStdOut);
raise;
end; try
FillChar(StartupInfo,SizeOf(StartupInfo), 0);
with StartupInfo do
begin
cb:= SizeOf(StartupInfo);
dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
hStdOutput := PipeStdOut.hWrite;
hStdError := PipeStdErr.hWrite;
wShowWindow := SW_HIDE;
end; Cmd := FMSSQLBinnDir + 'isql.exe' +
' -S "'+dmPMXData.DBServerName+'"' +
' -U "'+'sa'+'"' +
' -P "'+''+'"' +
' -d "'+dmPMXData.DBDatabaseName+'"' +
' -w 255 -n ' +
' -i "'+FileName+'"' +
' -r1 -l 10'; if CreateProcess(
nil, PChar(Cmd), nil, nil, true,
DETACHED_PROCESS or NORMAL_PRIORITY_CLASS,
nil, PChar(XWorkDir),
StartupInfo,
ProcessInformation
) then
begin
dwExitCode := STILL_ACTIVE;
Screen.Cursor := crHourglass;
bbTerminate.Enabled := true;
try
repeat
file://WaitForSingleObject(ProcessInformation.hProcess, 0);
GetExitCodeProcess(ProcessInformation.hProcess,
dwExitCode); Application.ProcessMessages; outstr := ReadPipe(PipeStdOut);
if outstr <> '' then
begin
LogStyle(ltNormal);
meOutput.SelText := outstr;
meOutput.Perform(EM_SCROLLCARET, 0, 0);
end; outstr := ReadPipe(PipeStdErr);
if outstr <> '' then
begin
LogStyle(ltError);
meOutput.SelText := outstr;
meOutput.Perform(EM_SCROLLCARET, 0, 0); if (error_msg = '') and (Pos('Msg 1105, Level 17',
outstr) > 0) then
begin
(* Error Message text:
Can't allocate space for object '%.*s' in database
'%.*s' because the
'%.*s' segment is full. If you ran out of space in
Syslogs, dump the
transaction log. Otherwise, use ALTER DATABASE or
sp_extendsegment to increase
the size of the segment.
*)
error_msg := 'Nema mjesta na segmentu baze
podataka, treba pokusati isprazniti transaction log ili pove鎍ti
bazu.';
end;
end; until dwExitCode <> STILL_ACTIVE; if not GetExitCodeProcess(ProcessInformation.hProcess,
dwExitCode) then
XWinError('Ne mogu o鑙tati exit code!'); if dwExitCode <> 0 then
raise Exception.Create('Exit code ' +
IntToStr(dwExitCode)); finally
Screen.Cursor := crDefault;
bbTerminate.Enabled := false;
if dwExitCode = STILL_ACTIVE then
TerminateProcess(ProcessInformation.hProcess, 1);
CloseHandle(ProcessInformation.hProcess);
CloseHandle(ProcessInformation.hThread);
ProcessInformation.hProcess := 0;
end;
end
else
XWinError('Ne mogu lansirati ' + FMSSQLBinnDir + 'isql.exe!' +
#10 + 'Cmd: ' + Cmd); finally
ClosePipe(PipeStdOut);
ClosePipe(PipeStdErr);
end;if error_msg <> '' then
raise Exception.Create(error_msg);
end;
比如winzip就是这样干
在电脑编程技巧与维护上有过
是99年还是2000的杂志上?VC的代码!
http://www.codeguru.com/console/QuickWin.shtml
一个很祥细的例程。快去down来看
大多是用API的
//---------------------------------------------------------------------------
//这个函数判断系统是否是WindowsNT
//参数
// 无
//返回值:
// 如果是NT返回true,否则返回falsebool IsWindowsNT()
{
OSVERSIONINFO osv;
osv.dwOSVersionInfoSize = sizeof(osv);
GetVersionEx(&osv);
return (osv.dwPlatformId == VER_PLATFORM_WIN32_NT);
}//---------------------------------------------------------------------------
//这个函数运行控制台下的程序
//参数:
// runString_s 是运行的命令
// result_p 是运行得到的结果
// showWindow_b 运行时是否显示窗口
//返回值:
// 无
//日期:
// 2001-3-25void Run(const AnsiString& runString_s, TStrings* const result_p, bool showWindow_b = false)
{
if(runString_s == "") return;
int break_b; Screen->Cursor = crHourGlass;
Application->ProcessMessages(); //如果是WindowsNT就安全填充
SECURITY_DESCRIPTOR sd;
SECURITY_ATTRIBUTES sa;
LPSECURITY_ATTRIBUTES lpsa = NULL;
if (IsWindowsNT())
{
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, true, NULL, false);
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = true;
sa.lpSecurityDescriptor = &sd;
lpsa = &sa;
} //建立管道并建立读/写句柄
HANDLE hReadPipe;
HANDLE hWritePipe;
assert(CreatePipe(&hReadPipe, &hWritePipe, lpsa, 2500000));
//初始化 STARTUPINFO 结构
STARTUPINFO si;
memset(&si, 0, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW |STARTF_USESTDHANDLES;
si.wShowWindow = showWindow_b ? SW_NORMAL : SW_HIDE;
si.hStdOutput = hWritePipe;
si.hStdError = hWritePipe;
PROCESS_INFORMATION pi;
assert(hWritePipe); Application->ProcessMessages(); DWORD bytesWrite_dw;
char write[8] = {'#', 'S', 't', 'a', 'r', 't', '!', '\n'};
WriteFile(hWritePipe, &write, sizeof(write), &bytesWrite_dw, NULL);
if(CreateProcess(NULL,
runString_s.c_str(),
NULL, //安全的
NULL, // 安全的
TRUE, //继承的句柄
0,
0,
0,
&si,
&pi))
{
CloseHandle(pi.hThread);
WaitForSingleObject(pi.hProcess, 90000); //从管道读取并将结果存入result_p
assert(hReadPipe);
DWORD bytesRead_dw;
char dest[N+1];
dest[N] = '\0';
bool rdLoopDone_b = false;
break_b = 1;
AnsiString temp_s;
if(ExitCode) Screen->Cursor = crDefault;
while (!rdLoopDone_b)
{
memset(dest, 0, N); assert(ReadFile(hReadPipe, &dest, sizeof(dest)-1, &bytesRead_dw, NULL));
temp_s += String(dest);
if (bytesRead_dw < N) rdLoopDone_b = true;
if (break_b > 150) rdLoopDone_b = true;
break_b++;
}
result_p->Text = temp_s;
}
Screen->Cursor = crDefault;
}