1. 程式人生 > 其它 >ArchLinux系統 .NET6 在C#中使用System.Diagnostics.Process 呼叫python指令碼

ArchLinux系統 .NET6 在C#中使用System.Diagnostics.Process 呼叫python指令碼

此方法需要在執行指令碼的電腦上安裝好python環境

1. 核心實現程式碼

  1. 使用Process 在shell中執行命令列 呼叫py檔案
var process = new Process();

//命令引數
var args = new string[]{"-u", ""}

//py 檔案路徑 可以使用相對路徑
var path = "./PythonModule/"+pythonFileName;

//如果安裝了anaconda可以像我這樣使用anaconda中的python絕對路徑, 當然如果配置了環境變數 也可以直接寫 一個python就可以
process.StartInfo.FileName = "/home/sukeban/anaconda3/bin/python3";

//新增引數
args.ForEach(arg => path += $" {arg}");
process.StartInfo.Arguments = sArguments;

//重定向標準輸入輸出 以及錯誤輸出
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardError = true;
//是否在新視窗中啟動程序
process.StartInfo.CreateNoWindow = true;

//開始執行
process.Start();
//接收輸入輸出 以及錯誤, 記得一定要用using
using var sw = process.StandardInput;
using var srout = process.StandardOutput;
using var srerr = process.StandardError;
sw.AutoFlush = true;

//使用ReadToEnd()獲取輸出資訊
var outMessage = srout.ReadToEnd();
var errorMessage = srerr.ReadToEnd();

//無限期地等待關聯的流程退出
process.WaitForExit();
  1. python怎麼和c# 實現資料傳輸

    1. 此例是呼叫pyautogui 使用火狐瀏覽器開啟連結 並識別截圖獲取座標之後滑鼠點選座標的一個功能
    2. 使用場景為個人辦公 整個功能的流程不考慮執行緒安全
    3. 新建兩個json檔案 一個用於傳參, 一個用於接受返回引數
    4. 目錄結構
graph LR A(PythonModule 資料夾)--> B[BrowserArticleDetail.py] A --> C(Mediums 資料夾) C --> D(BrowserArticleDetail 資料夾) D --> E[BrowserArticleDetailParam.json] D --> F[BrowserArticleDetailResult.json]
  1. 在python中讀取通過json檔案讀取引數
import json
import os
import time

from PIL import Image
import pyautogui


class PreviewPageOnMobileMode:
    def __init__(self):
        self.__url, self.__param_json_path, self.__param_uuid = "", "", ""
        # 獲取當前py檔案的工作目錄
        self.__root_path = os.path.dirname(os.path.abspath(__file__))
        try:
            # 拼接路徑
            with open(f"{self.__root_path}/Mediums/BrowserArticleDetail/BrowserArticleDetailParam.json", 'r') as f:
                obj = json.loads(f.read())
                self.__url, self.__param_uuid = obj.get('self.__url', ''), obj.get('self.__param_uuid', '')
            if self.__url == "" or self.__param_uuid == "":
                raise Exception("引數錯誤, 連結或者 引數uuid不能為空")
            self.__open_browser()
            self.__switch_to_mobile_mode()
    
        except Exception as e:
            # 拼接路徑
            result_json_path = f"{self.__root_path}/Mediums/BrowserArticleDetail/BrowserArticleDetailResult.json"
            with open(result_json_path, 'w+b') as f:
                # 如果報錯將錯誤資訊寫入BrowserArticleDetailResult.json
                error_json = f'{"error": "{str(e)}", "self.__param_uuid": "{self.__param_uuid}"}'
                f.write(bytes(error_json))

    def run_script(self):
        self.__open_browser()
        self.__switch_to_mobile_mode()

    def __open_browser(self):
        # 在命令的最後要加上&符號 否則會阻塞執行緒
        os.system(f'firefox -self.__url {self.__url} &')

    def __switch_to_mobile_mode(self):
        begin_time = time.perf_counter()
        location = None
        """獲取截圖對應的座標"""
        while True:
            location = pyautogui.locateCenterOnScreen(f'{self.__root_path}/Mediums/BrowserArticleDetail/EduCircle.png', confidence=0.5)
            if location is not None:
                break
            print((time.perf_counter() - begin_time) % 1000)
            # 超過六秒則丟擲異常
            if (time.perf_counter() - begin_time) % 1000 > 6:
                raise Exception("開啟瀏覽器等待超時")
            
        # 此處應該是繼續判斷瀏覽器是否渲染完成, 但在我的電腦上執行可以直接省略為兩個sleep等待渲染
        time.sleep(1)
        # 使用快捷鍵開啟瀏覽器的移動端瀏覽模式
        pyautogui.hotkey("ctrl", "shift", "m")
        time.sleep(2)
        pyautogui.hotkey("ctrl", "r")


if __name__ == '__main__':
    previewPageOnMobileMode = PreviewPageOnMobileMode()
    previewPageOnMobileMode.run_script()
    

繁星縱變,智慧永恆