python - Opdag script start op fra kommandoprompt eller 'dobbeltklik' på Windows

Indlæg af Hanne Mølgaard Plasc

Problem



Er det muligt at opdage, om et Python-script blev startet fra kommandoprompten eller af en bruger 'dobbeltklik' på en .py-fil i filutforskeren på Windows?

Bedste reference


Hvis der køres fra kommandolinjen er der defineret en ekstra miljøvariabel 'PROMPT'.


Dette script vil pause, hvis det klikkes fra exploreren og ikke stoppe hvis det løber fra kommandolinjen:


import os

print 'Hello, world!'

if not 'PROMPT' in os.environ:
    raw\_input()


Testet på Windows 7 med Python 2.7

Andre referencer 1


Kommandoprompten startet script har en overordnet proces kaldet cmd.exe (eller en ikke-eksisterende proces, hvis konsollen er lukket i mellemtiden).


Doubleclick-start scriptet skal have en forældersproces med navnet explorer.exe.

Andre referencer 2


Her er et eksempel på, hvordan man får forældelsesproces-id og navn på det aktuelle kørende script. Som foreslået af Tomalak kan dette bruges til at opdage, om scriptet blev startet fra kommandoprompten eller ved at dobbeltklikke i 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()


Når du løber fra kommandoprompten, følger disse udgange:



  Dette PID: 148. Forældre PID: 4660, Parent procesnavn: cmd



Når du starter med at dobbeltklikke i udforskeren, er disse udgange:



  Dette PID: 1896. Forældre PID: 3788, Forældre proces navn: explorer


Andre referencer 3


Godt spørgsmål. Én ting du kan gøre er at oprette en genvej til scriptet i Windows, og videregive argumenter (ved hjælp af genvejens Target-egenskab), der ville angive scriptet, blev lanceret ved at dobbeltklikke (i dette tilfælde en genvej).

Andre referencer 4


Jeg sætter denne lille funktion (pybyebye ()) lige før returopgørelsen i nogle af mine programmer. Jeg har testet det under Windows 10 på min desktop og laptop, og det gør hvad jeg vil, dvs. det pauser, venter kun brugerindgang, når programmet er startet, ved at dobbeltklikke på programmet i File Explorer. Dette forhindrer det midlertidige kommandovindue fra at forsvinde, før brugeren siger det. Under Linux gør det ingenting. Ingen skade alligevel! Ligeledes på en 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