c#窗体中用 cmd 方式执行 Python 文件,如何在文本框中输出 py 文件里的 print 值

2019-03-06 17:35:29 +08:00
 oldbird

python 文件里隔几秒会打印一个值,想把这些值同时显示在窗体里。 查了网上的资料,思路基本上是截取输出流, 现在自己能实现的是一次性显示所有的打印值,不知道怎么才能做到依次显示?

2954 次点击
所在节点    Python
16 条回复
yicong135
2019-03-06 17:58:17 +08:00
你可以搜索下 c#获取命令行内容
Youen
2019-03-06 19:19:28 +08:00
我觉得可以参考 VSCODE debug python 的那种
nanaw
2019-03-06 19:47:30 +08:00
用获取管道的函数获取命令返回的字符串 Python 里面 os.popen 这样的
c#应该也有,
没有的话就重定向到文件再读取出来(
lihongjie0209
2019-03-06 19:53:16 +08:00
查一下 window 中共享内存的方法
bakabie
2019-03-06 20:03:08 +08:00
参考远程匿名管道。一个管道读一个管道写。
以前远控木马常用技术(?
oldbird
2019-03-07 06:47:58 +08:00
@yicong135 目前只做到了一次性获取所有控制台输出内容,不知道怎么按时间间隔依次获取,还望指点。
yicong135
2019-03-07 09:09:40 +08:00
如果控制台输出没法满足你需求,那你可以用通讯手段,比如命名管道或者 socket
sarlanori
2019-03-07 09:44:00 +08:00
直接使用 Process 类的 OutputDataReceived 和 ErrorDataReceived 事件来获取进程输出和错误信息。

记得要将 EnableRaisingEvents 设为 true,并在调用 Process.Start 后调用 BeginErrorReadLine 和 BeginOutputReadLine。
oldbird
2019-03-07 10:51:01 +08:00
@sarlanori 这样是等 cmd 执行完一次性读取输出值,还是可以执行途中依次同步显示输出值?
sarlanori
2019-03-07 13:13:11 +08:00
实时同步触发,当目标进程打印一次,该事件触发一次。

其实你自己试一下就知道了,就几行代码的事。
oldbird
2019-03-07 15:48:24 +08:00
@sarlanori 试了以下代码,但是 richtextbox 控件中还是只能等 py 文件运行完才一次性显示所有的 print 输出,不知道怎么改。。。。
##aaa.py 每隔 2 秒打印一个值
import time
for i in range(0,5):
print i
time.sleep(2)

## c#代码段
using (Process process = new System.Diagnostics.Process())
{
process.StartInfo.FileName = "python";
process.StartInfo.Arguments = "aaa.py";
// 必须禁用操作系统外壳程序
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.Start();

// 异步获取命令行内容
process.BeginOutputReadLine();
process.BeginErrorReadLine();

// 为异步获取订阅事件
process.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
process.ErrorDataReceived += new DataReceivedEventHandler(process_ErrorDataReceived);
}
oldbird
2019-03-07 16:25:48 +08:00
跟了一下代码,11 楼的方法是可行的。
问题在于 richtextbox.text 的值的确是在动态更新的(采用 append 方式),但是控件中一直不显示,直到 cmd 运行完,才显示出来,所以只看到了最后一次的 text 值,即全部的输出内容。这个问题怎么解决呢?
sarlanori
2019-03-07 18:10:32 +08:00
@oldbird 估计是线程被阻塞了
sarlanori
2019-03-08 10:16:26 +08:00
@oldbird 刚才研究了一下,这个问题出在 python 代码里,你需要在每次 print 之后调用 sys.stdout.flush 及时将缓冲区里的内容 flush 出去,这样 C# 里回调就能触发了。
sarlanori
2019-03-08 10:17:26 +08:00
oldbird
2019-03-08 11:46:53 +08:00
@sarlanori 感谢,确实是的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/541828

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX