# -*- coding: utf-8 -*- r'''检查 Inno Setup 的 .iss 里有没有会害编译失败的写法。 踩过的三个坑,都是 Inno 的 [Code] 解析器**连注释内容也处理**: 1. 注释里写方括号区段名 { 规范化,后面 [Run] 阶段用得到 } 报 "无效的区段标记",编译直接失败。踩了两次。 2. 注释里写花括号常量 { 不带 --keep-dir 的话会 rmdir 删 {app} } Inno 会把 {app} 展开,展开后花括号配不上 -> 报 "Syntax error",编译失败。踩了一次。 3. 注释里写 {param:XXX|} Inno 会展开它,参数没传就展开成空,同样破坏括号配对。 所以规则:**[Code] 段落里,注释内容不能出现 [Section] 或 {常量}。** ⚠ 判断"是不是注释"必须跳过字符串字面量: ExpandConstant('{app}\x') <- 这里的 { 在字符串里,不是注释 { 这是注释 } <- 这里的 { 才是注释 ''' from __future__ import annotations import re import sys from pathlib import Path ISS = (Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote") / "installer" / "ykxmz.iss") SECTIONS = { "Setup", "Types", "Components", "Tasks", "Dirs", "Files", "Icons", "Ini", "InstallDelete", "Languages", "Messages", "CustomMessages", "Registry", "Run", "UninstallRun", "UninstallDelete", "Code", } def scan_comment_text(line: str, in_comment: bool): """返回 (这一行注释里的文字, 扫完后的 in_comment)。 关键:字符串字面量里的 { } 不算注释。 """ out = [] cursor = 0 in_string = False length = len(line) while cursor < length: ch = line[cursor] if in_string: if ch == "'": # Pascal 用 '' 表示一个单引号 if cursor + 1 < length and line[cursor + 1] == "'": cursor += 2 continue in_string = False cursor += 1 continue if not in_comment: if ch == "'": in_string = True elif ch == "{": in_comment = True cursor += 1 continue # 在注释里 if ch == "}": in_comment = False cursor += 1 continue out.append(ch) cursor += 1 return "".join(out), in_comment def main() -> int: if not ISS.is_file(): print(" 找不到 %s" % ISS) return 1 lines = ISS.read_text(encoding="utf-8").splitlines() code_start = None for index, line in enumerate(lines): if line.strip() == "[Code]": code_start = index break if code_start is None: print(" 没有 [Code] 段落,跳过") return 0 problems = [] in_comment = False for index in range(code_start, len(lines)): line = lines[index] comment_text, in_comment = scan_comment_text(line, in_comment) if not comment_text: continue # 只有**行首**的 [Section] 才会被 Inno 当成区段标记。 # 行中间的("交给 Run 段用...")不影响 —— 实测编译能过。 m = re.match(r"\s*\[([A-Za-z][A-Za-z0-9]*)\]", comment_text) if m and m.group(1) in SECTIONS: problems.append((index + 1, "注释**行首**有区段名 [%s]" % m.group(1), line.strip())) # 花括号常量:注释里出现就会被展开 for match in re.finditer( r"\{[A-Za-z][A-Za-z0-9]*(?:[:|][^}]*)?\}", comment_text): problems.append((index + 1, "注释里有会展开的常量 %s" % match.group(0), line.strip())) # 真区段必须顶格 for index, line in enumerate(lines): if re.match(r"^\s+\[[A-Za-z]+\]\s*$", line): problems.append((index + 1, "区段名前面有空格", line.strip())) if problems: print(" 发现 %d 个会让编译失败的问题:" % len(problems)) for lineno, why, text in problems: print(" 行 %d: %s" % (lineno, why)) print(" %s" % text[:74]) return 1 print(" [Code] 段落里没有违规写法 ✓") return 0 if __name__ == "__main__": sys.exit(main())