我有第三方控制台应用程序
我想在运行时从delphi应用程序执行它。
执行
必须隐藏控制台应用程序窗口。控制台应用程序的所有消息必须打印在我的应用程序的控件中(文本框,备忘录等)
并且还使用控件用户必须能够输入文本。
任何人都可以帮我这样做
答案 0 :(得分:3)
这将允许您从控制台(DOS类型)应用程序运行和接收信息到TRichEdit。一旦应用程序运行,它不允许您输入文本,但它可能会给您一个起点。 (原始代码来自TeamB的Peter Below博士撰写的新闻组帖子。)
procedure TFMainForm.RunDosInMemo(const App: String; AMemo: TRichEdit);
const
ReadBuffer = 2400;
var
Security : TSecurityAttributes;
StdInPipeR, StdInPipeW : THandle;
StdOutPipeR, StdOutPipeW : THandle;
StartInfo : TStartUpInfo;
ProcessInfo : TProcessInformation;
Buffer : PByte;
BytesAvailable, BytesRead : DWord;
sDosApp: String;
sData: RawByteString;
begin
sDosApp := DosApp;
UniqueString(sDosApp);
with Security do begin
nLength := SizeOf(TSecurityAttributes);
bInheritHandle := True;
lpSecurityDescriptor := nil;
end;
if CreatePipe(StdInPipeR, StdInPipeW, @Security, 0) then
try
SetHandleInformation(StdInPipeW, HANDLE_FLAG_INHERIT, 0);
if CreatePipe(StdOutPipeR, StdOutPipeW, @Security, 0) then
try
SetHandleInformation(StdOutPipeR, HANDLE_FLAG_INHERIT, 0);
GetMem(Buffer, ReadBuffer);
try
ZeroMemory(@StartInfo, SizeOf(StartInfo));
StartInfo.cb := SizeOf(StartInfo);
StartInfo.hStdOutput := StdOutPipeW;
StartInfo.hStdInput := StdInPipeR;
StartInfo.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
StartInfo.wShowWindow := SW_HIDE;
if CreateProcess(nil,
PChar(sDosApp),
nil,
nil,
True,
NORMAL_PRIORITY_CLASS,
nil,
nil,
StartInfo,
ProcessInfo) then
try
while WaitForSingleObject(ProcessInfo.hProcess, 500) <> WAIT_TIMEOUT do
Application.ProcessMessages;
while PeekNamedPipe(StdOutPipeR, nil, 0, nil, BytesAvailable, nil) do
begin
if BytesAvailable < 1 then
Break;
if BytesAvailable > ReadBuffer then
BytesAvailable := ReadBuffer;
if not ReadFile(StdOutPipeR,
Buffer[0],
BytesAvailable,
BytesRead,
nil) then
Break;
SetString(sData, PAnsiChar(Buffer), BytesRead);
// assign an appropriate codepage for the output data:
// 0 for default Ansi, 1252 or 20157 for ASCII, 1200 for
// Unicode, etc...
SetCodePage(sData, ...);
// this is faster and more efficient than reading/writing the
// Text property directly...
AMemo.SelStart := AMemo.GetTextLen;
AMemo.SelLength := 0;
AMemo.SelText := sData;
end;
finally
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
end;
finally
FreeMem(Buffer);
end;
finally
CloseHandle(StdOutPipeR);
CloseHandle(StdOutPipeW);
end;
finally
CloseHandle(StdInPipeR);
CloseHandle(StdInPipeW);
end;
end;
答案 1 :(得分:0)
Zarko在Delphi.about.com上写到了这一点。
这是一个常见的要求,例如,在IDE和构建工具中,或者产生外部命令行工具来进行版本控制的应用程序,例如。
如你要求的那样双向回答是非常复杂的,我不知道有任何人在delphi中完全实现了“命令shell”或“终端模式”。
我将Zlatko的代码移植到Delphi XE(也适用于2010年)here。