1

I am using os.Popen to open a new command prompt window and run a process. How can I read the text within that command prompt. Please help.

import os

def OpenServers():
        os.chdir(coreServerFullPath)
        process=os.popen("start cmd /K CoreServer.exe -c -s").read()
        print(process) #Prints nothing

This is the output text that's shown in the command prompt which I want to print.

Output text

EDIT:

I also tried this way, but no luck

 from subprocess import Popen, PIPE, STDOUT
 def OpenServers():
        os.chdir(coreServerFullPath)
        result = subprocess.Popen(['start', 'cmd', '/k', 'CoreServer.exe -c -s'], shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
        time.sleep(4)
        output=result.stdout.read()
        print(output) #Prints nothing

New Edit:

I tried something like this. Problem is, it makes me run 2 times. The first time when i run, the console is blank. The second time when I run it works but gives me an error because I can only open one instance of the server,.

def Test1():
        os.chdir(coreServerFullPath)
        result = subprocess.check_output(['CoreServer.exe', '-c', '-s'])
        print(result.stdout)

Here is the full code that I was trying. I can run CoreServer only as an admin so doing it like this

import os
import sys
import subprocess
from subprocess import Popen, CREATE_NEW_CONSOLE
from subprocess import Popen, PIPE, STDOUT
import time
import ctypes, sys

#The command prompts must be opened as administrators. So need to run the python script with elebvated permissions. Or else it won't work
def is_admin():
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False

if is_admin():
    #The program can only run with elevated admin previlages.
    
    #Get the directory where the file is residing.
    currentDirectory=os.path.dirname(os.path.abspath(__file__))
    coreServerFullPath=os.path.join(currentDirectory,"Core\CoreServer\Server\CoreServer/bin\Debug")
    isExistCoreServer=os.path.exists(coreServerFullPath)

    echoServerFullPath=os.path.join(currentDirectory,"Echo\Server\EchoServer/bin\Debug")
    isExistEchoServer=os.path.exists(echoServerFullPath)

    #For now this is the MSBuild.exe path. Later we can get this MSBuild.exe as a standalone and change the path.
    msBuildPath="C:\Program Files (x86)\Microsoft Visual Studio/2019\Professional\MSBuild\Current\Bin/amd64"
    pathOfCorecsProjFile=os.path.join(currentDirectory,"Core\CoreServer\Server\CoreServer\CoreServer.csproj")
    pathOfEchocsProjFile=os.path.join(currentDirectory,"Echo\Server\EchoServer\EchoServer.csproj")


    def OpenServers():
        os.chdir(coreServerFullPath)
        #os.system("start /wait cmd /c {command}")
        command_line = [coreServerFullPath, '-c', '-s']
        result = subprocess.Popen(['start', 'cmd', '/k', 'CoreServer.exe -c -s'], shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
        time.sleep(4)
        output=result.stdout.read()
        print(output)
        #process=os.popen("start cmd /K CoreServer.exe -c -s").read()
        #print(process)

    def Test():
        os.chdir(coreServerFullPath)
        output = subprocess.check_output(['CoreServer.exe', '-c', '-s'],shell=True)
        time.sleep(4)
        print(output)
    
    def Test1():
        os.chdir(coreServerFullPath)
        result = subprocess.check_output(['CoreServer.exe', '-c', '-s'])
        print(result.stdout)


    if(not isExistCoreServer):
        if(os.path.isfile(pathOfCorecsProjFile)):
            os.chdir(msBuildPath)
            startCommand="start cmd /c"
            command="MSBuild.exe "+pathOfCorecsProjFile+" /t:build /p:configuration=Debug"
            #os.system(startCommand+command)
            cmd=subprocess.Popen(startCommand+command)

    if(not isExistEchoServer):
        if(os.path.isfile(pathOfEchocsProjFile)):
            os.chdir(msBuildPath)
            startCommand="start cmd /c"
            command="MSBuild.exe "+pathOfEchocsProjFile+" /t:build /p:configuration=Debug"
            os.system(startCommand+command)

    if(isExistCoreServer and isExistEchoServer):
        Test1()

else:
    # Re-run the program with admin rights
    ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
Constantin Hong
  • 701
  • 1
  • 2
  • 16
nikhil
  • 1,578
  • 3
  • 23
  • 52
  • Why are you opening a new command prompt window for this? – user2357112 Feb 24 '23 at 09:21
  • You're not reading `CoreServer.exe`'s output. You're reading `start`'s output. – user2357112 Feb 24 '23 at 09:22
  • Can you help me how can I read the CoreServer.exe's output? – nikhil Feb 24 '23 at 09:26
  • I have 2 processes that I want to run on 2 different command prompts. – nikhil Feb 24 '23 at 09:26
  • Okay, but why are you opening new command prompts for these processes at all? Do you think you *need* to do that to run them concurrently? You don't. – user2357112 Feb 24 '23 at 09:28
  • Yes I want to run them concurrently. First I want to run one process and lets say after 3 seconds I want to run the other process. First i need say os.chdir(coreServerFullPath) and run process 1 and then I need to do os.chdir(EchoServerFullPath) and run process 2. If I can do it without opening a new command prompt window also great. Can you help me? – nikhil Feb 24 '23 at 09:31
  • Have been trying something like this https://stackoverflow.com/questions/75552575/read-command-prompt-output-in-new-window-in-python/75553139#75553139 But the problem is it makes me press the run button 2 times – nikhil Feb 24 '23 at 09:33
  • Please [don’t post images of code, error messages, or other textual data.](https://meta.stackoverflow.com/questions/303812/discourage-screenshots-of-code-and-or-errors) – tripleee Feb 24 '23 at 09:36
  • It looks like you are simply trying to reinvent `subprocess.check_output` – tripleee Feb 24 '23 at 09:37
  • Please see my new edit.. – nikhil Feb 24 '23 at 09:39
  • This sounds like you need to explain what `CoreServer.exe` does in some more detail. It sounds like it starts a service, and the output you get comes from somewhere else, not from the server process ...? – tripleee Feb 24 '23 at 09:42
  • I open The CoreServer.exe and pass in arguments like -c and -s. The CoreServer.exe is present within some location like "C:\Users\nandukurusai\Desktop\SourceCode\Core\CoreServer\Server\CoreServer\bin\Debug" The python script is located at C:\Users\nandukurusai\Desktop\SourceCode. So in the current directory i go to the folder where that CoreServer.exe is present and start that service. Its a standalone service., – nikhil Feb 24 '23 at 09:48
  • Yes I tried this result = subprocess.Popen(['start', 'cmd', '/k', 'CoreServer.exe -c -s'], shell=True, capture_output=True, text=True) It opens the command prompt and it immediately dissapears – nikhil Feb 24 '23 at 09:58

1 Answers1

1

For this type of situations the best way to get the output is to dump it to a log file and then read the output from the file. (Is better to create the log file before running the program)

Here you have a simple example:

result = subprocess.Popen('start cmd /k CoreServer.exe -c -s >> log.log 2>&1', shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
time.sleep(4)
with open('log.log', 'r') as logg:
    print(logg.read())

This should print the desired output. Hope it works for you.

kithuto
  • 455
  • 2
  • 11
  • Hi @Kithuto I created a log.log file. But it doesn't seem to be writing to the log file everytime I run. – nikhil Feb 27 '23 at 06:17
  • Make sure the log file is created before you run the code and check what subprocess has been created. Make sure that the subprocess has been executed successfully. You can make a method to wait for the process to output and then read the log file (output an error when timeout or max tries reached). You can check if the server is fully running checking if the string: "Waiting to SSL client to connect..." exists in the output and return the output then. When time out or max tries reached you can just kill the process and try again (specify a max number of times). – kithuto Feb 28 '23 at 13:30
  • Thank you so much this one helped me. https://stackoverflow.com/questions/75577379/python-popen-writing-command-prompt-output-to-logfile?noredirect=1#comment133338788_75577379. And like you mentioned I wrote an other script to create the log before running the processes. – nikhil Mar 01 '23 at 13:04