none
關於Shell函式的使用 RRS feed

  • 問題

  • 請問一下各位大大

    我在MSDN上看到這一段程式碼

    Dim ProcID As Integer
       ' Run Calculator.
    ProcID = Shell("C:\Windows\system32\calc.exe", AppWinStyle.NormalFocus)


    因為我要執行的是一個BAT檔

    那麼我就依樣畫葫蘆的把程式碼改成

     Dim ProcID As Integer
     ProcID = Shell("""C:\Inetpub\wwwroot\WebApplication6\lexparser.bat""", AppWinStyle.NormalFocus, False)

    結果ProcID是有數字的 表示開啟成功

    那請問我要怎麼抓到bat程式所處理出來的東西呢@@?

    再請問一下Shell跟Process.start看起來都是執行程式

    但是他們又有何不同呢?

    謝謝

    2006年11月16日 上午 12:45

解答

  • 你可以由 Process.StandardOutput,搭配 StreamReader 來取得輸出:

    Process 寫入文字至其標準資料流,該文字一般都是顯示在主控台上。您可以經由重新導向 StandardOutput 資料流,管理或隱藏處理序的輸出。例如,您可以篩選文字、以不同的方式格式化文字,或將輸出寫入至主控台 (Console) 和指定的記錄檔。

    注意事項:

    若要使用 StandardOutput,您必須將 ProcessStartInfo.UseShellExecute 設定為 false,而且必須將 ProcessStartInfo.RedirectStandardOutput 設定為 true。否則,從 StandardOutput 資料流讀取時會擲回例外狀況。

    可以同步或非同步讀取重新導向的 StandardOutput 資料流。諸如 Read、ReadLine 和 ReadToEnd 等方法會在處理序的輸出資料流上執行同步讀取作業。必須等到關聯的 Process 寫入其 StandardOutput 資料流,或關閉該資料流之後,這些同步讀取作業才算完成。

    相反地,BeginOutputReadLine 會在 StandardOutput 資料流上啟動非同步讀取作業。這個方法會啟用資料流輸出的指定事件處理常式,並立即傳回給呼叫端;將資料流輸出導向事件處理常式時,呼叫端可以同時執行其他工作。

    同步讀取作業會在從 StandardOutput 資料流讀取的呼叫端和寫入該資料流的子處理序 (Child Process) 之間,引入相依性。這些相依性可能會產生死結狀況。當呼叫端從子處理序的重新導向資料流讀取時,它便相依於該子系。呼叫端會等候讀取作業,直到子系寫入至資料流或關閉資料流為止。當子處理序寫入足夠資料,填滿其重新導向資料流時,它便相依於父代。子處理序會等候下一個寫入作業,直到父代從完整資料流讀取或關閉資料流為止。當呼叫端和子處理序互相等候對方完成作業且無法繼續時,就會導致鎖死狀態。您可以評估呼叫端和子處理序之間的相依性,藉以避免死結。

    2006年11月16日 上午 02:08
    版主

所有回覆

  • Process.Start 是 .Net 的類別庫,若是需要將 VBNET 轉換成 C# 可以直接轉。

    Shell 是 VB6 相容函數庫,也是包裝 .Net 類別庫來的。

    直接抓批次檔輸出很不方便,一般都用輸出轉向到文字檔,在讀文字檔,不然就要用 Console 系列讀取 Console 的緩衝區。

    2006年11月16日 上午 12:58
    版主
  • 你可以由 Process.StandardOutput,搭配 StreamReader 來取得輸出:

    Process 寫入文字至其標準資料流,該文字一般都是顯示在主控台上。您可以經由重新導向 StandardOutput 資料流,管理或隱藏處理序的輸出。例如,您可以篩選文字、以不同的方式格式化文字,或將輸出寫入至主控台 (Console) 和指定的記錄檔。

    注意事項:

    若要使用 StandardOutput,您必須將 ProcessStartInfo.UseShellExecute 設定為 false,而且必須將 ProcessStartInfo.RedirectStandardOutput 設定為 true。否則,從 StandardOutput 資料流讀取時會擲回例外狀況。

    可以同步或非同步讀取重新導向的 StandardOutput 資料流。諸如 Read、ReadLine 和 ReadToEnd 等方法會在處理序的輸出資料流上執行同步讀取作業。必須等到關聯的 Process 寫入其 StandardOutput 資料流,或關閉該資料流之後,這些同步讀取作業才算完成。

    相反地,BeginOutputReadLine 會在 StandardOutput 資料流上啟動非同步讀取作業。這個方法會啟用資料流輸出的指定事件處理常式,並立即傳回給呼叫端;將資料流輸出導向事件處理常式時,呼叫端可以同時執行其他工作。

    同步讀取作業會在從 StandardOutput 資料流讀取的呼叫端和寫入該資料流的子處理序 (Child Process) 之間,引入相依性。這些相依性可能會產生死結狀況。當呼叫端從子處理序的重新導向資料流讀取時,它便相依於該子系。呼叫端會等候讀取作業,直到子系寫入至資料流或關閉資料流為止。當子處理序寫入足夠資料,填滿其重新導向資料流時,它便相依於父代。子處理序會等候下一個寫入作業,直到父代從完整資料流讀取或關閉資料流為止。當呼叫端和子處理序互相等候對方完成作業且無法繼續時,就會導致鎖死狀態。您可以評估呼叫端和子處理序之間的相依性,藉以避免死結。

    2006年11月16日 上午 02:08
    版主
  • 謝謝樓上兩位的回答

    給我的幫助很大

    感恩

    再請問一下  XD

    如果我把bat處理過後的檔案存成output.txt檔

    在多人連線的情況下會抓錯txt檔嗎?

    因為我還需要處理那個檔案輸出過後的資料

    謝謝

    2006年11月16日 下午 03:17