TD默认版本管理器¶
- TD默认版本管理器.py
- 电脑同时安装了多个TD版本的情况
- 多TD版本在同一目录下面,比如都在默认
C:\Anlogic\ - 在D盘或者其它盘则手动改下py脚本前面几行的目录
- 单文件工具:管理一台机器上的多个安路 TD 版本。交互式选版本打开
.al工程 - 一键把所选版本设为「双击默认」和「脚本默认」。纯 Python 标准库实现,无第三方依赖
- 无需管理员权限(所有操作都在当前用户 HKCU 下)
1. 环境要求¶
| 项目 | 要求 |
|---|---|
| 操作系统 | Windows 10 / 11(Win10 22H2 实测通过) |
| Python | 3.8 及以上,纯标准库 |
| TD 安装位置 | C:\Anlogic\ 下任意目录,含 bin\td.exe 即会被自动发现 |
| 权限 | 普通用户权限即可 |
2. 快速开始¶
三种启动方式任选:
1. 双击 td_pick.py (需 .py 关联到 Python,官方安装包默认如此)
2. python td_pick.py 工程.al (命令行带工程参数)
3. 把 .al 文件拖到 td_pick.py 上 (同样需要 .py 关联带 %* 参数)
启动后的界面:
double-click default : TD_Release_2026.2.210.850 ← 当前双击 .al 用哪个版本
script default : TD_Release_2026.2.210.850 ← 当前裸调 td 命令解析到哪个版本
open : demo.al
[1] TD_Release_2026.2.210.850
[2] TD_Engineer_2027.1.212.603
[3] TD_4.6.8_CPLD_Release_96.021
select TD [1-3, Enter=1, q=quit]: 2
save TD_Engineer_2027.1.212.603 as default? [y = double-click + script, Enter = this time only]: y
double-click default -> TD_Engineer_2027.1.212.603
script default -> TD_Engineer_2027.1.212.603 (new terminals)
launching C:\Anlogic\TD_Engineer_2027.1.212.603\bin\td.exe ...
按键说明:
| 输入 | 行为 |
|---|---|
| 数字 + 回车 | 用对应版本启动(工程随参数打开) |
| 直接回车 | 用列表第一项启动(目录名降序排列,通常是最新的 Release 版) |
y(保存提示时) |
所选版本设为新默认:写 .al 双击关联 + 用户 PATH 置顶,然后启动 |
| 直接回车(保存提示时) | 只启动这一次,不改变任何默认 |
q |
退出,不启动 |
版本列表是启动时实时扫描 C:\Anlogic 生成的——新装一个 TD 后无需改脚本,下次打开自动出现。
3. 「保存默认」到底改了什么¶
按 y 保存时,脚本做两件事,都只动当前用户的注册表:
- 双击默认:重写
HKCU\...\FileExts\.al\UserChoice(ProgId + Hash)。
Windows 对该键有防篡改哈希校验(输入 = 扩展名 + 用户 SID + ProgId + 键写入时刻 +
shell32 内固定串),脚本内置了这套算法(移植自 PS-SFTA / kolbi.cz 的公开逆向结果),
现算现写,因此写入的哈希合法、不会被系统重置。遇到系统对该键的「Deny SetValue」
ACL 保护时,自动走「删键重建」路径绕过。 - 脚本默认:把所选版本的
bin目录移到用户 PATH 最前并广播刷新——
新开的终端生效,已打开的窗口不变。
4. 子命令¶
不带参数运行 = 交互菜单;带子命令运行 = 非交互工具模式:
python td_pick.py save # 把当前 .al 关联存为快照(ProgId+哈希+键时间戳)
python td_pick.py apply # 把快照原样写回(含键时间戳回写),恢复当时的默认
python td_pick.py status # 显示当前关联 / 脚本默认 / 与快照的差异
python td_pick.py verify # 哈希算法自校验:用快照对照,逐字节验证移植正确性
python td_pick.py set-progid <ProgId> # 把 .al 默认指向任意 ProgId(高级用法)
python td_pick.py install-picker # 让「双击 .al」直接弹出本选择器(而不是直接开 TD)
快照保存在脚本同目录的 td_pick.json,仅在本机、本账户、当前 Windows 版本上有效
(SID 和系统串都参与哈希),换机器请重新 save。
5. 典型场景¶
- 临时用旧版开一个工程:拖
.al到脚本上 → 选数字 → 保存提示直接回车。 - 项目切换,日常默认换版本:打开选择器 → 选号 →
y。双击和脚本默认一起切过去。 - 装了新版本 TD:什么都不用做,列表自动出现新版本;想设为默认就在选择器里选它存一次。
- 想让双击 .al 每次弹菜单:
python td_pick.py install-picker;
想恢复"双击直开版本":python td_pick.py apply(回到快照状态)或再保存一次。 - 右键打开方式:注册过的 "TD Version Picker" 会出现在
.al右键 → 打开方式菜单里。
6. 回退与安全¶
- 所有修改都在 HKCU(用户级),不碰系统级设置,不需要管理员。
- 三条回退路径,任选:
apply恢复快照;set-progid指回任意版本;
或 Windows 官方通道——右键.al→ 打开方式 → 选择其他应用 → 勾"始终"。 - 脚本无网络行为、无外部依赖,全部源码可见可审计。
7. 常见问题¶
双击 td_pick.py 打开的是编辑器(VS Code 之类)?
.py 没有关联到 Python。右键 → 打开方式 → 选择其他应用 → Python → 勾"始终"。
标准 CPython 安装(含 py 启动器)默认已正确关联。
按 y 保存后,双击 .al 还是旧版本?
资源管理器有关联缓存,通常即时生效;个别情况重启 explorer.exe 或注销一次。
若 Windows 弹"应用默认设置已重置"提示,说明哈希被判定无效(极少见,例如系统大更新
后 shell32 串变化)——重新打开选择器保存一次即可。
保存了脚本默认,命令行 td 还是旧版本?
PATH 修改只对新进程生效:新开一个 cmd/PowerShell 再试。
别的机器能用我的 td_pick.json 快照吗?
不能。快照绑定了用户 SID 和 Windows 版本,新机器上先设好默认再 save 一份自己的。
杀毒软件报警?
本工具的行为(改文件关联、改 PATH、调用 NtSetInformationKey 回写注册表键时间戳)
与关联劫持类恶意软件特征相似,可能被启发式引擎标记。源码全部可见,可自行审计后加白。
为什么不用管理员就能改受保护的注册表键?
UserChoice 键的 ACL 只对"写值"设了拒绝,未限制删除;脚本删掉该键重建后,
新键继承父键的普通权限,即可写入(详见 kolbi.cz 对这套保护机制的逆向分析)。
8. 技术背景(选读)¶
- UserChoice 哈希五要素:扩展名、用户 SID、ProgId、键最后写入时刻(分钟粒度)、
shell32.dll 内的固定串。任何一项变化哈希即失效——因此"恢复快照"必须连键时间戳
一起恢复,脚本通过未公开但稳定的NtSetInformationKey(KeyWriteTimeInformation)实现。 - 算法出处(公开逆向):
- kolbi.cz: SetUserFTA: UserChoice Hash defeated
https://kolbi.cz/blog/2017/10/25/setuserfta-userchoice-hash-defeated-set-file-type-associations-per-user - PS-SFTA(PowerShell 实现,本脚本的移植参考)
https://github.com/DanysysTeam/PS-SFTA - Win10/11 较新补丁带有 UCPD 保护驱动,个别构建上第三方写入会被拦截;
本脚本在 Win10 22H2(19045,UCPD 启用状态)实测可用。若你的系统上写入被拒,
会看到明确报错,此时用第 6 节的官方通道回退/设置即可。