抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

前言

本人为班里任命的电教委员(苦差事),因班里的教学需求,要在特定的某天切换使用某个播放器。

本人就想通过 Python 自动化设置默认 MP4 打开程序,然后就在请教 deepseek 等助手后,运行其生成的代码。随后就被各种奇怪的报错给卡死了。无奈之下便上 Github 看看有没有相关的代码。

万幸的是,我真的在 Github 上找到个用 Python 写的 文件默认大师 软件,感谢原作者。

https://github.com/3089464667/default-app

我便阅读这代码,并提取了其中设置默认程序的核心代码。

代码讲解

这段代码是一个用于 Windows 系统设置文件默认打开程序的 Python 工具。它通过命令行和注册表两种方式修改关联,适用于 Windows 7/10/11。

核心功能

  • 设置默认程序:通过 set_default_app() 函数指定文件扩展名与对应的应用程序路径,可自动配置系统关联。
  • 兼容性处理:优先使用 assocftype 命令行设置,同时直接修改注册表,并处理 Windows 10/11 的用户选择验证机制。
  • 验证功能check_default_app() 可检查当前默认程序是否为指定应用。

使用示例

1
2
3
set_default_app(".txt", "C:\\Windows\\notepad.exe")
if check_default_app(".txt", "C:\\Windows\\notepad.exe"):
print("设置成功")

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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("设置失败!")

评论