我有一个在delphi中编码的命令行应用程序,我需要从普通的桌面应用程序(也用delphi编写)调用.简而言之,我想调用命令行应用程序并在列表框中显示它"实时"输出的文本.
自从我使用shell以来已经很久了,但我清楚地记得,为了从命令行应用程序中获取文本 - 我必须使用管道符号">".像这样:
C:/mycmdapp.exe> c:/result.txt
这将打印到shell的任何文本(使用writeLn)并将其转储到名为"result.txt"的文本文件中.
但是......(这里有泡菜),我想要一个实时结果而不是一个积压文件.一个典型的例子是Delphi编译器本身 - 它设法向IDE报告发生了什么.如果我的记忆正确地为我服务,我似乎记得我必须创建一个"管道"通道(?),然后将管道名称分配给shell调用.
我试图谷歌这个但我老实说不确定如何制定它.希望社区中的某些人能指出我正确的方向.
更新:此问题可能与如何在Delphi中运行命令行程序相同?.虽然标题和问题本身并不相同,但有些答案符合我的要求.
我从C#启动一个进程如下:
public bool Execute()
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.Arguments = "the command";
startInfo.FileName = "C:\\MyApp.exe";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
Log.LogMessage("{0} {1}", startInfo.FileName, startInfo.Arguments);
using (Process myProcess = Process.Start(startInfo))
{
StringBuilder output = new StringBuilder();
myProcess.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e)
{
Log.LogMessage(Thread.CurrentThread.ManagedThreadId.ToString() + e.Data);
};
myProcess.ErrorDataReceived += delegate(object sender, DataReceivedEventArgs e)
{
Log.LogError(Thread.CurrentThread.ManagedThreadId.ToString() + " " + e.Data);
};
myProcess.BeginErrorReadLine();
myProcess.BeginOutputReadLine();
myProcess.WaitForExit();
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
但这有一个问题......如果有问题的应用程序按顺序写入std out和std err:
std out: msg 1 …Run Code Online (Sandbox Code Playgroud) 我希望Firebird备份工具gbak将其输出写入Delphi流(没有中间文件).有一个命令行参数可以写入stdout而不是文件.然后我使用ExecuteJEDI中的方法JclSysUtils启动gbak并处理该输出.
它看起来像这样:
procedure DoBackup;
var
LBackupAbortFlag: Boolean;
LBackupStream: TStringStream;
begin
LBackupAbortFlag := False;
LBackupStream := TStringStream.Create;
try
Execute('"C:\path to\gbak.exe" -b -t -v -user SYSDBA -pas "pw" <db> stdout',
LBackupStream.WriteString, // Should process stdout (backup)
SomeMemo.Lines.Append, // Should process stderr (log)
True, // Backup is "raw"
False, // Log is not
@LBackupAbortFlag);
LBackupStream.SaveToFile('C:\path to\output.fbk');
finally
LBackupStream.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
问题是输出文件太小而无法包含实际备份.我仍然看到文件内容的元素.我尝试了不同的流类型,但这似乎没有什么区别.这可能会出错?
需要明确的是:其他解决方案也是受欢迎的.最重要的是,我需要一些可靠的东西.这就是为什么我首先选择JEDI,而不是重新发明这样的事情.那么,如果它不会太复杂,那就太好了.
我有一个用 Delphi XE2 编写的 VCL 应用程序,它需要执行一个命令行程序(也是用 Delphi XE2 编写的)并通过它获取文本输出。我目前正在使用以下代码,该代码基于此处找到的代码:从 shell/dos 应用程序获取输出到 Delphi 应用程序
function GetDosOutput(ACommandLine : string; AWorkingDirectory : string): string;
var
SecurityAttributes : TSecurityAttributes;
StartupInfo : TStartupInfo;
ProcessInformation: TProcessInformation;
StdOutPipeRead, StdOutPipeWrite: THandle;
WasOK: Boolean;
Buffer: array[0..255] of AnsiChar;
BytesRead: Cardinal;
Handle: Boolean;
begin
Result := '';
SecurityAttributes.nLength := SizeOf(TSecurityAttributes);
SecurityAttributes.bInheritHandle := True;
SecurityAttributes.lpSecurityDescriptor := nil;
CreatePipe(StdOutPipeRead, StdOutPipeWrite, @SecurityAttributes, 0);
try
FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
StartupInfo.cb := SizeOf(TStartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
StartupInfo.wShowWindow := SW_HIDE;
StartupInfo.hStdInput := StdOutPipeRead;
StartupInfo.hStdOutput …Run Code Online (Sandbox Code Playgroud) 我用delphi来获取dos输出.
导致http://delphi.about.com/cs/adptips2001/a/bltip0201_2.htm的代码无法在vista上使用delphi2009?但它适用于XP中的D7.我不知道要修改哪个部分才能使其工作.
delphi ×4
c# ×1
command-line ×1
delphi-2010 ×1
firebird ×1
firebird2.5 ×1
jedi ×1
pipe ×1
shellexecute ×1
stderr ×1
stdout ×1
windows-xp ×1