20

I have a python application that has a shell that needs to do some setup based on whether the shell it's running in is the Windows Command Prompt (cmd) or Powershell.

I haven't been able to figure out how to detect if the application is running in powershell or cmd.

From my searches on stackoverflow and Google, it seems the only way to do this is to use psutil to find the name of the parent process.

Is there a nicer way?

12
  • 1
    In that case, you can try a command that you know will only work in Powershell and check for an error. Otherwise it is really a Python issue not a powershell issue. You could query the Win32_Process class in python for your process. Then get the PID of the parent process and query for that process to see what it is. Commented May 23, 2016 at 15:32
  • 1
    How about making the shell independent of launch shell? Add a menu that provides two shells so the user can decide whether cmd or psh is more suitable. Commented May 23, 2016 at 16:00
  • 1
    I think psutil is your best option. Your Python script is run by the Python interpreter regardless of whether it was launched from a PowerShell or CMD process. Commented May 23, 2016 at 16:30
  • 4
    Your script is not running in either cmd.exe or powershell.exe. If it's executed by python.exe, then it's attached to a console window that's implemented by conhost.exe and has nothing to do with either cmd.exe or powershell.exe. Python's os.system uses cmd.exe. The subprocess module uses WinAPI CreateProcess, which creates a process using a PE executable (i.e. .EXE, but the extension doesn't matter) or starts cmd.exe when passed the path to a .BAT or .CMD file. The shell=True option of subprocess uses the %ComSpec% shell, which is usually cmd.exe. Commented May 23, 2016 at 21:02
  • 5
    All existing answers to this question are functionally useless. Moreover, the OP failed to detail how they leveraged the third-party psutil package in their question edits. Instead, see this genuinely useful answer to a similar question elsewhere. tl;dr: is_powershell = bool(re.fullmatch('pwsh|pwsh.exe|powershell.exe', psutil.Process(os.getppid()).name())). Commented Jun 11, 2019 at 0:54

3 Answers 3

3

@Matt A. is right. Use psutil and os package to get the parent process id and the name.

parent_pid = os.getppid()
print(psutil.Process(parent_pid).name())
Sign up to request clarification or add additional context in comments.

1 Comment

This fails if you run from iPython
1

The following snippet finds md5sum on args.file in bash/powershell, I usually use the first command to check what we are running in, so I can use it later on, using shell=True in subprocess is not very portable.

import os, subprocess
running_shell = None
mycheck='/usr/bin/md5sum'   # full path is needed
if not os.path.isfile(mycheck):
    try:
        file_md5sum = subprocess.check_output("powershell.exe Get-FileHash -Algorithm MD5 {} | Select -expand Hash".format(args.file).split())
    except FileNotFoundError as e:
        log.fatal("unable to generate md5sum")
        sys.exit(-1)
    file_md5sum = file_md5sum.lower()
    running_shell = 'powershell'
else:
    file_md5sum = subprocess.check_output([mycheck, args.file])
    running_shell = 'bash'

Comments

-1

Based on this post, you should be able to run this CMD/PS command through the subprocess module in your Python script:

subprocess.call("(dir 2>&1 *`|echo CMD);&<# rem #>echo PowerShell", shell=True)

This will output CMD if you're in CMD, and PowerShell if you're in PS.

2 Comments

call and Popen apparently invoke cmd.exe for execution, rather than the parent shell. Thus even if python is started from within PowerShell, this command will return CMD as the answer.
I wonder if there is a way to set what kind of shell is invoked by Python?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.