Detect script run from command line or double-click on Windows

Is it possible to determine whether the Python script was run from the command line or the user "double-click" the .py file in the file explorer on Windows?

+6
python windows
source share
5 answers

Here is an example of how to get the parent process id and name of the current script run. As suggested by Tomalak , this can be used to detect the start of a script from the command line or double-click in Explorer.

import win32pdh import os def getPIDInfo(): """ Return a dictionary with keys the PID of all running processes. The values are dictionaries with the following key-value pairs: - name: <Name of the process PID> - parent_id: <PID of this process parent> """ # get the names and occurences of all running process names items, instances = win32pdh.EnumObjectItems(None, None, 'Process', win32pdh.PERF_DETAIL_WIZARD) instance_dict = {} for instance in instances: instance_dict[instance] = instance_dict.get(instance, 0) + 1 # define the info to obtain counter_items = ['ID Process', 'Creating Process ID'] # output dict pid_dict = {} # loop over each program (multiple instances might be running) for instance, max_instances in instance_dict.items(): for inum in xrange(max_instances): # define the counters for the query hq = win32pdh.OpenQuery() hcs = {} for item in counter_items: path = win32pdh.MakeCounterPath((None,'Process',instance, None,inum,item)) hcs[item] = win32pdh.AddCounter(hq,path) win32pdh.CollectQueryData(hq) # store the values in a temporary dict hc_dict = {} for item, hc in hcs.items(): type,val=win32pdh.GetFormattedCounterValue(hc,win32pdh.PDH_FMT_LONG) hc_dict[item] = val win32pdh.RemoveCounter(hc) win32pdh.CloseQuery(hq) # obtain the pid and ppid of the current instance # and store it in the output dict pid, ppid = (hc_dict[item] for item in counter_items) pid_dict[pid] = {'name': instance, 'parent_id': ppid} return pid_dict def getParentInfo(pid): """ Returns a PID, Name tuple of the parent process for the argument pid process. """ pid_info = getPIDInfo() ppid = pid_info[pid]['parent_id'] return ppid, pid_info[ppid]['name'] if __name__ == "__main__": """ Print the current PID and information of the parent process. """ pid = os.getpid() ppid, ppname = getParentInfo(pid) print "This PID: %s. Parent PID: %s, Parent process name: %s" % (pid, ppid, ppname) dummy = raw_input() 

When launched from the command line, this produces:

This PID: 148. Parent PID: 4660, Parent Process Name: cmd

When launched by double-clicking in Explorer, the outputs:

This PID: 1896. Parent PID: 3788, Parent process name: explorer

+3
source share

When launched from the command line, there is an additional environment variable "PROMPT".

This script will be paused if you click it from Explorer, and not pause if it is launched from the command line:

 import os print 'Hello, world!' if not 'PROMPT' in os.environ: raw_input() 

Tested on Windows 7 with Python 2.7

+7
source share

The initial script command has a parent process called cmd.exe (or a nonexistent process if the console was closed on average).

In running the double-click script, there must be a parent process named explorer.exe .

+3
source share
Good question. One thing you can do is create a shortcut for the script on Windows and pass arguments (using the Shortcut Target property), indicating that the script was launched by double-clicking (in this case, the shortcut).
+2
source share

I put this little function (pybyebye ()) immediately before the return statement in some of my programs. I tested it under Windows 10 on my desktop and laptop and it does what I want, i.e. It suspends waiting for user input only when the program was launched by double-clicking on the program in Explorer. This prevents the command window from disappearing before the user says this. On Linux, it does nothing. No harm! Also on Mac.

 ## PYBYEBYE : def pybyebye (eprompt="PROMPT",efps="FPS_BROWSER_"): "nice exit in Windows according to program launch from: IDLE, command, clix." ## first examine environment (os & sys having been imported) : ui = None platform = sys.platform ## print("os =",platform) if not platform.lower().startswith("win"): return ui ## only relevant in windows fromidle = False launched = "Launched from" if sys.executable.endswith("pythonw.exe"): fromidle = True ## launched from within IDLE envkeys = sorted(os.environ) prompter = eprompt in envkeys browser = False for ek in envkeys: ## print(ek) if ek.startswith(efps): browser = True break ## next decide on launch context : if fromidle and not prompter: ## surely IDLE ## print(launched,"IDLE") pass ## screen won't disappear elif browser and not prompter: ## run with double click ## print(launched,"File Explorer") print("Press Enter to finish ....") ; ui=input() elif prompter and not fromidle: ## run from preexisting command window ## print(launched,"Command Window") pass ## screen won't disappear else: ## something funny going on, Mac or Linux ?? print("launch mode undetermined!") return ui 
0
source share

All Articles