Я пытаюсь получить скрипт 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();
}
Мне пришлось изменить процесс для запуска следующим образом:
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?