2013-09-24 66 views
0

我需要使用「c#windows窗體應用程序」執行多個批處理文件。只是萬一蝙蝠包含一個或多個行如:「開始filename.exe」我的程序等待,直到「filename.exe」將終止,顯然這不是我所需要的我有
附加了一段代碼我使用跳你會發現一個示例Windows窗體應用程序。如何在C#中執行多個.BAT文件#

在此先感謝。

弗朗西斯

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Diagnostics; 
using System.Drawing; 
using System.IO; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace Sample 
{ 
    public partial class Form1 : Form 
    { 

     /* 
     * Batch files 
     * 
      c:\batch1.bat 
        echo startExecution 
        start /b calc.exe 
        echo endExecution 
        exit 
     * 
     * 
      c:\batch2.bat 
        echo startExecution2 
        start /b notepad.exe 
        echo endExecution2 
        exit 

     */ 

     public Form1() 
     { 
      //Just for sample is unsafe 
      Control.CheckForIllegalCrossThreadCalls = false; 
      InitializeComponent(); 
      this.button1.Click += button1_Click; 
     } 


     private void button1_Click(object sender, EventArgs e) 
     { 
      this.richTextBox1.Text = "Initialized\r\n"; 
      BatchExecution be = new BatchExecution("c:\\batch1.bat"); 
      be.endOccurs += be_endOccurs; 
      be.DoWork(); 
      be = new BatchExecution("c:\\batch2.bat"); 
      be.endOccurs += be_endOccurs; 
      be.DoWork(); 
     } 

     private void be_endOccurs(BatchExecution sender) 
     { 
      this.richTextBox1.AppendText(sender.output); 
      sender = null; 
     } 
    } 

    public class BatchExecution 
    { 

     private String batch { get; set; } 
     public Process process { get; private set; } 

     public delegate void workHasEndedHandler(BatchExecution sender); 
     public event workHasEndedHandler endOccurs; 

     private Boolean _hasEnded = false; 
     public Boolean hasEnded 
     { 
      get 
      { 
       return _hasEnded; 
      } 
      set 
      { 
       _hasEnded = value; 
       if (_hasEnded) 
       { 
        endOccurs(this); 
       } 
      } 
     } 

     public String output { get; set; } 

     public BatchExecution(String batFile) 
     { 
      batch = batFile; 
     } 

     private void workCompleted() 
     { 
      if (process != null) 
      { 
       process.Close(); 
       process.Dispose(); 
       GC.SuppressFinalize(process); 
       process = null; 
      } 

      output += "Batch ended\r\n"; 
      hasEnded = true; 
     } 

     public void DoWork() 
     { 
      output = "Batch output:\r\n"; 
      process = new Process(); 
      process.StartInfo.CreateNoWindow = true; 
      process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
      process.StartInfo.FileName = "cmd.exe"; 
      process.StartInfo.Arguments = " /c \"" + batch + "\""; 
      process.StartInfo.UseShellExecute = false; 
      process.StartInfo.RedirectStandardOutput = true; 
      process.StartInfo.RedirectStandardError = true; 
      process.ErrorDataReceived += process_ErrorDataReceived; 
      process.OutputDataReceived += process_OutputDataReceived; 
      process.Start(); 
      process.BeginOutputReadLine(); 
      process.WaitForExit(); 
      workCompleted(); 
     } 

     private void process_ErrorDataReceived(object sender, DataReceivedEventArgs e) 
     { 
      output += "" + e.Data + "\r\n"; 
     } 

     private void process_OutputDataReceived(object sender, DataReceivedEventArgs e) 
     { 
      output += "" + e.Data + "\r\n"; 
     } 
    } 

} 

自Kenneth建議開始我刪除 「process.WaitForExit()」。現在使用BackgroundWorker我可以檢查批處理執行是否完成。它似乎解決了,但我不太喜歡它。任何人有更好的主意?

