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

时间:2010-01-15 03:40:44

标签: python windows pywin32 readfile

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

我正在尝试正确使用win32file.ReadFile功能,而我在解释可能的结果代码时遇到了一些麻烦。

我正在调用这样的函数:

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

我正在读取我启动的子进程的输出。我得到了很好的数据,但我担心管道中的数据可能比4096个字符多。 (我宁愿这样做,而不是只选择一个任意大的缓冲区大小。)

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

ActiveState docs说:

  

结果是(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 docs表示0表示失败,非零表示成功,您需要运行GetLastError以了解更多信息。
  3. 这样做的正确方法是什么?

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

3 个答案:

答案 0 :(得分:3)

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

我对ActiveState文档的解释与您的相同。听起来包装器的工作方式与本机API略有不同。对不起,我还没有尝试过这个。

答案 1 :(得分:0)

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

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

答案 2 :(得分:-1)

请注意,ReadFile定义为:

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

其中...

hFile = PyHANDLE

这是任何Windows句柄(可以是文件,进程,线程......)

buffer/bufSize = PyOVERLAPPEDReadBuffer

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

overlapped=None [=PyOVERLAPPED]

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

所以 - 你基本上可以调用ReadFile,如:

ReadFile(child_stdout_r, 0, None)

,您指定给它的对象将包含文件句柄的完整内容。