C#:调用一个php脚本并能够阻止它
本文关键字:脚本 php 一个 调用 | 更新日期: 2023-09-27 18:32:13
我目前正在开发一个C#程序,该程序需要调用本地PHP脚本并将其输出写入文件。问题是,我需要能够停止脚本的执行。
首先,我尝试调用cmd.exe并让cmd将输出写入工作正常的文件。但我发现,杀死cmd进程并不能阻止php cli。
所以我尝试直接调用 php,重定向其输出并将其从 C# 代码写入文件。但这里的问题似乎是,当脚本完成时,php cli 不会终止。 process.WaitForExit()
不会返回,即使我确定脚本已完全执行。
我无法将超时设置为 WaitForExit()
,因为根据参数的不同,脚本可能需要 3 分钟或例如 10 小时。
我不想只杀死一个随机的 php cli,当前可能还有其他正在运行。
从 C# 调用本地 php 脚本,将其输出写入文件并能够停止执行的最佳方法是什么?
这是我当前的代码:
// Create the process
var process = new System.Diagnostics.Process();
process.EnableRaisingEvents = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.FileName = "php.exe";
// CreateExportScriptArgument returns something like "file.php arg1 arg2 ..."
process.StartInfo.Arguments = CreateExportScriptArgument(code, this.content, this.options);
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
process.StartInfo.RedirectStandardOutput = true;
// Start the process or cancel, if the process should not run
if (!this.isRunning) { return; }
this.currentProcess = process;
process.Start();
// Get the output
var output = process.StandardOutput;
// Wait for the process to finish
process.WaitForExit();
this.currentProcess = null;
要终止我正在使用的进程:
// Mark as not running to prevent starting new
this.isRunning = false;
// Kill the process
if (this.currentProcess != null)
{
this.currentProcess.Kill();
}
感谢您的阅读!
编辑
cli 不返回似乎是不可重现的。当我测试不同的脚本(没有参数)时,它可以工作,可能是脚本或参数的传递。
从cmd运行我的脚本工作得很好,所以脚本应该不是问题
编辑 2
禁用 RedirectStandardOutput
时,cli 退出。 可能是,我需要在该过程完成之前读取输出吗?还是在某种缓冲区已满时等待该过程?
编辑3:问题已解决
感谢VolkerK,我/我们找到了解决方案。问题是,当输出未被读取时,WaitForExit()
不会被调用(可能是由于标准输出中的缓冲区已满)。我的脚本写了很多输出。
什么对我有用:
process.Start();
// Get the output
var output = process.StandardOutput;
// Read the input and write to file, live to avoid reading / writing to much at once
using (var file = new StreamWriter("path''file", false, new UTF8Encoding()))
{
// Read each line
while (!process.HasExited)
{
file.WriteLine(output.ReadLine());
}
// Read the rest
file.Write(output.ReadToEnd());
// flush to file
file.Flush();
}
由于问题是输出缓冲区已满,因此 php 进程在等待发送其输出时停止,因此异步读取 C# 程序中的输出是解决方案。
class Program {
protected static /* yeah, yeah, it's only an example */ StringBuilder output;
static void Main(string[] args)
{
// Create the process
var process = new System.Diagnostics.Process();
process.EnableRaisingEvents = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.FileName = "php.exe";
process.StartInfo.Arguments = "-f path''test.php mu b 0 0 pgsql://user:pass@x.x.x.x:5432/nominatim";
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
process.StartInfo.RedirectStandardOutput = true;
output = new StringBuilder();
process.OutputDataReceived += process_OutputDataReceived;
// Start the process
process.Start();
process.BeginOutputReadLine();
// Wait for the process to finish
process.WaitForExit();
Console.WriteLine("test");
// <-- do something with Program.output here -->
Console.ReadKey();
}
static void process_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
if (!String.IsNullOrEmpty(e.Data)) {
// edit: oops the new-line/carriage-return characters are not "in" e.Data.....
// this _might_ be a problem depending on the actual output.
output.Append(e.Data);
output.Append(Environment.NewLine);
}
}
}
另请参阅:https://msdn.microsoft.com/en-us/library/system.diagnostics.process.beginoutputreadline%28v=vs.110%29.aspx