這樣的Form1的代碼的新版本是:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Diagnostics; 
using System.Drawing; 
using System.IO; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace Sample 
{ 
    public partial class Form1 : Form 
    { 

     /* 
     * Batch files 
     * 
      c:\batch1.bat 
        echo startExecution 
        start /b calc.exe 
        ping 1.1.1.1 -n 1 -w 10000 
        echo endExecution 
        exit 

     * 
     * 
      c:\batch2.bat 
        echo startExecution2 
        start /b notepad.exe 
        echo endExecution2 
        exit 

     */ 

     private List<String> batchFiles { get; set; } 
     private Int32 batchIndex { get; set; } 
     private BatchExecution be { get; set; } 

     public Form1() 
     { 
      //Just for sample is unsafe 
      Control.CheckForIllegalCrossThreadCalls = false; 
      InitializeComponent(); 
      this.button1.Click += button1_Click; 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      batchIndex = 0; 
      batchFiles = new List<String>(); 
      batchFiles.Add("c:\\batch1.bat"); 
      batchFiles.Add("c:\\batch2.bat"); 
      this.richTextBox1.Text = "Initialized\r\n"; 

      be = new BatchExecution(batchFiles[batchIndex]); 
      be.endOccurs += be_endOccurs; 
      be.DoWork(); 
     } 

     private void be_endOccurs(BatchExecution sender) 
     { 
      this.richTextBox1.AppendText(sender.output); 
      if (sender.process != null) 
      { 
       sender.process.Close(); 
       sender.process.Dispose(); 
       GC.SuppressFinalize(sender.process); 
       sender.process = null; 
      } 
      sender = null; 
      batchIndex++; 

      if (batchFiles != null && batchFiles.Count > batchIndex) 
      { 
       be = new BatchExecution(batchFiles[batchIndex]); 
       be.endOccurs += be_endOccurs; 
       be.DoWork(); 
      } 

     } 
    } 

    public class BatchExecution 
    { 
     private String batch { get; set; } 
     public Process process { get; set; } 

     private BackgroundWorker asyncVerifier { get; set; } 

     public delegate void workHasEndedHandler(BatchExecution sender); 
     public event workHasEndedHandler endOccurs; 

     private Boolean _hasEnded = false; 
     public Boolean hasEnded 
     { 
      get 
      { 
       return _hasEnded; 
      } 
      private set 
      { 
       _hasEnded = value; 
       if (_hasEnded) 
       { 
        if (asyncVerifier != null) 
        { 
         asyncVerifier.Dispose(); 
         GC.SuppressFinalize(asyncVerifier); 
         asyncVerifier = null; 
         output += "Batch ended\r\n"; 
        } 
        endOccurs(this); 
       } 
      } 
     } 

     public String output { get; set; } 

     public BatchExecution(String batFile) 
     { 
      batch = batFile; 
     } 

     public void DoWork() 
     { 
      output = "Batch output:\r\n"; 
      asyncVerifier = new BackgroundWorker(); 
      asyncVerifier.DoWork += asyncVerifier_DoWork; 
      process = new Process(); 
      process.StartInfo.CreateNoWindow = true; 
      process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
      process.StartInfo.FileName = "cmd.exe"; 
      process.StartInfo.Arguments = " /c \"" + batch + "\""; 
      process.StartInfo.UseShellExecute = false; 
      process.StartInfo.RedirectStandardOutput = true; 
      process.StartInfo.RedirectStandardError = true; 
      process.ErrorDataReceived += process_DataReceived; 
      process.OutputDataReceived += process_DataReceived; 
      process.Start(); 
      asyncVerifier.RunWorkerAsync(); 
      process.BeginOutputReadLine(); 
     } 

     private void asyncVerifier_DoWork(object sender, DoWorkEventArgs e) 
     { 
      Boolean performCheck = true; 

      while (performCheck) 
      { 
       if (process != null && !process.HasExited) 
       { 
        System.Threading.Thread.Sleep(500); 
       } 
       else 
       { 
        performCheck = false; 
       } 
      } 
      hasEnded = true; 
     } 

     private void process_DataReceived(object sender, DataReceivedEventArgs e) 
     { 
      output += "" + e.Data + "\r\n"; 
     } 
    } 

} 
+0

你需要使用批處理文件,如果你使用的是C#?通常情況下,比批處理文件更容易維護和調試C#代碼。如果批處理文件非常簡單,那麼您可以運行C#中的命令並輕鬆控制流。如果它們非常複雜...那麼,無論如何,當批處理文件很痛苦地使用(來自喜歡批處理文件的人)時,您可能會從將它移植到C#中受益。 – Gray

+0

是的,我真的需要它。所請求的功能是執行由用戶編輯和維護的多個批處理文件。 –

回答

0

如果刪除調用process.WaitForExit();該計劃將繼續,而不是等到進程退出。

顯然,您撥打WorkCompleted的電話不僅僅意味着所有批次都已啓動。

+0

我們是否需要刪除workCompleted();打電話呢? – doctorlove

+0

是的,因爲從我所看到的你正在殺死的過程中,仍然可能正在運行 – Kenneth

+0

這就是我駕駛的過程。你的回答沒有具體提到這個 – doctorlove

1

嘗試在單獨的線程中執行每個文件。 這樣,他們是彼此獨立的。

例子:

class MyThreadData 
{ 
    // bat info 
}; 

void ThreadFunction(object arg) 
{ 
    MyThreadData batInfo = (MyThreadData)arg; 
    // do work 
} 

void ExecBats(void) 
{ 
    System.Threading.Thread t1 = new System.Threading.Thread(ThreadFunction); 
    MyThreadData bat1 = new MyThreadData(); 
    t1.Start(bat1); 
    // ... 
} 
+0

不幸的是,我不能,所有執行都必須同步。我需要確保第二次執行在第一次結束時開始,第三次在第二次結束時開始...... –

+0

在這種情況下,嘗試使用帶蝙蝠線程的回調函數,以便您的主線程可以根據需要啓動新的蝙蝠線程,在蝙蝠執行時不會被阻擋。 –