如何用Popen无shell=True启动OneNote快捷方式并获取正确PID终止进程
解决OneNote快捷方式启动后PID不一致的问题
嘿,我太懂你踩的这个坑了!当你用shell=True启动.url快捷方式时,拿到的PID根本不是OneNote的——而是系统shell(比如cmd.exe)的进程ID。shell只是帮你启动了OneNote,它自己会先跑起来,所以你杀掉shell的PID对OneNote完全没用,这就是为啥任务管理器里的PID和你拿到的不一样。
下面给你两种不用shell=True的解决方案,都能拿到OneNote的真实PID:
方法一:直接启动OneNote可执行文件(最靠谱)
跳过快捷方式,直接启动OneNote的.exe程序,这样subprocess.Popen返回的PID就是OneNote本身的,杀起来一一个准。
首先找到你电脑上OneNote的安装路径,默认路径大概是C:\Program Files\Microsoft Office\root\Office16\ONENOTE.EXE(Office 365/2019/2016是Office16,2013是Office15)。然后用下面的代码:
import subprocess import os # 切换到你的工作目录(如果需要加载特定笔记文件的话) os.chdir(r"E:\Anyagok\Programozás\Python\projekts\Én projektjeim") # 替换成你实际的OneNote可执行文件路径 onenote_exe = r"C:\Program Files\Microsoft Office\root\Office16\ONENOTE.EXE" # 如果要打开特定的OneNote文件,把文件路径作为第二个参数传进去 am = subprocess.Popen([onenote_exe, "你的笔记文件路径.one"]) # 现在am.pid就是OneNote的真实PID,直接杀就行 os.system(f"TASKKILL /F /PID {am.pid}")
方法二:解析.url快捷方式的目标路径
如果你一定要用.url快捷方式,那得先把快捷方式里的目标地址读出来,再直接启动那个目标。.url本质是文本文件,里面会有一行URL=xxx记录了目标路径。
用下面的代码解析并启动:
import subprocess import os import urllib.parse import shlex def get_shortcut_target(url_file): """解析.url文件,提取目标路径""" with open(url_file, 'r', encoding='utf-8') as f: for line in f: line = line.strip() if line.startswith('URL='): target = line[4:] # 处理file:///开头的本地路径 if target.startswith('file:///'): # 解码URL编码的字符(比如%20对应空格) target = urllib.parse.unquote(target[8:]) # 把斜杠换成Windows的反斜杠 target = target.replace('/', '\\') return target return None # 切换工作目录 os.chdir(r"E:\Anyagok\Programozás\Python\projekts\Én projektjeim") # 解析.url文件的目标 target_path = get_shortcut_target("cold_turkey.url") if target_path: # 把路径拆分成命令参数(处理带空格的路径) cmd_args = shlex.split(target_path) # 启动目标程序,不用shell=True am = subprocess.Popen(cmd_args) # 杀掉真实PID os.system(f"TASKKILL /F /PID {am.pid}") else: print("抱歉,没能解析出.url文件的目标路径")
小提示
- 如果你的
.url是指向OneNote笔记的链接(比如onenote:///...),那方法二会拿到这个链接,你需要把它作为参数传给OneNote的.exe程序,就像方法一里那样。 - 永远避免在不需要的时候用
shell=True,不仅会导致PID问题,还存在安全风险。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

