Невозможно получить перенаправление Perl, работающее в C # с фоновым рабочим

1

Я пытаюсь получить скрипт Perl, чтобы не допустить его вывод в поле "Список" на С# без везения.

Я смотрел этот сайт и другие и пытался несколько комбинаций, но до сих пор не испытываю никакой радости от него, возможно, что-то делать с попыткой сделать это через фонового работника?

Мой код ниже, помощь будет оценена.

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();
}
  • 0
    Что не так?
  • 0
    @reinierpost ничего не выводит, используя скрипт Perl, если я изменю имя файла на исполняемый файл, я получу вывод.
Показать ещё 1 комментарий
Теги:
redirect

1 ответ

1
Лучший ответ

Мне пришлось изменить процесс для запуска следующим образом:

    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();

После этого он работает для меня! Однако каждая строка (стандартного) вывода будет отображаться как один элемент в вашем спискеBox. Возможно, вам нужно разбить выход, чтобы каждая строка вывода была отдельным элементом listBox?

  • 0
    Привет, jimtut, я все еще не могу заставить его работать с твоим примером (у меня должно быть что-то еще не так ... Я выпишу сценарий Perl и zip-проект сегодня вечером, когда вернусь домой. испортил ... Мне также нужно, чтобы обработать папку, выбранную с _dirPath = folderBrowserDialog1.SelectedPath
  • 0
    Пробовал что-то другое, и теперь он отображается в моем списке, кнопка отмены не работает, но я должен быть в состоянии разобраться с этим. Я добавил код, который использовал в исходном посте.
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню