2016-11-01 2 views
0

Я пытаюсь открыть исполняемый файл, который открывает файл базы данных HEC .dss. Тем не менее, я могу только заставить его прочитать один аргумент после открытия exe, а затем он ничего не читает. Есть ли способ заставить его продолжать вставлять команды.Как использовать подпроцесс Python для записи нескольких входов в пользовательскую программу exe

У этого exe есть некоторые уникальные функции, которые включают в себя, что первая команда запрашивает, какой DSS-файл вы собираетесь читать. Затем вы можете ввести команду для создания выходного файла txt, который он будет писать для остальных команд. То, что мне удалось сделать до сих пор, - запустить программу и запустить одну команду в exe (переменная mydss). Однако после считывания первой команды в командной строке не используются никакие другие команды. Я чувствую, что здесь что-то не хватает. Вот код:

##Testing on how to run and use the DSSUTL program 
import subprocess 
from subprocess import PIPE, STDOUT 

DSSUTL = "C:\Users\sduncan\Documents\HEC-DSS\HEC-DSSVue-2_0_1\FromSivaSel\DSSUTL.exe" 
mydss = "C:\Users\sduncan\Documents\HEC-DSS\HEC-DSSVue-2_0_1\FromSivaSel\\forecast.dss" 
firstLine = "WR.T TO=PythonTextOutput.txt" 
commandLine = "WR.T B=SHAVER RESERVOIR-POOL C=FLOW-IN E=1HOUR F=10203040" 
myList = [firstLine, commandLine] 
ps = subprocess.Popen([DSSUTL, mydss, myList[1], myList[0]], shell=True) 

Я также попытался в том числе STDIN = subprocess.PIPE, но это приводит лишь к открытию ехе и он пустой (когда я открываю его с кодом выше, я могу читать это и увидеть, что переменная mydss была прочитана правильно). Когда я использовал stdout или sterr, программа открывается и закрывается.

Я также попытался с помощью кода, когда STDIN = PIPE был включен с:

ps.stdin.write(myList[1]) 
ps.stdin.write(myList[0]) 
ps.communicate()[0] 

Однако, это ничего в программе не читать. Эта программа работает как в командной строке, однако, это не типичный CMD, как это было сделано, чтобы читать типы файлов DSS и производить текстовый файл со списком из поисков, как в CommandLine переменной

Было бы неплохо знаю, что я могу сделать, чтобы исправить код, чтобы я мог вводить дополнительные команды. Любая помощь, чтобы знать, как проверить событие, если команды были отправлены или обработаны этим exe. В конце концов, я добавлю еще много команд в exe-файл для печати в текстовый файл, поэтому, если есть способ получить питон для записи в exe, который поможет.

+0

Его интерактивная программа, и вы хотите управлять этим взаимодействием с python? Это было бы возможно в системах Linux, использующих модуль 'pexpect' намного сложнее для окон. Существует [ограниченная поддержка] (http://pexpect.readthedocs.io/en/stable/overview.html#pexpect-on-windows), но я не знаю, будет ли это работать для вас. – tdelaney

+0

Его общая для интерактивных программ также имеет интерфейс сценариев. Если ваша программа делает это, вы можете написать команду stdin, чтобы получить то, что вы хотите. – tdelaney

+0

@tdelaney, это часто возможно с помощью API консоли в расширении C или через ctypes. Если родительский процесс подключен к той же консоли, что и дочерний, то он может записывать входной буфер консоли и читать из активного экранного буфера консоли. – eryksun

ответ

0

@tdelaney, @eryksun Спасибо за комментарий, ваши комментарии о трубах и задержке действительно помогли. Я был в состоянии решить эту проблему, используя этот код:

##Testing on how to run and use the DSSUTL program 
import subprocess 
from subprocess import PIPE, STDOUT 
import time 

DSSUTL = "C:\Users\sduncan\Documents\HEC-DSS\HEC-DSSVue-2_0_1\FromSivaSel\DSSUTL.exe" 
mydss = "C:\Users\sduncan\Documents\HEC-DSS\HEC-DSSVue-2_0_1\FromSivaSel\\forecast.dss" 
location = "WR.T TO=PythonTextOutput.txt" + " WR.T B=SHAVER RESERVOIR-POOL C=FLOW-IN E=1HOUR F=10203040" + "\n" 
filecontent1 = "WR.T B=FLORENCE RESERVOIR-POOL C=FLOW-IN E=1HOUR F=10203040" + "\n" 
filecontent2 = "WR.T B=HUNTINGTON LAKE-POOL C=FLOW-IN E=1HOUR F=10203040" + "\n" 
filecontentList = [filecontent1, filecontent2] 
myList = [DSSUTL, mydss] # commandLine, location 
ps = subprocess.Popen(myList , shell=False, stdin=PIPE, stdout=PIPE, stderr=STDOUT) 
time.sleep(1) 
# input into stdin 
ps.stdin.write(location) 
time.sleep(1) 
ps.stdin.write(filecontent1) 
time.sleep(1) 
ps.stdin.write(filecontent2) 
time.sleep(1) 
print ps.communicate()[0] 
# End Script 

С помощью трубы, чтобы поговорить с программой и положить задержку времени, казалось, решить эту проблему и позволил мне поговорить с консоли. Несмотря на то, что дисплей консоли пуст, путем печати команды connect(), он выводит то, что сделал консоль, и создает текстовый файл с требуемой серией.

Спасибо, что надавили на меня в правильном направлении!

+0

Похоже, что соответствующее изменение здесь добавляет конечную '' \ n'' к каждой строке ввода, которую вы могли бы вместо этого положить в конец каждого строкового литерала, например. используйте '' string \ n'' вместо '' string '+' \ n''. Вызов 'sleep()' не требуется; вы просто пишете на трубу. Вы должны иметь возможность присоединиться к 3 строкам и записать их как аргумент 'input' для' общения'. FYI, вы * не * разговариваете с консолью; каждая из трех стандартных ручек - это труба. Фактически, вы сделали 'stdout' и' stderr' тот же самый канал, но я не рекомендую это в большинстве случаев. – eryksun