无法使用后台工作程序在C#中实现Perl重定向
本文关键字:实现 Perl 重定向 工作程序 后台 | 更新日期: 2023-09-27 18:27:12
我一直在尝试让一个Perl脚本将其输出放弃给C#中的List框,但没有任何运气。
我一直在这个网站和其他网站上寻找,尝试了多种组合,但仍然没有任何乐趣,也许是因为试图通过后台工作人员来做这件事?
我下面的代码,如有帮助,不胜感激。
public partial class Form1 : Form
{
/// <summary>
/// The backgroundworker object on which the time consuming operation shall be executed
/// </summary>
BackgroundWorker backgroundWorker1;
private String _dirPath = null;
public Form1()
{
InitializeComponent();
}
// On completed do the appropriate task
void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
btnOpenFolder.Enabled = true;
btnCancel.Enabled = false;
}
void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//Here you play with the main UI thread, update a progress bar or status label
}
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Process p = new Process();
p.StartInfo = new ProcessStartInfo(@"c:'Perl'bin'perl.exe");
p.StartInfo.WorkingDirectory = @"C:'Temp'";
p.StartInfo.FileName = @"C:'Temp'dirdupes.pl";
p.StartInfo.Arguments = _dirPath;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.UseShellExecute = false;
p.Start();
p.BeginErrorReadLine();
//For testing
//p.StartInfo.FileName = "cmd.exe";
//p.StartInfo.Arguments = "dir/s";
//For testing
//StreamReader sr = p.StandardError;
//string line;
//line = sr.ReadToEnd();
//listBox1.Text = line;
using (StreamReader std_out = p.StandardOutput, std_err = p.StandardError)
{
do
{
listBox1.Items.Add(std_out.ReadToEnd());
listBox1.Items.Add(std_err.ReadToEnd());
} while (!std_out.EndOfStream) ;
}
p.WaitForExit();
if (backgroundWorker1.CancellationPending)
{
e.Cancel = true;
//backgroundWorker1.ReportProgress(0);
return;
}
//Report 100% completion on operation completed
//backgroundWorker1.ReportProgress(100);
}
private void btnOpenFolder_Click(object sender, EventArgs e)
{
//Open folder browser for user to select the folder to scan
DialogResult result = folderBrowserDialog1.ShowDialog();
if (result == DialogResult.OK)
{
//Store selected folder path
_dirPath = folderBrowserDialog1.SelectedPath;
}
else
{
return;
}
btnOpenFolder.Enabled = false;
btnCancel.Enabled = true;
//Start the async operation here
backgroundWorker1.RunWorkerAsync();
}
private void btnCancel_Click(object sender, EventArgs e)
{
if (backgroundWorker1.IsBusy)
{
//Stop/Cancel the async operation here
backgroundWorker1.CancelAsync();
}
}
}
我最终使用了这段代码,它成功地将Perl脚本输出显示到我的列表框中
void p_DataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null && e.Data.Length > 0) this.Invoke(new Action(() => listBox1.Items.Add(e.Data)));
this.Invoke(new Action(() => listBox1.TopIndex = listBox1.Items.Count - 1));
}
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Process p = new Process();
var args = new ProcessStartInfo("cmd.exe");
args.WorkingDirectory = @"C:'";
//p.StartInfo.FileName = "perl.exe";
args.Arguments = @"/C perl.exe C:'Temp'dirdupes.pl " + _dirPath;
args.CreateNoWindow = true;
args.RedirectStandardOutput = true;
args.RedirectStandardInput = true;
args.RedirectStandardError = true;
args.UseShellExecute = false;
p = Process.Start(args);
p.OutputDataReceived += p_DataReceived;
p.ErrorDataReceived += p_DataReceived;
p.BeginErrorReadLine();
p.BeginOutputReadLine();
}
我不得不更改流程以启动如下:
p.StartInfo = new ProcessStartInfo();
p.StartInfo.WorkingDirectory = @"C:'Temp'";
p.StartInfo.FileName = @"C:'Perl'bin'perl.exe";
p.StartInfo.Arguments = @"C:'Temp'dirdupes.pl";
以克服启动流程时遇到的问题。也许那不是你挂断电话的地方?
不过,在那之后,你需要去掉这条线:
p.BeginErrorReadLine();
之后,它对我有效!然而,(标准)输出的每一行都将显示为listBox中的单个项目。也许您需要分解输出,将每一行输出作为一个单独的listBox项?