Returning subprocess STDOUT and STDERR output for PsExec execution in compiled app using windowed (noconsole) mode

252 Views Asked by At

I am trying to remotely execute a script using PsExec and return live output using subprocess.Popen within my Tkinter program. Everything workes fine using below code (without compiling my app using the --windowed parameter).

cmd = [Settings.psexec_loc, f"\\\\{target}", "-n", str(10), "-c", "-f", "-s", "-accepteula", "-nobanner", Settings.temp_cmd_loc]
process = subprocess.Popen(
    cmd,
    stdout=subprocess.PIPE,
    stderr=subprocess.STDOUT
)

while True:
    line = process.stdout.readline()
    if not line:
        break
    print(line.decode().rstrip())

When i tried removing the Tkinter startup cmd console window using the --windowed or --noconsole option when i compiled my program to .exe using pyinstaller, things started to break down unfortunately. I can only get to read STDERR and the first line of STDOUT, depending on combination of parameters i use.

I have tried several parameters for subprocess.Popen, including startup_info and creation_flags. It just doesnt seem to work. If stdin is set to subprocess.DEVNULL, and i run the app without compiling it, it outputs the same thing when i compile the app using the --windowed flag with stdin=None.

All commands within the cmd script are actually executed by PsExec. I tested this with msg * hello at the end of the script. Its just that subprocess only returns the first line of STDOUT.

I just want to process STDOUT and STDERR, and ignore STDIN. But i do not want any console windows visible anywhere. Can anyone provide me with some tips and tricks? Thanks in advance!

Anyway, i created this small program in my free time for a company i work for. If anyone is interested and willing to look into the source, this is the GitHub repo: https://github.com/vlreinier/CmdDeployer/blob/main/Progression.py (line 235-290)

EDIT: A temporary fix for hiding the CMD window during runtime is using the function below, and compiling without the --windowed flag. This will NOT however hide the console window during program startup.

def cmd_visibility(show=True):
    hWnd = ctypes.WinDLL('kernel32').GetConsoleWindow()
    if hWnd:
        ctypes.WinDLL('user32').ShowWindow(hWnd, int(show))
0

There are 0 best solutions below