2010-01-15 69 views
1

我使用pywin32擴展來訪問Python下的win32 API。我是用Python進行Windows編程的新手 - 我是POSIX的人 - 所以我可能會以一種頭腦的方式做事。使用win32file.ReadFile從管道獲取輸出的正確方法是什麼?

我試圖正確使用win32file.ReadFile函數,並且在解釋可能的結果代碼時遇到了一些麻煩。

我打電話的功能是這樣的:

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

我讀一個孩子的過程,我啓動的輸出。我獲得了很好的數據,但是我擔心管道中的數據可能會超過4096個字符。 (我寧願這樣做,而不是僅僅選擇一個任意大的緩衝區大小。)

在超過4096個字符的情況下,我需要多次運行win32file.ReadFile,直到我耗盡管道。爲了找出我是否需要多次運行ReadFile,我需要解釋結果代碼。

ActiveState docs說:

結果是元組(小時,串/ PyOVERLAPPEDReadBuffer),其中小時可以是0,或ERROR_MORE_DATA ERROR_IO_PENDING。

因爲我在函數調用中將重疊值設置爲None,我認爲我不需要擔心任何PyOVERLAPPEDReadBuffer的東西。 (而且因爲我得到有效的數據,我想我是對的。)

我有兩個問題小時結果變量:

  1. 我找不到常量ERROR_MORE_DATA值或任何地方都有ERROR_IO_PENDING。
  2. 的ActiveState的文檔似乎暗示0是成功和常數(無論他們是)表示失敗。該Microsoft docs狀態0表示失敗,非零表示成功,你需要運行GetLastError函數,以瞭解更多信息。

什麼是正確的方法來做到這一點?

編輯補充:我不使用子,因爲我需要的子進程添加到作業對象的創建。目標是如果父進程死亡,讓所有子進程立即死亡。通過向作業對象添加子進程,當作業對象的最後一個句柄關閉時,子進程將終止。由父母持有的手柄將在父母退出時關閉。就我所知,所有這些都阻止了我使用子進程。

回答

2

對於錯誤代碼,嘗試winerror.ERROR_MORE_DATA和winerror.ERROR_IO_PENDING

我對ActiveState的文檔的解釋是一樣的你。聽起來這個包裝器的工作原理與原生API略有不同。對不起,我沒有嘗試過。

+0

我想我愛你,jdigital。 ;-) 謝謝! – Schof 2010-01-16 02:06:27

+0

我必須承認這對我來說是第一次。 Blush ;-) – jdigital 2010-01-16 06:08:40

0

考慮使用subprocess啓動過程。它會給你一組類似文件的對象,你可以用它來與其他應用程序交談。

的POPEN對象的.terminate()方法可以讓你終止進程,如果你正在運行2.6+。

+0

如果父進程能夠清理,有很多方法可以終止子進程,但是如果父進程因任何原因死亡,我需要終止子進程,包括終止Windows的相當於Unix的「kill -9「 - 這排除了任何清理操作。 – Schof 2010-01-15 03:53:28

-1

注意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) 

和對象分配它包含文件句柄的全部內容。

+0

'ReadFile(child_stdout_r,0,None)'只是在python 2.7.9上返回一個空字符串。這個答案是錯誤的。 – 2015-04-28 05:07:10

+0

其實你只是沒讀過我的答案 - 我舉了一個例子。答案是正確的,因爲它被要求的python版本。 – efraimip 2016-08-20 08:29:44

相關問題