pkit pkit - 1 year ago 52
Python Question

Detect script start up from command prompt or "double click" on Windows

Is is possible to detect if a Python script was started from the command prompt or by a user "double clicking" a .py file in the file explorer on Windows?

Answer Source

Here is an example of how to obtain the parent process id and name of the current running script. As suggested by Tomalak this can be used to detect if the script was started from the command prompt or by double clicking 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)

            # store the values in a temporary dict
            hc_dict = {}
            for item, hc in hcs.items():
                hc_dict[item] = val

            # 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 run from the command prompt this outputs:

This PID: 148. Parent PID: 4660, Parent process name: cmd

When started by double clicking in explorer this outputs:

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