C# 调用python打包的exe程序

本文介绍如何使用 C# 启动并隐藏由 PyInstaller 打包的 Python 程序,同时捕获其输出信息进行交互。通过创建进程并设置相关属性,可以实现在 C# 中读取 Python 程序的标准输出和错误输出。此外,还展示了 Python 如何调用 C# 程序并进行双向通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 需求 C#  启动使用pyinstaller打包好的.exe 的python程序,隐藏python运行的cmd窗口,并将python程序的输出信息显示在C#的控件上

                     

Process p = new Process();
p.StartInfo.FileName = "./app.exe"; #python打包的.exe 程序
p.StartInfo.UseShellExecute = false; 
p.EnableRaisingEvents = true;
p.StartInfo.RedirectStandardInput = true; //重定向标准输入输出
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true; //
p.StartInfo.CreateNoWindow = true; #隐藏窗体

#订阅下面的事件
p.OutputDataReceived += new DataReceivedEventHandler(scu_pcomProcess_OutputDataReceived);
p.ErrorDataReceived += new DataReceivedEventHandler(Onscu_pcomerrorDataReceived);
p.Exited += new EventHandler(Onscu_pcomProcessExit);

p.Start();
    
#下面这两句是必须的,增加他们才能在上面订阅的事件中获得标准输入输出的消息                
p.BeginOutputReadLine();
p.BeginErrorReadLine();
p.WaitForExit();
p.Close();

2 在python程序中使用了print("信息")  和sys.stdout.write("")的地方要增加sys.stdout.flush(),刷新缓存,这样C#程序才能实时获得打印的消息

import sys

print("1234")

sys.stdout.flush() //刷新缓存

3 python 调用C#程序

  (1) python端

      

from subprocess import Popen,PIPE
import time
p=Popen('pipetest.exe',shell=True,stdin=PIPE,stdout=PIPE)

s=b"123\r\n"    //一定要有回车符
p.stdin.write(s)
p.stdin.flush() //一定要刷新缓存
print(p.stdout.readline())
time.sleep(3)
p.stdin.write(s)
p.stdin.flush()
print(p.stdout.readline())

 (2) C#端

int i = 0;
while(true)
{
     i += 1;
     string read = Console.ReadLine();
     Console.WriteLine(i.ToString()+read);
     Thread.Sleep(3000);
}

3 结束

### C# 调用 Python 编译的 EXE 并获取界面元素信息 为了实现从C#程序调用Python编译成的EXE文件并读取其界面信息,可以采用以下方法: #### 使用 Process 类启动 Python 应用程序C#中可以通过`System.Diagnostics.Process`类来启动外部进程。设置`ProcessStartInfo`属性以隐藏命令提示符窗口,并重定向标准输出以便捕获来自Python应用程序的信息。 ```csharp using System; using System.Diagnostics; class Program { static void Main() { var startInfo = new ProcessStartInfo(@"path\to\your_python_app.exe") { RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }; using (var process = Process.Start(startInfo)) { string output = process.StandardOutput.ReadToEnd(); Console.WriteLine(output); process.WaitForExit(); } } } ``` 此代码片段展示了如何创建一个新的进程实例来运行指定路径下的Python可执行文件[^1]。 #### UI 自动化技术用于访问界面元素 对于更复杂的场景——即不仅限于控制台输出而是要操作图形用户界面(GUI),则需要用到Windows自动化APIs 或第三方库如Selenium WebDriver、UIAutomation等工具。这些工具允许开发者编写测试脚本来模拟用户的交互行为以及提取GUI组件的状态数据。 例如,在.NET环境中推荐使用Microsoft自带的支持包 `UIAComWrapper.dll` 和 `UIAutomationClient.dll` 来构建自动化的客户端应用。以下是简单的例子展示怎样连接到已存在的窗口句柄(Window Handle)并检索特定控件的文字内容: ```csharp using System.Windows.Automation; // 假设我们知道目标窗体的名字叫做"MyApp" string appName = "MyApp"; IntPtr hWnd = FindWindow(null, appName); if(hWnd != IntPtr.Zero){ AutomationElement aeRoot = AutomationElement.FromHandle(hWnd); Condition cond = new PropertyCondition(AutomationElement.NameProperty,"Target Control Name"); AutomationElement targetControl = aeRoot.FindFirst(TreeScope.Descendants,cond); if(targetControl!=null){ object patternObj; ValuePattern valuePat=null; if(targetControl.TryGetCurrentPattern(ValuePattern.Pattern,out patternObj)){ valuePat=(ValuePattern)patternObj; Console.WriteLine(valuePat.Current.Value); }else{ // 处理其他类型的模式... } } } [DllImport("user32.dll", SetLastError=true)] static extern IntPtr FindWindow(string lpClassName,string lpWindowName); ``` 这段代码尝试找到名称匹配的应用程序主窗口,接着遍历它的子节点直到发现名为"Target Control Name"的目标控件;最后如果该控件支持`ValuePattern`接口的话,则打印出它当前持有的文本值。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值