无法使用后台工作程序在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();
}

无法使用后台工作程序在C#中实现Perl重定向

我不得不更改流程以启动如下:

    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项?