我正在寻找一种方法来确定我写的一个由PyInstaller打包的脚本是自己运行的唯一副本 - 这样如果它已经发现它已经打开就可以退出。
我还希望实现一个参数来杀死所有当前运行的.exe版本。通过与.exe关联的简单PID列表逐个杀死它们不是一个选项,因为我可能会在完成之前意外杀死我自己的进程。
如果我只能使用win32 API,那将是最好的,因为这个脚本有时被服务调用,因此对许多subprocess.Popen
调用不友好。我不想要通过UAC欺骗。但是,有时.exe调度程序或用户登陆程序会调用.exe。
我当前的查找过程版本使用win32pdh。我不确定将此归因于何处,尽管它与第一个示例非常接近:http://www.programcreek.com/python/example/51184/win32pdh.OpenQuery
def get_win_processes():
win32pdh.EnumObjects(None, None, win32pdh.PERF_DETAIL_WIZARD)
junk, instances = win32pdh.EnumObjectItems(None,None,'Process', win32pdh.PERF_DETAIL_WIZARD)
proc_dict = {}
for instance in instances:
if proc_dict.has_key(instance):
proc_dict[instance] = proc_dict[instance] + 1
else:
proc_dict[instance]=0
proc_ids = []
for instance, max_instances in proc_dict.items():
for inum in xrange(max_instances+1):
hq = win32pdh.OpenQuery() # initializes the query handle
try:
path = win32pdh.MakeCounterPath( (None, 'Process', instance, None, inum, 'ID Process') )
counter_handle=win32pdh.AddCounter(hq, path) #convert counter path to counter handle
try:
win32pdh.CollectQueryData(hq) #collects data for the counter
type, val = win32pdh.GetFormattedCounterValue(counter_handle, win32pdh.PDH_FMT_LONG)
proc_ids.append((instance, val))
except win32pdh.error, e:
pass
win32pdh.RemoveCounter(counter_handle)
except win32pdh.error, e:
pass
win32pdh.CloseQuery(hq)
return proc_ids
但是,这会返回两个进程,其中一个是PyInstaller的监护进程,另一个是程序的实际实例。此外,它并不表明哪一个是当前正在运行的监护人或孩子。
exe的示例输出是' wcdo.exe'并且有两个副本运行:
(u'wcdo', 11700)
(u'wcdo', 8748)
(u'wcdo', 4152)
(u'wcdo', 9308)
谢谢!
答案 0 :(得分:1)
您可以查询wmic并检查哪些应用程序已连接...
wcdo.exe --scheduled
下面:
使用PHD似乎是开销,在Windows上识别进程很慢且很不灵活。
致电' wmic'通过子进程和解析输出完成几行。 另外还有一个格式标志,如何显示wmic输出(csv,xml,...)
顺便说一下。您可以尝试使用py2exe创建您的exe,它不使用包装器应用程序。
不确定是否相关,以确定应用程序的启动方式。但是,您可以向Windows计划程序添加一个特殊的命令行参数以运行RemoteWebDriver
。