跳转至

TD默认版本管理器

  • TD默认版本管理器.py
    1. 电脑同时安装了多个TD版本的情况
    2. 多TD版本在同一目录下面,比如都在默认C:\Anlogic\
    3. 在D盘或者其它盘则手动改下py脚本前面几行的目录
    4. 单文件工具:管理一台机器上的多个安路 TD 版本。交互式选版本打开 .al 工程
    5. 一键把所选版本设为「双击默认」和「脚本默认」。纯 Python 标准库实现,无第三方依赖
    6. 无需管理员权限(所有操作都在当前用户 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 保存时,脚本做两件事,都只动当前用户的注册表:

  1. 双击默认:重写 HKCU\...\FileExts\.al\UserChoice(ProgId + Hash)。
    Windows 对该键有防篡改哈希校验(输入 = 扩展名 + 用户 SID + ProgId + 键写入时刻 +
    shell32 内固定串),脚本内置了这套算法(移植自 PS-SFTA / kolbi.cz 的公开逆向结果),
    现算现写,因此写入的哈希合法、不会被系统重置。遇到系统对该键的「Deny SetValue」
    ACL 保护时,自动走「删键重建」路径绕过。
  2. 脚本默认:把所选版本的 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 节的官方通道回退/设置即可。