简体   繁体   中英

Passing Python variable to Powershell parameter using Popen

Got one for ya...

I am calling Powershell scripts from within my Python code, using Python's subprocess.Popen ; there's one Powershell script that requires an initial input parameter, and then an 'Enter' at the end, to quit. This one is giving me some trouble; Powershell code goes a little something like this:

$usrFileName = read-host "Please enter a file name to save the report"
*does some computering*
*creates some output* #ideally looking to capture this to output, but not the main problem
#display task complete to user
Read-Host -Prompt "Press Enter to exit" #This is problematic - don't know how to end this

Python code:

from tkinter import *
import os, datetime
import subprocess
from subprocess import Popen, PIPE
from keyboard import press_and_release


window = Tk()
window.title( 'PowerShell Script' )

frame = Frame(window)

fldrPath = r"C:/Users/paul.sisson/Downloads/Powershell Development/Monthly PMs PowerShell scans/BLDG-7UP-SUNY-Scans/7UP-LAB-A-325/"

listbox = Listbox(frame)
listbox.configure(width=50)

# Get todays date and add the lab name to be piped later
today = (datetime.datetime.now().strftime('%d%b%Y')).upper()
usrFileName = today + "-7UP-A-325"

for name in os.listdir(fldrPath):
    listbox.insert('end', name)

def selection():
    fileList = listbox.curselection()
    for file in fileList:
        keyword = 'Scans'
        os.chdir(fldrPath)

        proc = subprocess.Popen(["powershell.exe", '-File', fldrPath + '\\' + listbox.get(file)], bufsize=0,
                                universal_newlines=1, stdout=subprocess.PIPE, stdin=subprocess.PIPE)

        #proc.stdin.write(usrFileName) works to name file, but then deadlocks
   
        while proc.poll() is None:
            p = proc.stdout.readline()
            output.insert('end', p)
            output.update()


output = Text(window, width=75, height=6, wrap=WORD, background="white")

btn = Button(frame, text='Run Script', command=selection)

btn.pack(side=RIGHT, padx=5)
listbox.pack(side=LEFT)
frame.pack(padx=30, pady=30)
output.pack(fill=BOTH, expand=1, padx=5, pady=5)

window.mainloop()

I've successfully passed the input, using proc.stdin.write(usrFileName) , but I'm worried it's not the proper way to go about it. Considering the fact that I want to read AND write, I don't want to risk deadlocking the process, which I'm pretty sure is happening.

Tried a few other examples, based on a few threads:

proc = subprocess.Popen(["powershell.exe", '-File', fldrPath + '\\' + listbox.get(file),'-usrFileName:',
                                         propername], bufsize=0, universal_newlines=1, 
                                         stdout=subprocess.PIPE, stdin=subprocess.PIPE)

went with subprocess.call once or twice but I need to use proc.poll for the output, so that won't work.

You can see that I brought in keyboard to remedy the enter, but code would hang before getting there, so not sure if that's the way to go.

Long story short - I'm looking for some guidance on properly writing usrFileName to Powershell, at the beginning, reading the output from the Powershell, and then executing the 'Press Enter', at the end.

Should I explicitly close stdin , so the child process stops hanging?

I'm feeling like .communicate() or threading is the way to go, but I need someone with some elegance to show me the way!

Appreciate the support.

PS Changing the Powershell isn't an option, not my code, just trying to work with something that's already in place. Thanks!

Answering interactive Read-Host prompts via stdin requires that each response be terminated with a newline .

Therefore, end your stdin input with 2 newlines: one to answer the filename prompt, and another to answer the exit prompt:

proc.stdin.write(usrFileName + '\n\n')

Note : PowerShell's stdout output will also include the prompt message and the response submitted, so you need to account for that when you parse the output; specifically, stdout output will include the following:
Please enter a file name to save the report: 10Sep2020--7UP-A-325 (for instance), Press Enter to exit: , plus an extra empty line, because the exit prompt's Read-Host statement's output isn't captured in a variable and is therefore implicitly output.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM