Loading

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()
    

繁星纵变,智慧永恒

posted @ 2021-12-21 18:24  SukeBan  阅读(497)  评论(0)    收藏  举报