转载自我的个人博客
《Posts: 用 Python 设置 Windows 文件默认打开程序》
如有什么疑问可在文章下方评论
前言
本人为班里任命的电教委员(苦差事),因班里的教学需求,要在特定的某天切换使用某个播放器。
本人就想通过 Python 自动化设置默认 MP4 打开程序,然后就在请教 deepseek 等助手后,运行其生成的代码。随后就被各种奇怪的报错给卡死了。无奈之下便上 Github 看看有没有相关的代码。
万幸的是,我真的在 Github 上找到个用 Python 写的 文件默认大师 软件,感谢原作者。
我便阅读这代码,并提取了其中设置默认程序的核心代码。
代码讲解
这段代码是一个用于 Windows 系统设置文件默认打开程序的 Python 工具。它通过命令行和注册表两种方式修改关联,适用于 Windows 7/10/11。
核心功能
- 设置默认程序:通过
set_default_app()函数指定文件扩展名与对应的应用程序路径,可自动配置系统关联。 - 兼容性处理:优先使用
assoc和ftype命令行设置,同时直接修改注册表,并处理 Windows 10/11 的用户选择验证机制。 - 验证功能:
check_default_app()可检查当前默认程序是否为指定应用。
使用示例
set_default_app(".txt", "C:\\Windows\\notepad.exe")
if check_default_app(".txt", "C:\\Windows\\notepad.exe"):
print("设置成功")
完整代码
import winreg
import subprocess
import os
import time
import hashlib
def set_default_app_cmd(file_extension, app_path):
"""
使用 Windows 命令行工具设置默认打开程序,兼容 Windows 10/11
"""
try:
ext = file_extension if file_extension.startswith('.') else '.' + file_extension
prog_id = ext[1:].upper() + "File"
subprocess.run(f'assoc {ext}={prog_id}', shell=True, check=True)
subprocess.run(f'ftype {prog_id}="{app_path}" "%1"', shell=True, check=True)
return True, ""
except Exception as e:
return False, str(e)
def set_default_app(file_extension, app_path, icon_path=None):
"""
设置文件扩展名的默认打开程序
参数:
file_extension: 文件扩展名(如 ".txt" 或 "txt")
app_path: 应用程序完整路径
icon_path: 可选图标路径
返回: 无
"""
# 先用命令行设置
ok, msg = set_default_app_cmd(file_extension, app_path)
if not ok:
print(f"命令行设置失败: {msg}")
try:
# 确保扩展名格式正确
ext = file_extension if file_extension.startswith('.') else '.' + file_extension
# 创建或打开扩展名对应的注册表键
with winreg.CreateKey(winreg.HKEY_CLASSES_ROOT, ext) as key:
prog_id = winreg.QueryValue(key, None)
if not prog_id:
prog_id = ext[1:].upper() + "File"
winreg.SetValue(key, None, winreg.REG_SZ, prog_id)
# 设置打开命令
with winreg.CreateKey(winreg.HKEY_CLASSES_ROOT, f"{prog_id}\\shell\\open\\command") as cmd_key:
winreg.SetValue(cmd_key, None, winreg.REG_SZ, f"\"{app_path}\" \"%1\"")
# 处理用户选择(Windows 10/11 需要)
user_choice_path = f"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\{ext}\\"
try:
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, user_choice_path, 0, winreg.KEY_ALL_ACCESS) as key:
winreg.DeleteKey(key, "UserChoice")
except WindowsError:
pass
# 生成用户选择哈希(Windows 10/11 验证机制)
try:
user_sid = os.getlogin()
except Exception:
user_sid = "unknown"
timestamp = int(time.time())
hash_input = f"{prog_id}{user_sid}{timestamp}".encode('utf-16le')
hash_value = hashlib.sha256(hash_input).hexdigest()
with winreg.CreateKey(winreg.HKEY_CURRENT_USER, user_choice_path + "UserChoice") as key:
winreg.SetValueEx(key, "ProgId", 0, winreg.REG_SZ, prog_id)
winreg.SetValueEx(key, "Hash", 0, winreg.REG_SZ, hash_value)
print(f"成功设置 {ext} 的默认打开程序为: {app_path}")
except Exception as e:
print(f"设置默认程序失败: {e}")
def check_default_app(file_extension, app_path):
"""
检查当前扩展名的默认打开程序是否为指定程序
参数:
file_extension: 文件扩展名
app_path: 应用程序路径
返回: True/False
"""
ext = file_extension if file_extension.startswith('.') else '.' + file_extension
try:
output = subprocess.check_output(f"assoc {ext}", shell=True, encoding="gbk", errors="ignore")
if "=" not in output:
return False
prog_id = output.strip().split("=")[-1]
output2 = subprocess.check_output(f"ftype {prog_id}", shell=True, encoding="gbk", errors="ignore")
if app_path.lower() in output2.lower():
return True
except Exception:
pass
return False
# 使用示例
if __name__ == "__main__":
# 示例1:设置.txt文件用记事本打开
set_default_app(".txt", "C:\\Windows\\notepad.exe")
# 示例2:设置.jpg文件用照片查看器打开
set_default_app("jpg", "C:\\Windows\\System32\\rundll32.exe", "C:\\Windows\\System32\\photo_viewer.dll")
# 检查设置是否成功
if check_default_app(".txt", "C:\\Windows\\notepad.exe"):
print("设置成功!")
else:
print("设置失败!")