外部工具无法在我的应用程序中输出,但在 CMD 屏幕中输出很好
External tool fails to output in my app but outputs nicely in CMD screen
我正在尝试在我的 C#/WPF 应用程序中使用随 Firebird 数据库一起提供的 GFIX 工具在数据库上执行某些命令。
火鸟http://www.firebirdsql.org/en/firebird-2-5-3-upd1/
Gfix http://www.firebirdsql.org/manual/gfix.html
为此,我使用以下代码:
public string RunExternalExe(string filename, string arguments = null)
{
var process = new Process();
process.StartInfo.FileName = filename;
if (!string.IsNullOrEmpty(arguments))
{
process.StartInfo.Arguments = arguments;
}
process.StartInfo.CreateNoWindow = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
var stdOutput = new StringBuilder();
process.OutputDataReceived += (sender, args) => stdOutput.Append(args.Data);
string stdError = null;
try
{
process.Start();
process.BeginOutputReadLine();
stdError = process.StandardError.ReadToEnd();
process.WaitForExit();
}
catch (Exception e)
{
throw new Exception("OS error while executing " + Format(filename, arguments) + ": " + e.Message, e);
}
if (process.ExitCode == 0)
{
return stdOutput.ToString();
}
else
{
var message = new StringBuilder();
if (!string.IsNullOrEmpty(stdError))
{
message.AppendLine(stdError);
}
if (stdOutput.Length != 0)
{
message.AppendLine("Std output:");
message.AppendLine(stdOutput.ToString());
}
throw new Exception(Format(filename, arguments) + " finished with exit code = " + process.ExitCode + ": " + message);
}
}
private string Format(string filename, string arguments)
{
return "'" + filename +
((string.IsNullOrEmpty(arguments)) ? string.Empty : " " + arguments) +
"'";
}
在那里找到
How To: Execute command line in C#, get STD OUT results
我也尝试了在那个问题中得到解释的所有其他方法,但它仍然没有给我任何输出。
我尝试执行以下命令
gfix.exe -user foo -pa foo -shut single -force 0 app1:\bar.fdb
我在cmd中执行看到的是如下输出
"Your user name and password are not defined. Ask your database administrator to set up a Firebird login."
这是一个明显的错误,因为用户 foo 和密码 foo 不存在。
所以我的问题不是错误本身,而是 我没有在我的 C# 应用程序中得到这个输出 不管我到目前为止尝试了什么。
因为我在我的 CMD 屏幕上看到错误输出,它应该在我的 C# 应用程序中得到输出,或者是否有可能是该工具本身阻止了输出而我没有机会得到它?
到目前为止我尝试了什么:
- 用参数调用 gfix.exe 本身。
- 调用包含对 gfix.exe 及其参数的调用的 bat。
- 使用 /c 或 /k 调用带有参数的 gfix.exe 的 CMD。
- 使用 /c 或 /k 调用 CMD,调用一个 bat,该 bat 调用 gfix.exe。
我相信我已经尝试了调用此工具的所有可能组合,但仍然没有得到输出。
我也尝试了 RedirectStandardError 和 RedirectStandardOutput,使用 async/sync 方法(开始..和 ReadToEnd), 我还尝试在 RedirectStandardInput 的帮助下输入参数,并按照我用 CMD 键入的方式准确地写下这些行,首先是 cd "C:\Test"
而不是对 gfix.exe 的调用都是徒劳的...
进一步的信息,如果我正确输入所有内容,该工具工作正常 运行s 并且完全按照它应该做的去做,但我也想在工具失败时捕捉并想要输出相应的错误.
编辑:
请注意,我现在尝试了以下操作,没有涉及我的 C# 应用程序,仅双击 bat 或在 CMD 中执行它。
我已将我的测试 bat 文件修改为:
gfix.exe -user foo -pa foo -shut single -force 0 app1:/bar.fdb > Test.txt 2> error.txt
这会创建 2 个文本文件 - 都是空的。
如果我 运行 在 CMD no 中显示此 .bat 错误,如果我删除 2> error.txt
错误消息 再次显示 在 CMD 屏幕中。所以重定向似乎 "work" 只有我的 txt 文件是空的... gfix 工具可以阻止这个吗?!?
当发生错误时,gfix 不会将其输出到标准输出,而是输出到标准错误。这是明显的标准行为。
这对我有用:
using (var process = Process.Start(
new ProcessStartInfo
{
FileName = fileName,
Arguments = args,
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = true,
RedirectStandardError = true,
UseShellExecute = false,
}))
{
process.WaitForExit();
if (process.ExitCode != 0)
{
var errorMessage = process.StandardError.ReadToEnd();
Assert.Fail(errorMessage);
}
}
注意 RedirectStandardError = true
。
我正在尝试在我的 C#/WPF 应用程序中使用随 Firebird 数据库一起提供的 GFIX 工具在数据库上执行某些命令。
火鸟http://www.firebirdsql.org/en/firebird-2-5-3-upd1/
Gfix http://www.firebirdsql.org/manual/gfix.html
为此,我使用以下代码:
public string RunExternalExe(string filename, string arguments = null)
{
var process = new Process();
process.StartInfo.FileName = filename;
if (!string.IsNullOrEmpty(arguments))
{
process.StartInfo.Arguments = arguments;
}
process.StartInfo.CreateNoWindow = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
var stdOutput = new StringBuilder();
process.OutputDataReceived += (sender, args) => stdOutput.Append(args.Data);
string stdError = null;
try
{
process.Start();
process.BeginOutputReadLine();
stdError = process.StandardError.ReadToEnd();
process.WaitForExit();
}
catch (Exception e)
{
throw new Exception("OS error while executing " + Format(filename, arguments) + ": " + e.Message, e);
}
if (process.ExitCode == 0)
{
return stdOutput.ToString();
}
else
{
var message = new StringBuilder();
if (!string.IsNullOrEmpty(stdError))
{
message.AppendLine(stdError);
}
if (stdOutput.Length != 0)
{
message.AppendLine("Std output:");
message.AppendLine(stdOutput.ToString());
}
throw new Exception(Format(filename, arguments) + " finished with exit code = " + process.ExitCode + ": " + message);
}
}
private string Format(string filename, string arguments)
{
return "'" + filename +
((string.IsNullOrEmpty(arguments)) ? string.Empty : " " + arguments) +
"'";
}
在那里找到 How To: Execute command line in C#, get STD OUT results
我也尝试了在那个问题中得到解释的所有其他方法,但它仍然没有给我任何输出。
我尝试执行以下命令
gfix.exe -user foo -pa foo -shut single -force 0 app1:\bar.fdb
我在cmd中执行看到的是如下输出
"Your user name and password are not defined. Ask your database administrator to set up a Firebird login."
这是一个明显的错误,因为用户 foo 和密码 foo 不存在。
所以我的问题不是错误本身,而是 我没有在我的 C# 应用程序中得到这个输出 不管我到目前为止尝试了什么。
因为我在我的 CMD 屏幕上看到错误输出,它应该在我的 C# 应用程序中得到输出,或者是否有可能是该工具本身阻止了输出而我没有机会得到它?
到目前为止我尝试了什么:
- 用参数调用 gfix.exe 本身。
- 调用包含对 gfix.exe 及其参数的调用的 bat。
- 使用 /c 或 /k 调用带有参数的 gfix.exe 的 CMD。
- 使用 /c 或 /k 调用 CMD,调用一个 bat,该 bat 调用 gfix.exe。
我相信我已经尝试了调用此工具的所有可能组合,但仍然没有得到输出。
我也尝试了 RedirectStandardError 和 RedirectStandardOutput,使用 async/sync 方法(开始..和 ReadToEnd), 我还尝试在 RedirectStandardInput 的帮助下输入参数,并按照我用 CMD 键入的方式准确地写下这些行,首先是 cd "C:\Test"
而不是对 gfix.exe 的调用都是徒劳的...
进一步的信息,如果我正确输入所有内容,该工具工作正常 运行s 并且完全按照它应该做的去做,但我也想在工具失败时捕捉并想要输出相应的错误.
编辑:
请注意,我现在尝试了以下操作,没有涉及我的 C# 应用程序,仅双击 bat 或在 CMD 中执行它。
我已将我的测试 bat 文件修改为:
gfix.exe -user foo -pa foo -shut single -force 0 app1:/bar.fdb > Test.txt 2> error.txt
这会创建 2 个文本文件 - 都是空的。
如果我 运行 在 CMD no 中显示此 .bat 错误,如果我删除 2> error.txt
错误消息 再次显示 在 CMD 屏幕中。所以重定向似乎 "work" 只有我的 txt 文件是空的... gfix 工具可以阻止这个吗?!?
当发生错误时,gfix 不会将其输出到标准输出,而是输出到标准错误。这是明显的标准行为。
这对我有用:
using (var process = Process.Start(
new ProcessStartInfo
{
FileName = fileName,
Arguments = args,
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = true,
RedirectStandardError = true,
UseShellExecute = false,
}))
{
process.WaitForExit();
if (process.ExitCode != 0)
{
var errorMessage = process.StandardError.ReadToEnd();
Assert.Fail(errorMessage);
}
}
注意 RedirectStandardError = true
。