C#使用Process操作CMD,process.StandardOutput.ReadToEnd阻塞/假死/獲取不到信息/無法關閉CMD真正原因及解決方案!!

網上看了很多解決方案

有的說在最後一條命令執行"exit",

有的說重定向標準錯誤輸出要設置成false(process.StartInfo.RedirectStandardError = false;) 

有的說命令執行完要獲取輸出信息,否則會一直等待↓↓↓↓↓

output = process.StandardOutput.ReadToEnd();

和errOutput = process.StandardError.ReadToEnd();

有的說要在等待程序執行完退出進程 process.WaitForExit();
............................................                   
看看來去結果都解決不了執行完命令獲取不到輸出,CMD掛起的問題!

直到最後意外發現StandardInput是個IO流,IO流線程回收機制是不會主動回收的,這個需要我們手動去關閉它才行,果不其然,添加完這行代碼,裏面就解決了:process.StandardInput.Close();                   

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓我的代碼: ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

private string ExecutionCMDOrders(List<string> list,bool isReadReturn) {
    string output = null;
    string errOutput = null;
    try {
        //創建一個進程
        Process process = new Process();
        process.StartInfo.FileName = "cmd.exe";
        process.StartInfo.UseShellExecute = false;//是否使用操作系統shell啓動
        process.StartInfo.RedirectStandardInput = true;//接受來自調用程序的輸入信息
        process.StartInfo.RedirectStandardOutput = true;//由調用程序獲取輸出信息
        process.StartInfo.RedirectStandardError = true;//重定向標準錯誤輸出
        process.StartInfo.CreateNoWindow = true;//不顯示程序窗口
        process.Start();//啓動程序
        process.StandardInput.AutoFlush = true;

        //輸入命令
        for (int i = 0; i < list.Count; i++) {
            process.StandardInput.WriteLine(list[i]);
            Console.WriteLine(i + " " + list[i]);
        }

        //ReadToEnd阻塞使用exit純粹是扯淡
        //process.StandardInput.WriteLine("exit");  

        //真正的原因是StandardInput流沒有關閉,所以線程會一直等待新輸入,以便獲取產生的輸出信息
        process.StandardInput.Close();

        //是否輸出信息
        if (isReadReturn) {
            //獲取cmd窗口的輸出信息
            output = process.StandardOutput.ReadToEnd();
            errOutput = process.StandardError.ReadToEnd();
            cmdOutput_textBox.AppendText(output + "\r\n" + errOutput);
            //等待程序執行完退出進程
            process.WaitForExit();
        }
        
        process.Close();
        process.Dispose();
    } catch (Exception ex) {
        MessageBox.Show(ex.Message + "\r\n跟蹤;" + ex.StackTrace);
    }
    return output;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章