提问人:rejkid 提问时间:11/10/2023 最后编辑:rejkid 更新时间:11/10/2023 访问量:34
从 Web 应用控制器中运行外部控制台应用(写入输出文件)
Running an external console app (that writes to the output file) from within web app controller
问:
我在服务器端运行 Web 应用程序控制器应用程序 (c#)。当特定的 http 请求传入时,控制器将运行外部控制台应用程序,该应用程序读取数据输入文件并写入包含结果的输出文件。问题是,此外部控制台应用程序始终输出一个空文件。 如果我通过自己执行外部控制台应用程序(将输入和输出文件作为参数传递)手动执行此过程,它会按预期创建非空输出结果文件。 这是一个安全问题吗,是否有任何解决方法?
我启动控制台应用的调用如下所示:
string a2tExePath = Path.Combine(Directory.GetCurrentDirectory(), A2T_EXE);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append(" ").Append(Path.Combine(uploadFolder, A2T_INPUT)).Append(" ").Append(Path.Combine(uploadFolder, A2T_OUTPUT));
using (System.Diagnostics.Process pProcess = new System.Diagnostics.Process())
{
pProcess.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory();
pProcess.StartInfo.FileName = a2tExePath;// a2tExePath;
pProcess.StartInfo.Arguments = stringBuilder.ToString(); //argument
pProcess.StartInfo.ErrorDialog = true;
pProcess.StartInfo.UseShellExecute = true;
pProcess.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
pProcess.StartInfo.CreateNoWindow = true; //not diplay a windows
pProcess.Start();
//string output = pProcess.StandardOutput.ReadToEnd(); //The output result
log.Info("Executing " + a2tExePath + " " + pProcess.StartInfo.Arguments);
pProcess.WaitForExit();
}
}
答:
0赞
C. McCoy IV
11/10/2023
#1
我假设你在 Windows 上。这将在 no-show 命令提示符下运行任何一个衬里:
public class Cmd
{
public CommandLineResult Run(string singleLine)
{
var startInfo = new ProcessStartInfo("cmd.exe")
{
Arguments = $"/c \"{singleLine}\"",
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
};
var process = Process.Start(startInfo);
var stdErr = string.Empty;
process!.ErrorDataReceived += new DataReceivedEventHandler((sender, e) => { stdErr += e.Data });
process.BeginErrorReadLine();
var stdOut = process?.StandardOutput.ReadToEnd();
process?.WaitForExit();
return new CommandLineResult
{
ExitCode = process?.ExitCode ?? -1,
StandardOut = stdOut!,
StandardErr = stdErr!,
};
}
}
public class CommandLineResult
{
public int ExitCode { get; init; }
public string StandardOut { get; init; } = null!;
public string StandardErr { get; init; } = null!;
public bool IsSuccess => ExitCode == 0;
public string StandardAll = string.Join(Environment.NewLine, new[] { StandardOut, StandardErr });
}
您可以像这样使用它:
var inputPath = Path.Combine(uploadFolder, A2T_INPUT);
var outputPath = Path.Combine(uploadFolder, A2T_OUTPUT);
var singleLine = $"{a2tExePath} {inputPath} {outputPath}";
var result = new Cmd().Run(singleLine);
或者,如果您有 a2t 的 dll,您可以尝试将 extern 绑定到其 Main 函数并直接调用它(如果可能的话,我认为这更干净,因为您避免启动新进程,因为它只是一个花哨的函数调用)。参考: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/extern
评论
0赞
rejkid
11/10/2023
此 c# 代码与我的代码类似,不会创建输出文件 - 它始终为空。顺便说一句,你的类没有编译 - 它有一些错误,StandardOut 和 StandardErr 不是静态的。
0赞
rejkid
11/11/2023
你能帮我解决你发给我的代码的问题吗?C# 抱怨变量无法初始化,因为不是静态字段。StandardAll
StandardOut StandardErr
评论