您好,登錄后才能下訂單哦!
使用.NET Core怎么跨平臺執(zhí)行命令、腳本?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
1. ProcessStartInfo 類
ProcessStartInfo主要設置一些我們需要創(chuàng)建的進程的參數(shù)。比如需要啟動的應用程序的文件名,參數(shù)等等。
(1)構(gòu)造方法
它有三個構(gòu)造方法:
public ProcessStartInfo(); public ProcessStartInfo(string fileName); public ProcessStartInfo(string fileName, string arguments);
fileName:用于啟動進程的應用程序。
arguments:在進程啟動時傳遞給應用程序的命令行參數(shù)。
(2)主要屬性
CreateNoWindow:指示是否在新窗口中啟動進程。
RedirectStandardError:指示應用程序的錯誤輸出是否寫入到流中。
RedirectStandardInput:指示是否從應用程序讀取應用程序的輸入流。
RedirectStandardOutput:指示應用程序的文本輸出是否寫入流。
StandardErrorEncoding:錯誤輸出內(nèi)容編碼。
StandardOutputEncoding:文本輸出內(nèi)容編碼。
UseShellExecute:指示是否使用操作系統(tǒng)shell啟動進程。如果啟動進程時使用shell,則為true; 如果應該直接從可執(zhí)行文件創(chuàng)建進程,則為false。 默認值是true。
該類并沒有定義自己的方法,因為它主要設置一些創(chuàng)建進程需要的參數(shù)信息。
2. Process 類
該類的主要作用是提供對本地和遠程進程的訪問,并使你能夠啟動和停止本地系統(tǒng)進程。
(1).主要屬性
ExitCode:獲取退出代碼。0表示正常, 非0表示非正常退出。
ExitTime:獲取關聯(lián)進程退出的時間。
StartTime:獲取關聯(lián)進程啟動的時間。
HasExited:獲取一個值,指示相關進程是否已終止。
MachineName:獲取運行關聯(lián)進程的計算機的名稱。
SessionId:獲取關聯(lián)進程的終端服務會話標識符。
StandardError:獲取讀取應用程序錯誤輸出的流。
StandardInput:獲取應用程序輸入內(nèi)容的流。
StandardOutput:獲取用于讀取應用程序文本輸出的流。
Threads:獲取關聯(lián)進程中正在運行的線程集合。
(2).主要方法
Start :啟動進程
BeginErrorReadLine:異步開始讀取應用錯誤輸出。
BeginOutputReadLine:異步開始讀取應用標準輸出。
CancelErrorRead:取消讀取錯誤輸出。
CancelOutputRead:取消讀取標準輸出。
Close:釋放與此組件關聯(lián)的所有資源。
CloseMainWindow:通過向其主窗口發(fā)送關閉消息來關閉具有用戶界面的進程。
Kill:立即停止關聯(lián)的進程。
Refresh:放棄已經(jīng)在進程中緩存的關聯(lián)進程的任何信息。
WaitForExit:等待關聯(lián)進程退出,可以設置超時時間,如不設置則一直等待。
(3)事件
一共有三個事件:
ErrorDataReceived:接收到關聯(lián)進程輸出錯誤數(shù)據(jù)。
OutputDataReceived:接收到關聯(lián)進程輸出標準數(shù)據(jù)。
Exited:關聯(lián)進程退出
三.在Windows OSX Linux 下執(zhí)行命令
這里我選擇.NET Core帶的 dotnet --info
輸出.NET Core SDK&Runtime相關的信息。
我們通過cmd執(zhí)行會收到下面的信息:
1.編寫代碼執(zhí)行命令
編寫的代碼如下:
static void Main() { //創(chuàng)建一個ProcessStartInfo對象 使用系統(tǒng)shell 指定命令和參數(shù) 設置標準輸出 var psi = new ProcessStartInfo("dotnet", "--info") {RedirectStandardOutput = true}; //啟動 var proc=Process.Start(psi); if (proc == null) { Console.WriteLine("Can not exec."); } else { Console.WriteLine("-------------Start read standard output--------------"); //開始讀取 using (var sr = proc.StandardOutput) { while (!sr.EndOfStream) { Console.WriteLine(sr.ReadLine()); } if (!proc.HasExited) { proc.Kill(); } } Console.WriteLine("---------------Read end------------------"); Console.WriteLine($"Total execute time :{(proc.ExitTime-proc.StartTime).TotalMilliseconds} ms"); Console.WriteLine($"Exited Code : {proc.ExitCode}"); } }
執(zhí)行結(jié)果如下:
從執(zhí)行結(jié)果可以看出,我們通過編寫的程序來執(zhí)行dotnet --info
命令獲取的結(jié)果幾乎一樣,只有第一行的提示,我們通過cmd執(zhí)行命令輸出的是中文,我們通過程序調(diào)用執(zhí)行輸出的是英文,這個問題,有興趣的朋友可以研究一下。
2.在Linux上執(zhí)行
使用的系統(tǒng)環(huán)境為CentOS 7.2,.NET Core sdk版本為2.0.3。
直接執(zhí)行命令結(jié)果如下:
我將代碼上傳到git server,然后在linux上clone然后執(zhí)行結(jié)果如下:
可以看到我們獲取執(zhí)行輸出是沒有問題的,但是獲取進程開始執(zhí)行出錯了,無法從進程檢索該信息,現(xiàn)在我們移除統(tǒng)計執(zhí)行時間的代碼:
這下我們執(zhí)行就沒有問題了。從這里我們可以得出結(jié)論:由于平臺的差異,獲取一些信息可能會出現(xiàn)異常,所以我們實際一定要在多個平臺上測試。
3.在OSX上運行
我在OSX上的.NET Core SDK版本為2.0.0 很久沒更新了。
直接執(zhí)行命令:
從git Clone代碼,執(zhí)行結(jié)果如下:
可以看出我們在OSX上執(zhí)行是沒有問題的。
四.在Windows OSX Linux 下執(zhí)行腳本1.編寫測試腳本
編寫腳本的主要邏輯為輸出程序當前目錄結(jié)構(gòu),然后輸出一句話 “dotnet in 操作系統(tǒng)類型”
Windows: win.bat
@echo off dir echo "dotnet in Windows"
Linux: linux.sh
#!/bin/bash ls echo "dotnet in Linux"
OSX: OSX.sh
#!/bin/bash ls echo "dotnet in OSX"
2.編寫測試代碼
我將所有的腳本都放在 項目根目錄/shell 文件夾下。
因為我們需要根據(jù)不同的操作類型,選擇不同的腳本來進行執(zhí)行,所以我們需要在代碼里面判斷一下操作系統(tǒng)類型。我們可以通過 RuntimeInformation.IsOSPlatform
來判斷。
static void Main() { string fileName="shell/"; //根據(jù)系統(tǒng)使用不同的shell文件 if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { fileName += "win.bat"; } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { fileName += "linux.sh"; } else { fileName += "OSX.sh"; } //創(chuàng)建一個ProcessStartInfo對象 使用系統(tǒng)shell 指定命令和參數(shù) 設置標準輸出 var psi = new ProcessStartInfo(fileName) { RedirectStandardOutput = true }; //啟動 var proc = Process.Start(psi); if (proc == null) { Console.WriteLine("Can not exec."); } else { Console.WriteLine("-------------Start read standard output--------------"); //開始讀取 using (var sr = proc.StandardOutput) { while (!sr.EndOfStream) { Console.WriteLine(sr.ReadLine()); } if (!proc.HasExited) { proc.Kill(); } } Console.WriteLine("---------------Read end------------------"); Console.WriteLine($"Exited Code : {proc.ExitCode}"); } }
3.在Windows下運行
在windows下運行是完全正常的。
4.在OSX運行
直接運行會報一個權(quán)限異常,如下:
使用命令加入執(zhí)行權(quán)限:
chmod +x OSX.sh
然后再次執(zhí)行:
可以看到成功執(zhí)行了腳本。
5.在Linux上運行
直接運行也是會有權(quán)限問題的:
同樣使用命令加入執(zhí)行權(quán)限:
chmod +x linux.sh
然后再次執(zhí)行:
可以看到成功執(zhí)行了我們的腳本。
4.容易犯的錯誤
看見上面的例子,我都成功執(zhí)行了,其實我踩了幾個坑,花了我不少時間來解決。
1.sh腳本一定要指定命令解析器
也就是這句話,放在sh腳本開頭
#!/bin/bash
看完上述內(nèi)容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業(yè)資訊頻道,感謝您對億速云的支持。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。