使用 win32file.ReadFile 从管道获取输出的正确方法是什么?

发布于 2024-08-18 03:20:16 字数 1575 浏览 11 评论 0原文

我正在使用 pywin32 扩展来访问 Python 下的 win32 API。我是用 Python 进行 Windows 编程的新手——我是一个 POSIX 人——所以我可能会以一种愚蠢的方式做事。

我正在尝试使用 win32file.ReadFile< /a> 功能正常,但我在解释可能的结果代码时遇到一些问题。

我这样调用该函数:

result, data = win32file.ReadFile(child_stdout_r, 4096, None)

我正在读取我启动的子进程的输出。我获得了良好的数据,但我担心管道中的数据可能超过 4096 个字符。 (我宁愿正确执行此操作,而不是只选择任意大的缓冲区大小。)

如果要读取的字符超过 4096 个字符,我需要多次运行 win32file.ReadFile直到我耗尽管道。要确定是否需要多次运行 ReadFile,我需要解释结果代码。

ActiveState 文档 说:

结果是 (hr, string/PyOVERLAPPEDReadBuffer) 的元组,其中 hr 可以是 0、ERROR_MORE_DATA 或 ERROR_IO_PENDING。

由于我在函数调用中将重叠值设置为 None,因此我认为我不需要担心任何 PyOVERLAPPEDReadBuffer 内容。 (因为我得到了有效的数据,所以我认为我是对的。)

hr 结果变量有两个问题:

  1. 我在任何地方都找不到常量 ERROR_MORE_DATA 或 ERROR_IO_PENDING 的值。
  2. ActiveState 文档似乎暗示 0 表示成功,常量(无论它们是什么)表示失败。 Microsoft 文档指出 0 表示失败,非零表示成功,您需要运行 GetLastError 来了解更多信息。

这样做的正确方法是什么?

编辑添加:我没有使用子流程,因为我需要将子流程添加到我创建的作业对象中。目标是如果父进程死亡,则所有子进程立即死亡。通过将子进程添加到作业对象,当作业对象的最后一个句柄关闭时,子进程将被终止。由父进程持有的句柄将在父进程退出时关闭。据我所知,所有这些都阻止我使用子进程。

I'm using the pywin32 extensions to access the win32 API under Python. I'm new at doing Windows programming in Python -- I'm a POSIX guy -- so I may be doing things in a bone-headed manner.

I'm trying to use the win32file.ReadFile function properly, and I'm having some trouble interpreting the possible result codes.

I'm calling the function like this:

result, data = win32file.ReadFile(child_stdout_r, 4096, None)

I'm reading the output from a child process that I launch. I get good data, but I'm concerned that there may be more data in the pipe than 4096 characters. (And I'd rather do this right, instead of just picking an arbitrarily large buffer size.)

In the case where there's more than 4096 characters to read, I would need to run win32file.ReadFile multiple times until I exhaust the pipe. To find out whether I need to run ReadFile multiple times, I need to interpret the result code.

The ActiveState docs say that:

The result is a tuple of (hr, string/PyOVERLAPPEDReadBuffer), where hr may be 0, ERROR_MORE_DATA or ERROR_IO_PENDING.

Since I'm setting the overlapped value to None in the function call, I think I don't need to worry about any PyOVERLAPPEDReadBuffer stuff. (And since I'm getting valid data, I think I'm right.)

I have two problems with the hr result variable:

  1. I can't find the values of the constants ERROR_MORE_DATA or ERROR_IO_PENDING anywhere.
  2. The ActiveState docs seem to imply that 0 is success and the constants (whatever they are) indicate failure. The Microsoft docs state that 0 indicates failure, non-zero indicates success, and you need to run GetLastError to find out more.

What's the correct way to do this?

EDITED TO ADD: I'm not using subprocess because I need to add the child process to a job object I create. The goal is to have all child processes die immediately if the parent process dies. By adding the child process to the job object, the child process will be terminated when the last handle to the job object is closed. The handle, held by the parent, will be closed when the parent exits. All of this, as far as I can tell, precludes me from using subprocess.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我的黑色迷你裙 2024-08-25 03:20:16

对于错误代码,请尝试 winerror.ERROR_MORE_DATAwinerror.ERROR_IO_PENDING

我对 ActiveState 文档的解释与您的相同。听起来包装器的工作方式与本机 API 略有不同。

我还没有真正尝试过这个。

For error codes, try winerror.ERROR_MORE_DATA and winerror.ERROR_IO_PENDING

My interpretation of the ActiveState docs is the same as yours. It sounds like the wrapper works slightly differently than the native API.

I haven't actually tried this.

你的他你的她 2024-08-25 03:20:16

考虑使用subprocess来启动进程。它将为您提供一组类似文件的对象,您可以使用它们与其他应用程序进行对话。

如果您运行的是 2.6+,则 Popen 对象的 .terminate() 方法将允许您终止进程。

Consider using subprocess to launch the process. It will give you a set of file-like objects that you can use to talk with the other app.

The .terminate() method of the Popen object will allow you to terminate the process if you are running 2.6+.

我不吻晚风 2024-08-25 03:20:16

请注意,ReadFile 定义为:

(int, string) = ReadFile(hFile, buffer/bufSize , overlapped)

其中...

hFile = PyHANDLE

这是任何窗口句柄(可以是文件、进程、线程...)

buffer/bufSize = PyOVERLAPPEDReadBuffer

,根据文档,它会自动分配 hFile 的内容,无论它是否重叠。

overlapped=None [=PyOVERLAPPED]

如果您愿意,您可以分配一个额外的对象来获取超出重叠(缓冲区/bufSize)的任何额外数据,但默认情况下这是NULL。

因此 - 您基本上可以像这样调用 ReadFile

ReadFile(child_stdout_r, 0, None)

并且您分配给它的对象将包含文件句柄的完整内容。

note that ReadFile is defined as:

(int, string) = ReadFile(hFile, buffer/bufSize , overlapped)

where...

hFile = PyHANDLE

which is any windows handle (can be file, process, thread...)

buffer/bufSize = PyOVERLAPPEDReadBuffer

which, according to documentation automatically allocates contents of hFile regardless if it overlaps or not.

overlapped=None [=PyOVERLAPPED]

you can allocate an additional object to take any extra data, beyond the overlapped (buffer/bufSize) if you wish, but by default this is NULL.

So - you can basically call ReadFile like:

ReadFile(child_stdout_r, 0, None)

and the object you assign it to will contain the full contents of the file handle.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文