检测脚本从命令提示符启动或在Windows上“双击”

时间:2009-02-17 21:20:25

标签: python windows

是否可以检测Python脚本是从命令提示符启动还是用户“双击”Windows上的文件浏览器中的.py文件?

5 个答案:

答案 0 :(得分:8)

如果从命令行运行,则会定义一个额外的环境变量'PROMPT'。

如果从资源管理器中单击此脚本将暂停,如果从命令行运行,则不会暂停:

import os

print 'Hello, world!'

if not 'PROMPT' in os.environ:
    raw_input()

使用Python 2.7在Windows 7上测试

答案 1 :(得分:3)

命令提示符启动脚本有一个名为cmd.exe的父进程(或者一个不存在的进程,以防控制台同时关闭)。

doubleclick-started脚本应该有一个名为explorer.exe的父进程。

答案 2 :(得分:3)

以下是如何获取当前运行脚本的父进程ID和名称的示例。正如Tomalak所建议的那样,这可用于检测脚本是从命令提示符启动还是双击资源管理器。

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()

从命令提示符运行时,输出:

  

此PID:148。父PID:4660,父进程名称:cmd

通过在资源管理器中双击启动时,输出:

  

此PID:1896。父PID:3788,父进程名称:资源管理器

答案 3 :(得分:2)

好问题。您可以做的一件事是在Windows中创建脚本的快捷方式,并传递参数(使用快捷方式的Target属性),表示通过双击(在本例中为快捷方式)启动脚本。

答案 4 :(得分:0)

我把这个小函数(pybyebye())放在我的一些程序中的return语句之前。我已经在台式机和笔记本电脑上在Windows 10下进行了测试,它可以实现我想要的功能,即只有在文件资源管理器中双击程序启动程序时,它才会暂停等待用户输入。这可以防止临时命令窗口在用户这样说之前消失。在Linux下,它什么都不做。反正没有坏处!同样在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