2010-01-15 7 views
1

Я использую расширения pywin32 для доступа к API win32 под Python. Я новичок в программировании Windows на Python - я парень 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, чтобы узнать больше.

Каков правильный способ сделать это?

EDITED TO ADD: Я не использую подпроцесс, потому что мне нужно добавить дочерний процесс к объекту задания, который я создаю. Цель состоит в том, чтобы все дочерние процессы немедленно умирали, если родительский процесс умирает. Добавив дочерний процесс к объекту задания, дочерний процесс будет завершен, когда последний дескриптор объекта задания будет закрыт. Ручка, удерживаемая родителем, будет закрыта, когда родитель выйдет. Все это, насколько я могу судить, исключает возможность использования подпроцесса.

ответ

2

Для кодов ошибок, попробуйте winerror.ERROR_MORE_DATA и winerror.ERROR_IO_PENDING

Моя интерпретация ActiveState документы так же, как ваша.Похоже, что обертка работает несколько иначе, чем собственный API. Извините, я на самом деле не пробовал это.

+0

Я думаю, что люблю тебя, jdigital. ;-) Благодаря! – Schof

+0

Должен признаться, это первый для меня на SO. Blush ;-) – jdigital

0

Рассмотрите возможность использования subprocess для запуска процесса. Он предоставит вам набор файловых объектов, которые вы можете использовать для общения с другим приложением.

Метод объекта Popen позволяет завершить процесс, если вы используете 2.6+.

+0

Существует множество способов убить дочерний процесс, если родитель может очистить, но мне нужно убить дочерний процесс, если родитель умирает по какой-либо причине вообще, в том числе заканчивается эквивалентом Windows, эквивалентным Unix's kill -9 ", что исключает любые действия по очистке. – Schof

-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. Эти ответы неверны. –

+0

На самом деле вы просто не читали мой ответ - я приводил пример. ответ правильный, для версии python его попросили. – efraimip