{"id":"3f0b6864-7346-4f1f-81b1-5e7b4c87d35a","entityType":"agent","slug":"clawhub-virtualhotbar-pecmd-pro-max","name":"PECMD Pro Max","canonicalUrl":"https://www.xpersona.co/agent/clawhub-virtualhotbar-pecmd-pro-max","canonicalPath":"/agent/clawhub-virtualhotbar-pecmd-pro-max","generatedAt":"2026-10-11T17:42:15.239Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-11T15:26:58.742Z","emptyReason":null},"description":"PECMD2012 WinPE 脚本编程 — 轻量级 Windows GUI、系统工具、启动/初始化 脚本、自动化。适用于 .wcs/.wci/.wce 文件、磁盘分区、批处理转 PECMD、 系统信息收集、PE/预安装环境工具、PECMD 代码调试。 参考文件：references/commands-full.... Skill: PECMD Pro Max Owner: virtualhotbar Summary: PECMD2012 WinPE 脚本编程 — 轻量级 Windows GUI、系统工具、启动/初始化 脚本、自动化。适用于 .wcs/.wci/.wce 文件、磁盘分区、批处理转 PECMD、 系统信息收集、PE/预安装环境工具、PECMD 代码调试。 参考文件：references/commands-full.... Tags: automation:1.7.1, latest:1.7.1, pecmd:1.7.1, scripting:1.7.1, system-tools:1.7.1, windows:1.7.1, winpe:1.7.1 Version history: v1.7.1 | 2026-05-05T14:47:29.285Z | auto pecmd-pro-max 1.7.1 - Updated comma","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1K downloads reported by the source. Last updated 10/11/2026.","installCommand":"clawhub skill install s178gdhrbp1e18pdxs1t0eh4th83xjr3:pecmd-pro-max","sourceUrl":"https://clawhub.ai/virtualhotbar/pecmd-pro-max","homepage":"https://clawhub.ai/virtualhotbar/skills/pecmd-pro-max","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/virtualhotbar/pecmd-pro-max","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/virtualhotbar/skills/pecmd-pro-max","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":60,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"PECMD2012 WinPE 脚本编程 — 轻量级 Windows GUI、系统工具、启动/初始化 脚本、自动化。适用于 .wcs/.wci/.wce 文件、磁盘分区、批处理转 PECMD、 系统信息收集、PE/预安装环境工具、PECMD 代码调试。 参考文件：references/commands-full...."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-11T15:26:58.742Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T15:26:58.742Z","emptyReason":null},"stars":null,"forks":null,"downloads":1040,"packageName":null,"latestVersion":"1.7.1","tractionLabel":"1K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T15:26:58.648Z","emptyReason":null},"lastUpdatedAt":"2026-10-11T15:26:58.742Z","lastCrawledAt":"2026-10-11T15:26:58.648Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-12T15:26:58.648Z","lastVerifiedAt":null,"highlights":[{"version":"1.7.1","createdAt":"2026-05-05T14:47:29.285Z","changelog":"pecmd-pro-max 1.7.1 - Updated command and troubleshooting references for improved coverage and clarity. - Expanded and refined GUI scripting guides. - Enhanced troubleshooting instructions for common issues. - Improved documentation formatting for easier reading. - Fixed minor errors and outdated examples in reference files.","fileCount":13,"zipByteSize":135604},{"version":"1.7.0","createdAt":"2026-05-05T13:21:06.988Z","changelog":"pecmd-pro-max 1.7.0 - Documentation expanded and improved for all usage guides and reference files. - SKILL.md: Clarified variable precedence rules, command-line/script execution modes, and file extension support; added more examples. - Added section covering ENVI-env / SET-env for temporary override of ForceLocal. - Enhanced GUI, FIND, and CALL variants documentation (including menu alignment, memory function calls, and window flags). - Updated and corrected reference and troubleshooting guides for clarity and completeness.","fileCount":12,"zipByteSize":134156},{"version":"1.5.2","createdAt":"2026-05-05T01:45:07.255Z","changelog":"pecmd-pro-max 1.5.2 - Expanded GUI documentation in README and references, including typical usage scenarios. - Improved and clarified storage/how-tos, networking, and system how-tos with refined instructions. - Enhanced code examples and explanations in multiple reference files. - Minor adjustments for clarity and consistency in documentation content across files.","fileCount":12,"zipByteSize":127085},{"version":"1.5.1","createdAt":"2026-05-04T14:44:17.770Z","changelog":"No file changes detected for version 1.5.1. - No updates or modifications in this release. - All features and documentation remain unchanged from version 1.5.0.","fileCount":12,"zipByteSize":126743},{"version":"1.6.0","createdAt":"2026-05-04T14:34:27.511Z","changelog":"pecmd-pro-max 1.6.0 - 变量系统和流程控制部分更加详细，补充了变量解析层级、规则和引用方式的说明 - 流程控制（FIND/IFEX/LOOP等）示例和行为描述全面调整，修正了关于区分大小写和数据类型比较的解释 - 增加并完善 ENVI^/ENVI @@ 控制命令说明，更细化参数与用法描述 - 更新窗口与并发调用方式的命令解释，更清晰指明各类型调用的行为和阻塞特性 - 代码结构与注释显著增强，可读性与可检索性提升 - 文档参考与帮助文件链接更为统一和直观","fileCount":12,"zipByteSize":126743},{"version":"1.5.0","createdAt":"2026-05-04T13:48:35.956Z","changelog":"## PECMD Pro Max v1.5.0 - Added comprehensive troubleshooting guide (`references/troubleshooting.md`) - Updated and expanded key documentation: improved variable system explanations, GUI programming sections, and flow control examples - Enhanced and clarified details in ENVI^ runtime commands and multi-thread/multi-window scripting best practices - Added new and detailed examples for advanced syntax (FORX, CALL variants, code blocks, GUI styles, etc.) - Numerous documentation improvements across all references—more usage notes, clearer rules, and up-to-date command tables","fileCount":12,"zipByteSize":126247},{"version":"1.2.4","createdAt":"2026-05-03T07:20:51.591Z","changelog":"**Expanded variable system and documented standard I/O in scripts** - Clarified and expanded PECMD变量体系，详细说明了 `%&::var%`（全局），`%&&var%`（局部），和 `%&var%`（就近/引用）规则与优先级。 - 新增和补充 ENVI^控制命令表，包括 EXPORTLOCAL、Alias、WndProc、memvar、Clipboard、DeskTopFresh、TaskIcoMenu 等重要运行时参数。 - 新增标准输入/输出用法说明（READ/WRIT/LOGS），补全 PECMD 脚本如何直接读写 stdin/stdout/stderr。 - 增强并修订变量作用域细节，强调多线程场景下的正确变量类型与继承策略。 - 同步指南文档与参考文档，例子和规则表述更系统全面。","fileCount":11,"zipByteSize":103701},{"version":"1.2.3","createdAt":"2026-05-02T15:30:18.275Z","changelog":"**Reference documentation split and rewritten, recipes replaced by how-tos, multilingual update.** - Reference sections previously under `references/recipes/` are now moved and rewritten as `references/how-tos/` (gui, net, storage, system). - Documentation in `SKILL.md` and related files has been updated and translated to Chinese. - References in documentation now point to new how-to files. - Old recipe files removed and replaced with the new how-to structure. - Various improvements and localization to documentation for easier usage and clearer guidance.","fileCount":11,"zipByteSize":101843}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s178gdhrbp1e18pdxs1t0eh4th83xjr3:pecmd-pro-max","setupComplexity":"low","setupSteps":["Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-virtualhotbar-pecmd-pro-max/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-virtualhotbar-pecmd-pro-max/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-virtualhotbar-pecmd-pro-max/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-virtualhotbar-pecmd-pro-max/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-virtualhotbar-pecmd-pro-max/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-virtualhotbar-pecmd-pro-max/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-11T17:42:15.237Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-virtualhotbar-pecmd-pro-max/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-virtualhotbar-pecmd-pro-max/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-virtualhotbar-pecmd-pro-max/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-virtualhotbar-pecmd-pro-max/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-11T15:26:58.742Z","emptyReason":null},"readme":"Skill: PECMD Pro Max\n\nOwner: virtualhotbar\n\nSummary: PECMD2012 WinPE 脚本编程 — 轻量级 Windows GUI、系统工具、启动/初始化 脚本、自动化。适用于 .wcs/.wci/.wce 文件、磁盘分区、批处理转 PECMD、 系统信息收集、PE/预安装环境工具、PECMD 代码调试。 参考文件：references/commands-full....\n\nTags: automation:1.7.1, latest:1.7.1, pecmd:1.7.1, scripting:1.7.1, system-tools:1.7.1, windows:1.7.1, winpe:1.7.1\n\nVersion history:\n\nv1.7.1 | 2026-05-05T14:47:29.285Z | auto\n\npecmd-pro-max 1.7.1\n\n- Updated command and troubleshooting references for improved coverage and clarity.\n- Expanded and refined GUI scripting guides.\n- Enhanced troubleshooting instructions for common issues.\n- Improved documentation formatting for easier reading.\n- Fixed minor errors and outdated examples in reference files.\n\nv1.7.0 | 2026-05-05T13:21:06.988Z | auto\n\npecmd-pro-max 1.7.0\n\n- Documentation expanded and improved for all usage guides and reference files.\n- SKILL.md: Clarified variable precedence rules, command-line/script execution modes, and file extension support; added more examples.\n- Added section covering ENVI-env / SET-env for temporary override of ForceLocal.\n- Enhanced GUI, FIND, and CALL variants documentation (including menu alignment, memory function calls, and window flags).\n- Updated and corrected reference and troubleshooting guides for clarity and completeness.\n\nv1.5.2 | 2026-05-05T01:45:07.255Z | auto\n\npecmd-pro-max 1.5.2\n\n- Expanded GUI documentation in README and references, including typical usage scenarios.\n- Improved and clarified storage/how-tos, networking, and system how-tos with refined instructions.\n- Enhanced code examples and explanations in multiple reference files.\n- Minor adjustments for clarity and consistency in documentation content across files.\n\nv1.5.1 | 2026-05-04T14:44:17.770Z | auto\n\nNo file changes detected for version 1.5.1.\n\n- No updates or modifications in this release.\n- All features and documentation remain unchanged from version 1.5.0.\n\nv1.6.0 | 2026-05-04T14:34:27.511Z | auto\n\npecmd-pro-max 1.6.0\n\n- 变量系统和流程控制部分更加详细，补充了变量解析层级、规则和引用方式的说明\n- 流程控制（FIND/IFEX/LOOP等）示例和行为描述全面调整，修正了关于区分大小写和数据类型比较的解释\n- 增加并完善 ENVI^/ENVI @@ 控制命令说明，更细化参数与用法描述\n- 更新窗口与并发调用方式的命令解释，更清晰指明各类型调用的行为和阻塞特性\n- 代码结构与注释显著增强，可读性与可检索性提升\n- 文档参考与帮助文件链接更为统一和直观\n\nv1.5.0 | 2026-05-04T13:48:35.956Z | auto\n\n## PECMD Pro Max v1.5.0\n\n- Added comprehensive troubleshooting guide (`references/troubleshooting.md`)\n- Updated and expanded key documentation: improved variable system explanations, GUI programming sections, and flow control examples\n- Enhanced and clarified details in ENVI^ runtime commands and multi-thread/multi-window scripting best practices\n- Added new and detailed examples for advanced syntax (FORX, CALL variants, code blocks, GUI styles, etc.)\n- Numerous documentation improvements across all references—more usage notes, clearer rules, and up-to-date command tables\n\nv1.2.4 | 2026-05-03T07:20:51.591Z | auto\n\n**Expanded variable system and documented standard I/O in scripts**\n\n- Clarified and expanded PECMD变量体系，详细说明了 `%&::var%`（全局），`%&&var%`（局部），和 `%&var%`（就近/引用）规则与优先级。\n- 新增和补充 ENVI^控制命令表，包括 EXPORTLOCAL、Alias、WndProc、memvar、Clipboard、DeskTopFresh、TaskIcoMenu 等重要运行时参数。\n- 新增标准输入/输出用法说明（READ/WRIT/LOGS），补全 PECMD 脚本如何直接读写 stdin/stdout/stderr。\n- 增强并修订变量作用域细节，强调多线程场景下的正确变量类型与继承策略。\n- 同步指南文档与参考文档，例子和规则表述更系统全面。\n\nv1.2.3 | 2026-05-02T15:30:18.275Z | auto\n\n**Reference documentation split and rewritten, recipes replaced by how-tos, multilingual update.**\n\n- Reference sections previously under `references/recipes/` are now moved and rewritten as `references/how-tos/` (gui, net, storage, system).\n- Documentation in `SKILL.md` and related files has been updated and translated to Chinese.\n- References in documentation now point to new how-to files.\n- Old recipe files removed and replaced with the new how-to structure.\n- Various improvements and localization to documentation for easier usage and clearer guidance.\n\nv1.2.1 | 2026-05-02T14:38:33.201Z | auto\n\n### Minor update: Documentation reorganization, enhanced references, and recipe additions.\n\n- Major documentation overhaul for clarity; improved structure and updated descriptions in guides and reference files.\n- New recipe/reference files added: storage, system, GUI, and networking quickstart examples (recipes/).\n- Reference to codebook.md removed; documentation now points to more focused reference files (e.g. commands-full.md, recipes/*.md).\n- Updated encoding recommendations in examples (now using #code=65001 for UTF-8).\n- File references in SKILL description and README files revised to include new recipe files and remove outdated content.\n\nv1.2.0 | 2026-05-02T12:25:47.075Z | auto\n\npecmd-pro-max 1.2.0\n\n- Expanded variable system documentation with new `ENVI^` control commands and more binary buffer operations.\n- Updated references in SKILL.md to include additional command options and usage examples.\n- Clarified and added details for environment variable prefixes and scope.\n- Improved coverage of binary/memory operations (e.g., `SET-cmp`, `SET-tom`, `SET^`).\n- Added explanations of new script header standards and more control commands for environment, plugin, logging, UI, and desktop refresh.\n\nv1.0.5 | 2026-05-02T05:38:50.359Z | auto\n\npecmd-pro-max 1.0.5\n\n- Updated documentation in SKILL.md with new details on script header encoding (handling `#!` on line 1 with encoding directive on line 2).\n- Added new parameter reference `%@` (all arguments from %0, including function name) to the function parameter section.\n- References and command documentation files updated: codebook.md, commands-full.md, pecmd-gui.md.\n- Minor clarifications to variable/encoding sections for improved accuracy and usability.\n\nv1.0.4 | 2026-05-02T04:31:36.718Z | auto\n\npecmd-pro-max 1.0.4\n\n- Updated and expanded references in codebook.md, commands-full.md, pe-startup.md, and pecmd-gui.md for improved documentation and usability.\n- SKILL.md unchanged; all updates are within supporting documentation files.\n- No changes to functionality or compatibility; this version is focused on enhancing documentation.\n\nv1.0.3 | 2026-05-02T03:34:16.879Z | auto\n\n- Updated documentation and examples in README and SKILL.md for greater clarity.\n- Expanded and revised explanations in the variable system section, improving accuracy and usability.\n- Enhanced formatting and code samples throughout the documentation for better readability.\n- No functional or code changes; this is a documentation-focused release.\n\nv1.0.1 | 2026-05-02T03:27:06.426Z | auto\n\npecmd-pro-max 1.0.1\n\n- Added project links (GitHub and ClawHub) to documentation headers.\n- Introduced a version field to SKILL.md for improved clarity.\n- Minor content and formatting updates to documentation files for accuracy and consistency.\n- No functional or code changes; updates are documentation improvements only.\n\nv1.0.0 | 2026-05-02T03:06:25.638Z | auto\n\nInitial release of PECMD Pro Max.\n\n- Expert tooling and scripting guidance for PECMD2012 in WinPE environments.\n- Supports lightweight GUI scripting, system tools, automation, and code debugging.\n- Detailed documentation of the three-tier variable system and best practices.\n- Reference materials for core scripting, code organization, function/parameter handling, and advanced ENVI^ controls.\n- Compatibility: Requires PECMD2012 v1.88+; scripts are for the PECMD/WinCMD runtime (not cmd.exe).\n- Includes code templates for disk partitioning, batch conversion, system info collection, and pre-install utilities.\n\nArchive index:\n\nArchive v1.7.1: 13 files, 135604 bytes\n\nFiles: README.en.md (4738b), README.md (4635b), references/commands-full.md (93821b), references/how-tos/gui.md (31756b), references/how-tos/net.md (6065b), references/how-tos/storage.md (16594b), references/how-tos/system.md (33590b), references/pe-startup.md (11938b), references/pecmd-gui.md (75422b), references/troubleshooting.md (9907b), skill-card.md (2906b), SKILL.md (34471b), _meta.json (132b)\n\nFile v1.7.1:SKILL.md\n\n---\nname: pecmd-pro-max\nversion: 1.5.5\ndescription: |\n  PECMD2012 WinPE 脚本编程 — 轻量级 Windows GUI、系统工具、启动/初始化\n  脚本、自动化。适用于 .wcs/.wci/.wce 文件、磁盘分区、批处理转 PECMD、\n  系统信息收集、PE/预安装环境工具、PECMD 代码调试。\n  参考文件：references/commands-full.md、references/pecmd-gui.md、references/pe-startup.md、\n  references/how-tos/storage.md、references/how-tos/system.md、references/how-tos/gui.md、references/how-tos/net.md、\n  references/troubleshooting.md。\ncompatibility: 需要 PECMD2012 v1.88+ 解释器。脚本运行于 PECMD/WinCMD 环境，非 cmd.exe。\n---\n\n# PECMD Pro Max\n\n你是 PECMD 专家程序员。PECMD 是从 XCMD V2.2 演进而来的 WinPE 命令解释器与脚本语言——可将其视为 Windows PE 系统管理和轻量级 GUI 工具的领域特定语言。\n\n## $1 心智模型\n\nPECMD 有两种执行模式：\n- **命令行模式**：`PECMD.EXE ENVI $PPPoE=OK` — 单条命令，注释默认关闭\n- **脚本模式**：`PECMD.EXE LOAD C:\\PECMD.INI` — 多命令文件，注释默认开启\n\nPECMD 脚本是一组平铺的顶层语句。从上到下顺序执行。`_SUB` 块在解析时声明，仅在 CALL 时运行。所有 GUI 由定义窗口函数的 `_SUB` 块创建（通过 `CALL @窗口名` 调用）。\n\n关键运行时事实：\n- `PECMD.EXE MAIN 路径\\PECMD.INI` — 标准 WinPE 入口，执行 INI 并启动消息循环\n- 可在 PECMD 内运行 PECMD：`EXEC =!\"%MyNAME%\" <命令>` — 用于隔离的子操作\n- `EXIT FILE` 终止整个脚本；`EXIT _SUB` 从当前函数返回\n- 循环体内 `EXIT CONTINUE` 继续下一次迭代；`EXIT -` 跳到当前 `{}` 块尾部；`EXIT LOOP` / `EXIT FORX` / `EXIT BREAK` 跳出循环；`EXIT ToWin` 中止函数返回窗口消息循环\n- 脚本文件常用 `.wcs` 扩展名（也支持 `.wce`、`.wci`、`.wcx`、`.ini`、`.inf`、`.txt`、`.log` 等）。中文脚本首行加 `#code=65001` 声明 UTF-8 编码。若首行以 `#!` 开头，编码指令放在第二行。\n\n**标准 I/O（stdin/stdout/stderr）：**\n- `READ -,n,&var` — 从 stdin 读取一行\n- `WRIT -,$+0,text` — 写入 stdout\n- `WRIT --,$+0,text` — 写入 stderr\n- `LOGS * CONOUT$` — 输出到控制台（调试终端输出）\n\n## $2 变量系统\n\nPECMD 有**四种访问前缀**对应三种存储层级（加上就近查找机制）。搞错这一点是绝大多数错误的根源。\n\n| 层级 | 语法 | 设置方式 | 作用域 |\n|------|------|----------|--------|\n| 环境变量 | `%var%` | `ENVI var=val` 或 `ENVI $var=val` | 进程级，与子进程共享 |\n| PE 全局变量 | `%&::var%` | `ENVI &::var=val` 或 `SET &::var=val` | 跨函数、跨线程、文件级，永不消失 |\n| PE 局部变量 | `%&&var%` | `SET &&var=val` 或 `ENVI &&var=val` | 当前 `_SUB`/`{}` 块，退出自动销毁 |\n| PE 变量引用 | `%&var%` | `ENVI &var=val` 或 `SET var=val` | 就近解析：从内向外查找，找到谁就是谁；找不到则创建为 `&&var` |\n\n**`&a` 解析顺序**（反向匹配，从内向外）：\n1. 先找当前范围的 `&&a` → 找到就用它\n2. 再往外层找 `&::a`（全局）→ 找到就用它\n3. 都没找到 → 当作 `&&a` 在当前范围新建\n\n**关键规则：**\n1. `ENVI^ ForceLocal=1` 放在文件顶部——强制 `ENVI` 和 `SET` 默认创建局部 PE 变量。**务必始终使用**（默认 `ForceLocal=0`，变量按就近查找链解析）。\n2. `ENVI^ EnviMode=1` — 空变量引用返回空字符串。务必始终使用（默认 `EnviMode=0`，兼容 4.0 模式：空变量不解释为字面文本，自动多轮次非顺序解释）。\n3. `SET` **始终**等价于 `ENVI &`（SET 总是创建 PE 变量而非环境变量）。ForceLocal=1 同时影响 SET 和 ENVI 的作用域（默认局部）。\n4. `%Desktop%` 是**环境变量**版本；`%&Desktop%` 是**PE 变量**版本。\n5. 多线程代码中务必使用 PE 变量（`&var`）——环境变量跨线程共享会竞态。跨线程通信用 `&::` 类变量。\n6. `SET~ &&dest=Source.Key` — `~` 运算符执行**间接解引用**：将右侧展开为变量名，再读取该变量的值。伪数组必备。\n7. `^` 前缀（`^SET`、`^ENVI`、`^CALC`、`^IFEX` 等）— 预先解释本命令（help.txt: \"命令前若干个^表示预先解释本命令几次\"）。循环中动态变量名必备。`^^` 预解释两次。\n8. `ENVI-ret %~1=%var%` — 将值设置到*名称*存储在 `%~1` 中的变量（引用返回）。\n9. `SET-def var=value` — 仅在变量未定义时设置（安全默认值）。\n\n### ENVI^ / ENVI @@ 运行时控制命令\n\n| 命令 | 功能 |\n|------|------|\n| `ENVI^ EnviMode=1` | 标准模式：空变量解释为空字符串，顺序解释1遍 |\n| `ENVI^ ForceLocal=1` | 强制所有变量为 PE 变量，最简多线程/并行窗口 |\n| `ENVI^ EXPORTLOCAL=1\\|0\\|&1\\|&0` | PE 变量继承：1=继承，0=隔离（默认），&1=仅本级及以下继承，&0=仅本级及以下隔离 |\n| `ENVI^ Alias name=cmd` | 命令别名：替代命令前半部（可包装 DLL 调用为伪命令） |\n| `ENVI^ WndProc[1\\|2\\|3][C][,ptr]` | Win32 回调绑定（C=C 调用约定） |\n| `ENVI^ memvar=[?返回名,][:字节数:]偏移,值` | 修改/查询 PECMD 内存变量 |\n| `ENVI^ LoadPlugin=basename` | 加载插件 |\n| `ENVI^ DisX64=1[,Old]` | 禁用/恢复 WOW64 文件系统重定向 |\n| `ENVI^ zero=0\\|1` | 私密模式：内存用完清零 |\n| `ENVI^ Arg=*[字符集]字符串` | 词语分断 |\n| `ENVI^ Clipboard=text\\|?=var` | 读写剪贴板 |\n| `ENVI^ EnviBroad=0\\|1\\|-` | 环境变量广播开关 |\n| `ENVI^ __arg=0\\|1` | 兼容模式：启用 `&&__arg` 参数表 |\n| `ENVI^ LoadEnvi [路径\\|-] [变量名]` | 从注册表刷新环境变量 |\n| `ENVI^ HelpColor=[*高度] [前景色][#背景色]` | HELP 显示颜色 |\n| `ENVI @@DeskTopFresh=[clearicon][;][1\\|2\\|4\\|8\\|16][;[-+]path]` | 桌面刷新 |\n| `ENVI @@TaskIcoMenu=0\\|1\\|2` | 托盘菜单切换（0=关闭, 1=开启, 2=切换） |\n\n> 完整 ENVI^ 控制命令、二进制缓冲区操作（SET-cmp、SET-tom、SET-copy、SET?int 等）和函数参数引用，参见 [commands-full.md](references/commands-full.md)。\n\n### ENVI-env / SET-env — 临时绕过 ForceLocal\n\n`ENVI-env` 和 `SET-env` 后缀临时绕过 ForceLocal=1 限制，直接操作环境变量。常用于线程内读取父窗口上下文的环境变量（如 `__WinID`）：\n\n```wcs\nENVI-env hwnd0=%&__WinID%           // 从环境变量读取 __WinID（绕过 ForceLocal）\nSET-env MyName=%MyName%             // 临时设为环境变量\n```\n\n```wcs\n#code=65001\nENVI^ EnviMode=1\nENVI^ ForceLocal=1\nSET$ &NL=0d 0a\nSET$ &TAB=09\n```\n\n### 十六进制数据与原始内存\n\n```wcs\nSET$ &NL=0d 0a                  // 十六进制转宽字符串（Unicode）\nSET$# &buf=*4096 0              // 十六进制转原始字节（二进制缓冲区）\nENVI$ &data=*1M 30 0d 0a        // 可变长度十六进制分配\n```\n\n## $3 代码组织\n\n### 函数与 CALL 变体\n\n```wcs\n_SUB 函数名 [*]                   // * = this-call（在调用者栈中运行）\n    SET &param1=%~1                 // %~1 剥离外层引号\n    ENVI-ret %~3=%&result%          // 通过引用参数返回值\n    // 函数参数：%0=函数名, %1~%n=各参数, %#=参数个数, %*=全部参数, %~=去掉引号\n_END\n```\n\n```\nCALL 函数名 [参数]                 // 调用函数\nCALL *函数名 [参数]                // this-call（调用者栈）\nCALL @窗口名 [参数]                // 创建/显示窗口（模态，阻塞）\nCALL @*窗口名 [参数]               // 并行窗口（可同时操作，但关闭前阻塞后续命令）\nCALL @-窗口名 [参数]               // 后台窗口\nCALL @~窗口名 [参数]               // 后台，完全非阻塞\nCALL @~~窗口名 [参数]              // 后台快速调用（非阻塞）\nCALL @^窗口名 [参数]               // 并行，父窗口不阻塞子窗口\nCALL @+窗口名 [参数]               // 弃养子窗口\nCALL @--                           // 销毁 Win 环境（无参数）\nCALL @--popmenu 窗口名 [x.y[:对齐]] // 在指定位置弹出菜单（对齐：对齐方式）\nCALL --mem &变量名 [*] [参数]      // 执行内存中的动态函数代码\n```\n\n### 窗口（GUI）\n\n```wcs\n_SUB 窗口名,L200T100W400H300,窗口标题,[关闭命令],[图标],[样式],[遮罩] [-标志1 -标志2 ...]\n_END\n```\n\n窗口形状：`L<左>T<上>W<宽>H<高>`。省略 L/T 则居中。\n窗口样式：`-` = 无标题栏，`#` = 无边框，数字 1-99 = 透明度，`:`透明色。\n常用标志：`-trap`（关闭按钮不退出）、`-nocap`（无标题栏）、`-nosysmenu`、`-top`、`-size`、`-maxb`、`-disminb`、`-discloseb`、`-nfocus`、`-ntab`、`-forcenomin`、`-scalef`、`-scale[:DPI]`、`-nxp`、`-csize`、`-na`、`-layer`（支持渐透明）、`-disaltmv`（禁用 ALT 拖动）\n\n### IMPORT 与代码块\n\n```wcs\nIMPORT 路径\\库文件.wcs          // 将可复用函数加载到当前脚本\n_ENDFILE-IMPORT                // 此行以下内容在 IMPORT 时被丢弃\n\n{                               // 带独立 PE 变量栈的代码块\n    SET temp=仅此处有效\n}\n{*                              // this-call 代码块（在调用者栈中运行）\n    LOCK .ole                   // COM 初始化等需要在当前作用域执行的操作\n}\n```\n\n文件级和函数级的 `{` 必须从第 1 列开始。嵌套 `_SUB` 用双冒号访问：`类名::子函数名`。点号用于数据成员访问（如 `类名.属性`）。\n\n## $4 流程控制\n\n### FIND — 字符串比较（默认不区分大小写，`*c` 后缀区分）\n\n```wcs\nFIND $%var%=hello, 命令               // 相等（不区分大小写）\nFIND $%var%*c=hello, 命令             // 相等（区分大小写，*c 后缀）\nFIND $%var%<>hello, 命令              // 不等\nFIND $%var%=, 命令                    // \"为空\" 测试（惯用法）\nFIND *=var, 命令                      // 惯用法：\"为空\"\nFIND *<>var, 命令                     // 惯用法：\"非空\"\nFIND |%a%>%b%, 命令                   // | 前缀 = 浮点数比较\nFIND #%a%>%b%, 命令                   // # 前缀 = 整数比较（INT64）\nFIND [ $A & $B ], 命令                // 复合 AND\nFIND [ $A | $B ], 命令                // 复合 OR（| 分隔）\nFIND --pid &var,                     // 返回 5 值：空闲时间 总时间 CPU个数 1秒时钟数 一时钟100ns数\nFIND --pid*@ &var,                   // 进程列表（用于 TABL）\nFIND --class:Shell_TrayWnd --wid*@ &var  // 按类名过滤窗口列表\nFIND --forpid:PID --wid*@ &var       // 按进程 ID 过滤窗口\nFIND --sub --wid*@ &var              // 递归子窗口\nFIND --menu &var,窗口ID              // 查询窗口的 MENU 句柄\nFIND --menu#Index &var,MenuID        // 按索引查询子 MENU\n```\n\n### IFEX — 文件测试 / 数值比较\n\n```wcs\nIFEX C:\\boot.ini, 命令                // 文件/目录存在\nIFEX C:\\boot.ini,! 命令               // 不存在\nIFEX x:\\, 命令                        // 盘符存在且有文件系统\nIFEX $%val%>=5, 命令                  // $=浮点数比较（#=整数比较，|=字符串比较）\nIFEX [ 条件1 & 条件2 ], 命令          // AND 复合条件\nIFEX [ 条件1 | 条件2 ], 命令          // OR 复合条件（| 分隔）\nIFEX MEMU=?,&var                     // 查询可用内存\nIFEX C:\\=?,&可用空间                  // 查询磁盘可用空间\n```\n\n### LOOP / FORX / TEAM / LOCK\n\n```wcs\nSET &&I=0\nLOOP #%&I%<=10, { MESS %&I% | CALC &I=%&I% + 1 }\n\nFORX * %&list%,&&item, { MESS %&item% }              // * = 空格分隔\nFORX *NL &多行变量,&&line, { ... }                    // *NL = 换行分隔\nFORX *NL:| &数据,&&item, { ... }                     // *NL:分隔符 = 自定义分隔符\nFORX *L 0 2 10,&&val, { ... }                        // *L = 数值循环（起始 步长 结束）\nFORX /S C:\\Windows\\*.exe,&&file,0 { ... }            // 文件系统枚举\nFORX @\\Windows,&&winDir,1 { ... }                    // @=仅搜索目录，\\=所有盘符\n\n// ⚠ FORX 循环变量引用规则：\n// 定义用 &&item，引用值用 %&item%（单&），**不是** %&&item%\n// 示例：FORX *NL &list,&&line, { SET &val=%&line% }  // ✅ 正确\n//       FORX *NL &list,&&line, { SET &val=%&&line% }  // ❌ 错误\n\nTEAM SET &a=1| SET &b=2| CALC &c=%&a% + %&b%         // 多命令链\n\n// 线程\nTHREAD* CALL WorkerFunc                             // * = 持久栈（共享变量，保持父子关系）\nTHREAD CALL WorkerFunc                              // 独立模式（复制变量到子线程）\nTHREAD& CALL WorkerFunc                             // & = 强制 PE 变量模式（最简多线程）\nTHREAD+ CALL WorkerFunc                             // + = 抛弃式线程（不等待退出）\nTHREAD# CALL WorkerFunc                             // # = 代理模式（线程结束则退出）\nTHREAD $ CALL WorkerFunc                            // $ = 预先解释命令组\nTHREAD -link CALL WorkerFunc                        // 保持父子关系（类似 *）\nTHREAD -wait CALL WorkerFunc                        // 等待完成（阻塞消息循环）\nTHREAD -waitx CALL WorkerFunc                       // 等待完成（不阻塞消息循环）\nTHREAD -here CALL WorkerFunc                        // 当前栈的孩子（可修改父栈临时PE变量）\nTHREAD -waitp CALL WorkerFunc                       // 进程结束前等待该线程\nTHREAD -tid:&tid CALL WorkerFunc                    // 获取线程 ID\nTHREAD --st:128K CALL WorkerFunc                    // 设置栈大小\n\n{ LOCK #pecmd                                      // 原子作用域\n    LOCK --exist #MyLock,&&ret                      // 检查锁是否存在\n}\nLOCK #MyLock,&&ret2                                 // 创建/获取命名锁\n```\n\n完整 EXIT 变体、LAMBDA 语法和 `FIND --class:` 参见 [commands-full.md](references/commands-full.md)。\n\n## $5 GUI 编程\n\n### 控件类型\n\n| 控件 | 命令 | 控件 | 命令 |\n|------|------|------|------|\n| 按钮 | `ITEM` | 标签 | `LABE` |\n| 编辑框 | `EDIT` | 复选框 | `CHEK` |\n| 单选框 | `RADI` | 下拉列表 | `LIST` |\n| 表格 | `TABL` | 进度条 | `PBAR` |\n| 分组框 | `GROU` | 图片 | `IMAG` |\n| 多行文本 | `MEMO` | 子窗口 | `SWIN` |\n| 定时器 | `TIME` | 托盘/气泡 | `TIPS` / `TIPS*` |\n| 选项卡 | `TABS` | 滑块 | `SLID` |\n| 微调器 | `SPIN` | 树形视图 | `TREE` |\n| 滚动条 | `SBAR` | 热键 | `HKEY` |\n| 日期时间 | `DTIM` | IP 地址 | `IPAD` |\n| 菜单项 | `MENU` | 屏幕捕捉 | `SCRN` |\n| 浏览窗口 | `BROW` | | |\n\n### 消息映射\n\n```wcs\nENVI @控件.MSG=_%&WM_LBUTTONDOWN%: 命令        // _ = 后置系统处理器（控件通知）\nENVI @窗口.MSG=0x0010: CALL OnClose             // 无 _ = 窗口级消息（WM_CLOSE）\nENVI @控件.MSG=_%&msg%::&&wp,&&lp, CALL Handler // 捕获 wParam/lParam\nENVI @控件.POSTMSG=#1                            // 投递自定义消息 #1\nENVI @控件.SENDMSG=消息号;wParam;lParam          // 同步发送\nENVI @控件.MSG=$0x0201: 命令                     // $ = 屏蔽系统响应（可返回结果码）\nENVI @控件.MSG=*msg: 命令                        // * = 捕鼠器 B（鼠标捕获模式）\nENVI @控件.MSG=+msg: 命令                        // + = 超级捕获\n```\n\nMSG 前缀说明：无前缀=直接处理后丢弃（不传递给系统），`_`=系统响应后执行（控件通知），`$`=屏蔽系统响应（可返回结果码），`*`=捕鼠器 B（鼠标捕获），`+`=超级捕获。消息号 `*del` 删除映射。`#1`~`#N` 为 PECMD 自定义消息。\n\n### 控件操作\n\n```wcs\nENVI @控件名=新文本                              // 设置文本\nENVI @控件名.Enable=0                            // 禁用（1=启用）\nENVI @控件名.Visible=0                           // 隐藏（1=显示）\nENVI @控件名.POS=左:上:宽:高                     // 移动/调整大小\nENVI @控件名.POS=?;&L:&T:&W:&H                  // 查询位置\nENVI @控件名.Val=?行.列;&var                     // 获取 TABL 单元格\nENVI @控件名.Val=?*;&count                       // 获取 TABL 行数\nENVI @控件名.*del=                               // 销毁控件\n```\n\n完整控件语法、全部 25 种控件类型、ENVI @ 属性参考、窗口生命周期和消息映射——参见 [pecmd-gui.md](references/pecmd-gui.md)。\n\nGUI 写法示例（动态控件、选项卡页、自定义标题栏、GDI 绘图、拖放等）——参见 [how-tos/gui.md](references/how-tos/gui.md)。\n\n## $6 DLL 调用\n\n> **实测验证（32-bit / 64-bit 行为一致）：** 以下内容在 PECMD 32-bit (PECMDx86) 和 64-bit (PECMD) 上均经实测确认，行为完全相同。DLL 调用可正常工作，但有重要限制。\n\n### 调用约定\n\nDLL 函数**默认按 PASCAL/stdcall** 调用约定。Windows API（WINAPI 标记）不需要 `--c`。使用 `--c` 切换到 CDECL。最多 20 个参数（C 调用 100 个）。\n\n### 正确语法（逗号分隔 + 类型前缀 + --qd）\n\n```wcs\n// ✅ 正确格式：逗号分隔，整数 #，字符串 $，建议加 --qd\nCALL $ --qd --ret:&&r user32.dll,GetSystemMetrics,#0             // 整数参数\nCALL $ --qd --ret:&&r user32.dll,FindWindowW,$Progman,#0         // 字符串+整数\nCALL $ --qd --ret:&&r kernel32.dll,lstrlenW,$Hello World          // 字符串参数\nCALL $ --ret:&&hDll ,-LoadLibrary,^user32.dll                     // 加载 DLL（^ = 自动释放）\nCALL $ --ret:&&r *%&hDll%,GetSystemMetrics,#0                     // 通过句柄调用\nCALL $ ,-FreeLibrary,*%&hDll%                                      // 释放 DLL\nCALL $ --bool --ret:&&ret DLL,函数,...                             // --bool：函数返回 BOOL\nCALL $ --cd --ret:&&ret DLL,函数,...                               // --cd：执行前切换到目标目录\n\n// Win32 回调函数绑定（用于 EnumResourceNames 等 API）\nENVI^ WndProc1C,WndProc1Addr               // C 调用约定回调\nSET^ WndProc1,WndProc1Addr                  // PASCAL/stdcall 回调\n// PECMD 自动查找 _SUB OnWndProc1 并包装为 Win32 回调\n```\n\n### 关键规则\n\n1. 参数**必须**用逗号分隔——点语法（`Func.#Param`）完全不工作\n2. 整数参数**必须**有 `#` 前缀——无前缀返回 0\n3. 字符串**必须**用 `$` 前缀\n4. **务必加 `--qd`**——否则字符串多传一个 null 终止符，导致 API 结果错误：\n\n| 字符串 | 无 `--qd` | 有 `--qd` | 说明 |\n|--------|-----------|-----------|------|\n| `$A` | lstrlenW → 2 | lstrlenW → 1 | 无 --qd 含 null |\n| `$Test` | lstrlenW → 5 | lstrlenW → 4 | 无 --qd 含 null |\n| `$Progman` | FindWindowW → 0 | FindWindowW → 66062 | 无 --qd 找不到窗口 |\n\n### ❌ 不可用的语法\n\n```wcs\n// ❌ 点语法完全不工作\nCALL $--qd --ret:&&r user32.dll,GetSystemMetrics.#0              // 返回空\n\n// ❌ 整数无前缀返回 0\nCALL $ --ret:&&r user32.dll,GetSystemMetrics,0                   // 返回 0\n\n// ⚠ GetProcAddress：无 --qd 时常返回 0x0，加 --qd 后可工作\nCALL $ --ret:&&p ,-GetProcAddress,*%&hDll%,$GetSystemMetrics     // 可能返回 0x0\nCALL $--qd --ret:&&p ,-GetProcAddress,*%&hDll%,GetSystemMetrics  // 加 --qd 更可靠\n\n// ⚠ 缓冲区输出：无 --qd 时数据可能不回传，加 --qd 后可工作\nSET$ &buf=*256 0\nCALL $--qd --ret:&&r kernel32.dll,GetWindowsDirectoryW,*&buf,#256  // --qd 模式\n\n// ❌ 无 --qd 时字符串含 null 终止符，FindWindowW 等失败\nCALL $ --ret:&&r user32.dll,FindWindowW,$Progman,#0             // 返回 0\n```\n\n### 可靠工作的场景\n\n| 场景 | 语法 | 状态 |\n|------|------|------|\n| 无参整数返回 | `CALL $ --ret:&&r kernel32.dll,GetTickCount` | ✅ |\n| 整数参数 | `CALL $ --qd --ret:&&r user32.dll,GetSystemMetrics,#0` | ✅ |\n| 字符串输入 | `CALL $ --qd --ret:&&r user32.dll,FindWindowW,$Progman,#0` | ✅ |\n| 变量作参数 | `CALL $ --qd --ret:&&r kernel32.dll,lstrlenW,$%&str%` | ✅ |\n| LoadLibrary | `CALL $ --ret:&&h ,-LoadLibrary,^user32.dll` | ✅ |\n| 通过句柄调用 | `CALL $ --ret:&&r *%&h%,GetSystemMetrics,#0` | ✅ |\n| 缓冲区输出 | 加 `--qd` 后可回传到 PE 变量 | ⚠ |\n| GetProcAddress | 加 `--qd` 后可工作 | ⚠ |\n| 点语法 | Func.#Param 不解析 | ❌ |\n\n### 32-bit vs 64-bit 区别\n\n| 项目 | PECMDx86 (32-bit) | PECMD (64-bit) |\n|------|-------------------|----------------|\n| 文件标识 | PE32, i386 | PE32+, x86-64 |\n| `bX64` 值 | `0`（32 位系统）或 `1`（64 位系统） | `3` |\n| 指针大小 | 4 字节（< 4GB） | 8 字节（> 4GB） |\n| DLL 调用行为 | 与 64-bit 完全相同 | 与 32-bit 完全相同 |\n| LoadLibrary 句柄 | `0x761A0000` | `0x7FFC34B00000` |\n| 代码差异 | 无 | 无 |\n\n`bX64` 值含义：`0`=WIN32（32 位系统原生），`1`=WIN64（64 位系统运行 32 位 PECMD），`3`=PECMD64（64 位 PECMD）。\n\n### 参数类型前缀\n\n| 前缀 | 类型 | 描述 | 示例 |\n|------|------|-------------|------|\n| `#` | integer | 按整数传递 | `#0`、`#256`、`#%&hwnd%` |\n| `<` | INT64 | 64 位整数 | `<0x100000000` |\n| `$` | string | 按 Unicode 字符串传递（配合 `--qd` 不含 null） | `$CabinetWClass` |\n| `@` | ANSI | 按 ANSI 字符串传递 | `@text` |\n| `*` | buffer | 传递 PE 变量地址（`*&buf` 形式可回传输出） | `*&buf` |\n| `=` | raw | 按原始数据传递 | |\n| `~` | deref | 间接解引用（展开变量名再读值） | |\n\n### 缓冲区操作（PE 变量内部）\n\n```wcs\nSET$# &buf=*256 0                     // 分配 256 字节原始缓冲区\nSET$ &strBuf=*256 0                   // 分配 256 个宽字符\nSET-long &buf=value:offset            // 写入 32 位整数到缓冲区偏移\nSET?int &buf=&&var:offset             // 从缓冲区偏移读取 32 位整数\n```\n\n### DLL 输出数据的替代方案\n\nDLL 缓冲区输出可使用 `*&buf` 形式（PE 变量地址传递，输出回传）。获取系统信息也可用内置命令：\n- `FIND --wid*@ &var` — 枚举窗口（返回 HWND、类名、标题）\n- `FIND --pid*@ &var` — 枚举进程\n- `REGI` — 注册表读取系统信息\n- `EXEC* &out=!cmd.exe /c ...` — 捕获外部命令输出\n- `IFEX MEMU=?,&var` — 查询可用内存\n- `IFEX C:\\=?,&var` — 查询磁盘空间\n\n### 平台检测\n\n```wcs\nIFEX #%&::bX64%=3, SET &PtrSz=8! SET &PtrSz=4  // 3=PECMD64, 1=WIN64(32位PECMD在64位系统), 0=WIN32\n```\n\n## $7 常用范式\n\n### 磁盘与分区\n\n```wcs\nFDRV &盘符列表=*:                                        // 枚举所有盘符\nFDRV *vol &卷标,&文件系统=C:                             // 获取卷标和文件系统\nPART list disk,&&全部磁盘                                 // 枚举所有物理磁盘\nPART list disk %&dsk%,&&磁盘信息                          // 获取磁盘信息\nPART list part %&dsk%,&&分区列表                          // 列出分区号\nPART -hextp -phy# list part %&dsk%#%&pt%,&&分区信息       // 详细分区信息\nSHOW * %&dsk%#%&pt%,%&盘符%                               // 分配盘符\nSHOW *- %&dsk%#%&pt%,                                     // 移除盘符\n```\n\n### 注册表与文件 I/O\n\n```wcs\nREGI $HKLM\\SOFTWARE\\App\\Key,&var                  // 读 REG_SZ\nREGI #HKLM\\SOFTWARE\\App\\Count,&var                // 读 REG_DWORD\nREGI $HKLM\\SOFTWARE\\App\\Key=值                     // 写 REG_SZ\nREAD %路径%,**,&内容                               // 读取整个文件\nWRIT %路径%,+0,新行                                // 追加一行\nGETF# %路径%,0#*,&原始数据                         // 按原始字节读取文件\n```\n\n### 执行与捕获\n\n```wcs\nEXEC* &输出=!cmd.exe /c dir /b                            // 捕获全部输出\nEXEC =!\"%MyNAME%\" TEAM WAIT 1000|LOAD other.ini           // 运行子 PECMD\nEXEC* &out=!cmd.exe /c ipconfig                           // 捕获外部命令输出\nEXEC* --exe:#101 &out=*embedded.exe                       // 从 PECMD 资源运行 EXE\n```\n\n### 单实例互斥体\n\n```wcs\n{ LOCK #pecmd\n    LOCK --exist #MyAppLock,&&exists\n}\nIFEX $1=%&exists%,\n{\n    REGI $HKCU\\Software\\MyApp\\WID,&&wid\n    IFEX $%&wid%>0, TEAM ENVI @@Visible=%&wid%:2| ENVI @@POS=%&wid%:::::::1\n    EXIT FILE\n}\nLOCK #MyAppLock,&ret2\n```\n\n### 字符串操作\n\n```wcs\nMSTR &&a,&&b=<1><3->%&data%                              // 字段1、字段3到末尾（- = 到末尾）\nMSTR &&last=<-1>%&data%                                   // 最后字段（负索引）\nMSTR &&q=<~5>%&data%                                      // 字段5并剥离外层引号（~前缀）\nMSTR -delims:. &&a,&&b,&&c,&&d=<1><2><3><4>%&ip%         // 按自定义分隔符拆分\nMSTR* &&a,&&b=<1><2>%&data%                               // *前缀 = TAB 分隔\nMSTR$ &&a,&&b=<1><2>%&data%                               // $前缀 = 空格分隔（连续空格视为单个）\nSED &&r=0,模式,替换,%&source%                             // 替换所有匹配（正则模式）\nSED &&r=1,模式,替换,%&source%                             // 替换第一个匹配\nSED &&r=-1,模式,替换,%&source%                            // 替换最后一个匹配（负数=从末尾）\nSED -t &&r=0,ABCD,abcd,%&source%                          // -t = 字符集翻译（A→a, B→b, 逐字符映射）\nSED -ni &&r=0,模式,替换,%&source%                         // -ni = 不区分大小写\nSED &&ext=-1,.*\\.,,  ,%&filename%                          // 获取扩展名（.*\\. 匹配到最后一个句号）\nLPOS &&pos=needle,,%&haystack%                            // 查找首次出现（不区分大小写）\n```\n\n> **MSTR 注意事项：** 默认分隔符为空格。`-delims:09` 指定制表符（十六进制 09）。字段索引从 1 开始。`<N>` = 单个字段，`<N->` = 字段N到末尾，`<N*>` = 仅字段N（单字段），`<~N>` = 剥离引号，`<-N>` = 从末尾反向索引。`MSTR*` = TAB分隔，`MSTR$` = 空格分隔（连续空格视为单个）。如果 MSTR 返回空，先用 `WRIT` 打印源变量确认格式，或改用 `FORX *` 按空格逐字段拆分作为替代。\n>\n> **SED 注意事项：** SED 默认使用正则模式。`.` 匹配任意字符，非字面量句号。匹配字面量句号用 `\\.`。使用标志字符 `*` 可切换为字面量模式（不解释正则）。count=0 替换全部匹配，count=N 替换前 N 个，count=-N 替换后 N 个。`0:0` 与 `0` 等价。`-t` 标志启用字符集翻译，`-ni` 标志不区分大小写。模式中的空格作为参数分隔符处理时可能引起问题——用变量间接传递含空格的模式。\n>\n> **LPOS 注意事项：** 参数顺序为 `LPOS &&pos=needle,,haystack`（查找目标在前，源字符串在后）。返回首次出现的位置索引。加 `,1,` 可区分大小写。`RPOS` 从末尾查找。\n\n含错误处理和边界情况处理的完整展开版本，参见 [how-tos/storage.md](references/how-tos/storage.md)（磁盘/注册表/文件）、[how-tos/system.md](references/how-tos/system.md)（进程/线程/定时器）、[how-tos/net.md](references/how-tos/net.md)（网络/COM）。\n\n### CALC 计算与数学函数\n\n```wcs\nCALC &结果=%&a% + %&b%                               // 基本算术：+ - * / % ^\nCALC #&结果=%&a% & %&b%                               // # = 整数模式；位运算：& | @\nCALC -base=16 #&hex=shl(0x07,16)|0x20                 // 十六进制输出 + 位移\nCALC &sz=%&bytes%/1G#3                                // 字节转 GB，3 位小数\nCALC -err=0 &r=%&a% / %&b%                            // 出错时返回默认值 0\n```\n\n**数学函数（34个）：**\n\n| 类别 | 函数 |\n|------|------|\n| 三角 | `sin cos tan ctg arcsin arccos arctan arcctg deg rad` |\n| 代数 | `abs sqrt ln lg log exp pow pow10 hypot`（⚠ `log()` 需两参数 `log(底数,值)`，单参数返回 0；用 `lg()` 代替 log₁₀） |\n| 取整 | `floor ceil round int frac` |\n| 位运算 | `shl shr xor not lnot` |\n| 其他 | `div mod rand max min` |\n\n常量：`e`、`pi`。尺寸后缀：`K`=1024、`M`=1024²、`G`=1024³、`T`=1024⁴、`S`=512。\n多表达式用 `;` 分隔，子变量 `$subName=expr`。\n\n## $8 陷阱与注意事项\n\n1. **CALC 空格**：`CALC &J=1+2` 可以正常执行。右侧以 `%&I%` 等变量开头时，用空格分隔（`CALC &J= %&I%+1`）。PECMD 要求减号后必须有空格（`3 - 2`）。\n2. **注释标记**：`//`、`;`、`` ` ``（反引号）均为有效注释符。行尾注释前必须有空格（如 `SET &a=1 // 注释`）。help.txt: \"注释符前有一个空字符，该空字符算注释\"——所有位置的注释符前都建议加空格。\n3. **SET 就是 ENVI &**：`SET var=val` 语义上等价于 `ENVI &var=val`。启用 ForceLocal=1 后，两者都创建局部 PE 变量。\n4. **FIND 与 IFEX 前缀交换**：FIND 中 `$` = 字符串比较、`|` = 浮点比较；IFEX 中 `$` = 浮点比较、`|` = 字符串比较。`#` 在两者中均为整数比较。IFEX 中 `|` 在 `[]` 复合条件内为 OR 逻辑运算符。\n5. **盘符冒号**：`FDRV`、`FORM`、`FIND C:\\=?` 都需要 `:` 后缀。\n6. **带空格的路径**：`LOAD \"C:\\Program Files\\a.ini\"` 需要引号。\n7. **文件编码**：中文脚本首行声明编码（`#code=65001` = UTF-8，`#code=936` = GBK）且文件编码须与声明一致。SDK 示例普遍使用 GBK（936）。\n8. **`{` 位置**：文件级和函数级 `{` 必须从第 1 列开始。在 TEAM/LOOP/IFEX 内部，`{` 启动命令组。\n9. **行续接**：行首第一个非空格字符为 `\\` 时，将该行合并到上一行。\n10. **`_SUB`、`WRIT`、`LOOP` 不能内联**：不能在 FIND/IFEX/TEAM 命令内部定义 `_SUB`。`WRIT` 和 `LOOP` 也必须位于单独一行，不能嵌套在 FIND/IFEX/TEAM 内。\n11. **空字符串检测**：`FIND $%var%=,` 测试\"为空\"。`FIND *=var,` 也测试\"为空\"（惯用法）。`FIND *<>var,` 测试\"非空\"。\n12. **字面 %**：字符串中表示字面 `%` 用 `%%`。\n13. **线程安全**：线程创建时，**共享点之后**的 PE 变量复制到子线程。持久栈上下文（窗口、`*` 函数）中的变量是**共享**的（非复制）；非持久上下文（普通函数、`{}` 块）中的变量自动复制一份。真正跨线程通信用 `&::` 变量。\n14. **中文变量名**：PECMD 社区的事实标准。为这个生态系统编写脚本时使用中文名称。\n15. **OnShutdown.wcs**：PECMD 在关机/重启/注销前自动运行 `%SystemRoot%\\System32\\OnShutdown.wcs`，格式为 `OnShutdown.wcs <操作码> [脚本参数表]`。操作码：`shutdown`=关机、`reboot`=重启、`logout`=注销、`suspend`=挂起、`hiber`=休眠、`poweroff`=关电、`lock`=锁定计算机、`unknown`=未知。关机菜单支持的子集：`shutdown`、`reboot`、`logout`、`poweroff`、`unknown`。\n16. **`^` 预解释**：`^COMMAND` 将变量展开推迟到执行时（循环中必备）。`^^COMMAND` 预解释两次。\n17. **MSG 上的 `_` 前缀**：控件通知用 `_msg#`；窗口级消息省略 `_`。搞错这一点是非常常见的错误。\n18. **THREAD\\* 与 THREAD**：只有持久（窗口）栈中的 THREAD* 共享 PE 变量。在 `{}` 块中，两者都复制。\n19. **FIND 展开规则**：FIND 中的裸标识符被视为字面字符串。始终使用 `FIND $%&var%=值` 引用 PE 变量。\n20. **`@@Visible` 与 `@Visible`**：跨进程用 `ENVI @@Visible=窗口ID:值`。进程内用 `ENVI @控件.Visible=0|1`。\n21. **FORX 变量引用**：`FORX ... &&item, { }` 定义用 `&&item`，循环体内引用值用 `%&item%`（单&）。用 `%&&item%` 会找不到变量。\n22. **FIND --wid\\*@ 输出格式**：`序号 窗口ID 控件ID 父窗口ID 线程ID 进程ID 类型 标题`，字段用 **TAB** 分隔。配合 `FORX *NL` 按行遍历、`MSTR*` 按 TAB 分字段提取（field 2=窗口ID, field 7=类型, field 8=标题）。\n23. **DLL 调用不可用时**：优先用 `FIND --wid*@`（窗口枚举）、`FIND --pid*@`（进程枚举）、`REGI`（注册表）、`EXEC*`（外部命令）替代。\n24. **`Visible` 与 `Visable`**：两者均可工作（PECMD 接受两种拼写）。文档统一用 `Visible`，但 SDK 示例普遍用 `Visable`。\n25. **FORX *NL: 自定义分隔符**：`FORX *NL:| &data,&&item,` 用 `|` 作为行分隔符（默认为换行）。\n26. **ENVI^ ALIAS 包装 DLL**：`ENVI^ ALIAS GetTick=CALL $ --ret:&&r kernel32.dll,GetTickCount` 使 `GetTick` 可作为伪命令直接调用。\n\n## $9 参考文件\n\n当需要超越上述快速参考的详细信息时，查阅以下权威文件：\n\n| 文件 | 何时查阅 |\n|------|----------|\n| `references/commands-full.md` | 命令语法、全部标志、参数细节 |\n| `references/pecmd-gui.md` | GUI 控件、消息、窗口生命周期、ENVI @ 属性 |\n| `references/pe-startup.md` | WinPE 启动脚本、PECMD.INI 结构、启动阶段 |\n| `references/how-tos/storage.md` | 磁盘、分区、文件、注册表、设备 写法示例 |\n| `references/how-tos/system.md` | 进程、线程、定时器、系统信息、加密、工具 |\n| `references/how-tos/gui.md` | GUI 模式：动态控件、选项卡、GDI、拖放等 |\n| `references/how-tos/net.md` | 网络、SOCK、COM/WMI 写法示例 |\n| `references/troubleshooting.md` | 常见错误排查、DLL 调用失败、变量引用问题 |\n\n## $10 输出规范\n\n编写 PECMD 脚本和工具时遵循以下规范：\n\n1. 中文脚本首行 `#code=65001`，随后 `ENVI^ EnviMode=1`，再 `ENVI^ ForceLocal=1`\n2. 默认使用中文变量名——PECMD 社区的事实标准\n3. 除非明确需要环境变量，始终使用 PE 变量（`&变量名`）\n4. 大量使用 `TEAM` 链式组合紧凑的初始化序列\n5. 将复杂操作拆分为命名清晰的 `_SUB` 函数\n6. GUI 中用 `ENVI @控件.POS=?` 保存初始控件位置，在 resize 事件中恢复\n7. 可调大小的窗口务必处理 WM_SIZE（0x0005）以重新计算布局\n8. 调用外部程序优先用 `EXEC =!\"%MyNAME%\" ...` 或 `EXEC* &out=!cmd.exe /c ...`\n9. 线程安全：跨线程通信用 `&::` 类 PE 变量\n10. 生产代码：用 `{ LOCK #pecmd ... }` 块包装互斥操作\n11. 控件消息用 `_` 前缀（`_0x0201`）；窗口级消息省略 `_`（`0x0010`）\n12. 用 `SED` 做正则替换（始终正则模式，`.` 匹配任意字符，`\\.` 匹配字面量句号），用 `MSTR` 从结构化输出中提取字段——如果 MSTR 不工作，改用 `FORX *` 逐字段拆分\n\n\n---\n\nGitHub: https://github.com/VirtualHotBar/PECMD-Pro-Max\nClawHub: https://clawhub.ai/virtualhotbar/pecmd-pro-max\n\nFile v1.7.1:README.md\n\n# PECMD Pro Max\n\n> PECMD2012 脚本编程的 AI 技能文件 —— 让 AI 编码助手一次写出正确的 WinPE 工具、GUI 和启动脚本。\n\n简体中文 | [English](./README.en.md)\n\n[![Version](https://img.shields.io/badge/version-1.5.1-blue)](./SKILL.md)\n[![License](https://img.shields.io/badge/license-NonCopyRight-yellow)](./LICENSE)\n[![PECMD](https://img.shields.io/badge/PECMD-v1.88+-green)](https://pecmd.net)\n\n## 这是什么？\n\nPECMD Pro Max 是一个 **AI 编码助手技能文件**，教会 AI 如何编写正确的 PECMD2012 脚本。PECMD 是 WinPE 指挥官 —— 一种用于 Windows PE 启动脚本、轻量级 GUI 系统工具、磁盘实用程序和预安装环境自动化的脚本语言与命令解释器。其变量作用域规则、十六进制内存模型和窗口系统以复杂著称。本技能编码了十多年的 PECMD 脚本知识，让 AI 助手能够一次写出生产就绪的 `.wcs` / `.wci` / `.wce` 文件，无需反复试错。\n\n## 文件结构\n\n```\npecmd-pro-max/\n├── README.md                        ← 你正在阅读\n├── README.en.md                     ← English version\n├── SKILL.md                         ← 主技能文件 — 心智模型、变量系统、关键规则、陷阱（561行）\n└── references/\n    ├── commands-full.md             ← 110+ 条命令完整参考（1943行）\n    ├── pecmd-gui.md                 ← 完整 GUI 控件与窗口系统参考（2178行）\n    ├── pe-startup.md                ← WinPE 启动流程、环境限制、PE版本差异\n    └── how-tos/\n        ├── storage.md               ← 磁盘/分区/文件/注册表/设备 写法示例\n        ├── system.md                ← 进程/线程/系统/工具/回调 写法示例\n        ├── gui.md                   ← GUI 控件/窗口/绘制 写法示例\n        └── net.md                   ← 网络/SOCK/COM/WMI 写法示例\n```\n\n## 核心特性\n\n- **三层变量系统详解** —— 环境变量 vs PE-局部 vs PE-全局，间接引用、延迟展开、引用返回、十六进制/原始缓冲区分配、二进制比较/转换\n- **110+ 命令参考** —— 每条 PECMD 命令包含完整语法、返回值、陷阱说明（含 BROW、TREE、LAMBDA、SBAR、IPAD、BLOCK、DTIM、SLID、SPIN）\n- **按域组织的写法示例** —— 磁盘/分区、进程/线程、GUI控件/绘制、网络/COM，按主题独立文件，AI按需加载\n- **完整 GUI 参考** —— 所有 25 种控件与子窗口（`LABE`、`EDIT`、`CHEK`、`RADI`、`IMAG`、`TABL`、`LIST`、`MEMO`、`TREE`...）、ENVI @ 控件属性大全、消息系统、窗口管理\n- **WinPE 启动流程** —— 从 `winpeshl.exe` → `PECMD MAIN PECMD.INI` 直至 `EXPLORER.EXE`，包含 `WinXShell` 集成\n- **50 个内置变量全表** —— 路径/Shell变量、进程/线程变量、窗口/GUI变量、脚本/运行时变量、命令结果变量\n- **17 个 ENVI 运行时控制命令** —— EnviMode、ForceLocal、Alias、WndProc、memvar、LoadPlugin、DisX64、zero、Arg、Clipboard、EnviBroad、__arg、LoadEnvi、HelpColor、DeskTopFresh(@@)、TaskIcoMenu(@@)、EXPORTLOCAL\n- **ForceLocal + EnviMode 默认值** —— 确保每个生成的脚本都使用最安全的变量作用域\n- **代码组织规则** —— `_SUB` 声明时解析 vs 运行时调用、`SET^` Win32 回调绑定、`CALL @` 变体速查表\n- **ENVI @ 控件属性大全** —— 通用属性、EDIT/ITEM/窗口专用、TABL 30+ 操作、TREE 10+ 操作、跨进程控制\n\n## 快速上手\n\n```wcs\n#code=65001\nENVI^ EnviMode=1\nENVI^ ForceLocal=1\nSET$ &NL=0d 0a\n\n_SUB MainWin,L200T100W400H200,你好世界,-trap\n    LABE Lbl1,L20T30W350H24,欢迎使用 PECMD\n    ITEM Btn1,L150T120W80H28,关闭,CALL CloseMe\n_END\n\n_SUB CloseMe\n    KILL \\\n_END\n\nCALL @MainWin\n```\n\n## 安装\n\n将 `pecmd-pro-max/` 文件夹复制到 AI 编码助手的技能目录：\n\n- **Claude Code**: `~/.claude/skills/pecmd-pro-max/`\n- **OpenCode**: `~/.config/opencode/skills/pecmd-pro-max/`\n\n## 运行要求\n\n- [Claude Code](https://claude.ai)、[OpenCode](https://opencode.ai) 或任何支持 agent 技能的兼容 AI 编码工具\n- [PECMD2012](https://pecmd.net) v1.88+（执行生成脚本的解释器）\n\n## 协议\n\n**NonCopyRight** —— 本技能完全自由、开源、无限制。随意使用、修改、用于商业产品。无需署名。无任何限制。\n\n---\n\n源码仓库：[github.com/VirtualHotBar/PECMD-Pro-Max](https://github.com/VirtualHotBar/PECMD-Pro-Max)\n\nClawHub：[clawhub.ai/virtualhotbar/pecmd-pro-max](https://clawhub.ai/virtualhotbar/pecmd-pro-max)\n\nFile v1.7.1:_meta.json\n\n{\n  \"ownerId\": \"kn75c1axscyjtg0wtnnt4h2jjx839hs5\",\n  \"slug\": \"pecmd-pro-max\",\n  \"version\": \"1.7.1\",\n  \"publishedAt\": 1777992449285\n}\n\nFile v1.7.1:references/commands-full.md\n\n# PECMD 命令参考\n\n按类别组织的完整命令参考。所有命令不区分大小写。\n语法约定：`<required>` 为必填，`[optional]` 为可选，`|` 表示多选一。\n\n---\n\n## 脚本结构\n\n### _END\n结束一个 `_SUB` 函数或代码块。\n```\n_END\n```\n必须单独一行。每个 `_SUB` 需要一个对应的 `_END`。\n\n### _ENDFILE\n脚本文件结束。该行之后的代码不会被加载。\n```\n_ENDFILE[-IMPORT]\n```\n`-IMPORT`：仅在文件被 IMPORT 时生效。\n\n### _SUB — 定义函数 / 类 / 窗口\n```\n_SUB FuncName [*]                   // 函数 (* = this-call，使用调用者栈)\n_SUB FuncName,*,,destroyCmd         // 带析构命令的函数\n_SUB WinName,<shape>,[title],[closeCmd],[icon],[style],[mask] [-flag1 -flag2 ...]  // 窗口\n```\n窗口形状：`LleftTtopWwidthHheight`。省略 L/T 为居中。\n窗口标志：\n`-top`（始终置顶），`-nocap`（无标题栏），`-nosysmenu`（无系统菜单），\n`-trap`（关闭时不退出），`-size`（可调整大小），`-maxb`（启用最大化），\n`-minb`（启用最小化），`-disminb`（禁用最小化按钮），\n`-discloseb`（禁用关闭按钮），`-nfocus`（不接受键盘焦点），\n`-ntab`（无 Tab 键导航），`-disaltmv`（禁用 ALT 拖动），\n`-forcenomin`（阻止最小化），`-scalef`（XP 风格 DPI 缩放），\n`-scale[:DPI]`（Win8+ DPI 缩放），`-nxp`（无 XP 视觉样式），\n`-csize`（尺寸=客户区），`-na`（创建时不激活）\n样式：`[#][$]`数字 表示透明度，`,#` 表示隐藏窗口。\n遮罩：`[color][*][w:h]bmpname` 用于异形窗口。\n\n### CALL — 调用函数/窗口/DLL\n```\nCALL FuncName [args...]               // 调用函数\nCALL *FuncName [args...]              // this-call（使用调用者栈）\nCALL @WinName [args...]              // 创建/显示窗口（模态，会阻塞）\nCALL @*WinName [args...]             // 并行窗口\nCALL @-WinName [args...]             // 后台窗口\nCALL @~WinName [args...]             // 后台，非阻塞\nCALL @+WinName [args...]             // 抛弃式子窗口\nCALL @^WinName [args...]             // 并行，父窗口不阻塞子窗口\nCALL @--popmenu WinName [x.y[:align]] // 弹出菜单\nCALL @--WinName                      // 销毁 Win 环境\nCALL @WinName                        // 初始化 Win 环境\n\n// DLL 调用（缓冲区输出用 `*&buf` 形式传递，见下方说明；需要 PECMD2012 v1.88+ 完整版）\nCALL $[? --cd --nrcd --c --[[i]v]ret:[~@]retVar] DLL|*hDll,Func,[#]p1,[#]p2...\nCALL $--ret:retVar [--cd],[--nrcd],-LoadLibrary,[^]DLLpath     // 加载 DLL（^=自动释放）\nCALL $--ret:retVar [&&memVar],-LoadLibrary,*[file]#resID[|type] // 从内存加载\nCALL $--ret:retVar ,-GetProcAddress,*hDll,FuncName             // 获取函数地址\nCALL $[--ret:retVar] ,-FreeLibrary,*hDll                        // 释放 DLL\nCALL $--win [--qd@ --cd --nrcd --ret:retVar] DLL,Func,cmdLine   // rundll32\nCALL $--cpl CPLpath                                             // 控制面板\nCALL $--ret:var ,-LoadLibrary,^<DLLpath                         // COM DLL 加载\n```\nDLL 标志：`--cd`=切换目录，`--nrcd`=不恢复目录，`--c`=C 调用约定（默认 PASCAL/stdcall），\n`--bool`=BOOL 返回，`--ret:*`=通过指针返回，`--m`=内存中，\n`--1`=剩余全部作为一个参数，`--co`=注册 DLL（默认），`--nco`=不注册 DLL。\n`--qd`=启用类型前缀系统（qualified mode），允许用 `#`/`$`/`*` 等前缀为每个参数指定类型。\n\n**类型前缀系统（--qd）：** 每个参数的类型覆盖，使用 `--qd:类型1,类型2,...`\n| 前缀 | 类型 | 描述 |\n|--------|------|-------------|\n| `#` | integer | 按整数传递（数字的默认方式） |\n| `<` | INT64 | 64位整数 |\n| `*` | PE variable | 按 PE 变量指针传递 |\n| `$` | string | 按字符串传递（Unicode） |\n| `=` | raw | 按原始数据传递 |\n| `>` | VARIANT | 按 VARIANT 传递 |\n| `@` | narrow | ANSI 窄字符串 |\n| `~` | UTF8 | UTF-8 字符串 |\n\n附加标志：\n```\n--sret           // 返回符号数量\n--16             // 以十六进制返回\n--iret:retVar    // 以 INT 返回\n--vret:[~@]var   // 返回 VARIANT（~=剥离，@=原始）\n--arg:~.table    // 参数备选格式（~=去除引号）\n.vFun:index      // 虚函数索引\n.vFun:[?]name    // IDispatch 函数名（[propget] 前缀已移除）\n--get / --put    // COM 属性 获取/设置\n?                // 查询 DLL 函数地址（存入返回变量）\n^<               // COM DLL 加载前缀\n^                // 变量超出作用域时自动释放\n```\n\n**实测验证的调用格式（PECMD2012 v1.88+, 32-bit / 64-bit 行为一致）：**\n- 正确格式：`CALL $ --qd --ret:&&r DLL,Func,#intParam,$strParam`（逗号分隔，`#` 整数，`$` 字符串）\n- `--qd` 影响字符串传递方式（无 --qd 时字符串多含 null 终止符，建议始终加 `--qd`）\n- 点语法（`Func.#param`）不工作，整数无 `#` 前缀返回 0\n- **缓冲区输出**：`*&buf` 形式传递 PE 变量地址，DLL 写入可回传；`SET$#` 原始缓冲区 + `*` 不加 `&` 可能不回传\n- `GetProcAddress` 始终返回 0x0（实现问题），建议直接用函数名调用\n- 整数返回和字符串输入参数正常工作，32-bit 和 64-bit 行为完全一致\n\n地址调用：DLL 路径=`#`，函数=原始地址。函数名加 `*` 前缀 = 取地址。参数加 `&` 前缀 = 组合变量地址。\n内置：`-DllRegisterServer` / `-DllUnregisterServer`。\nDLL 架构必须与 PECMD 进程（x86/x64）匹配。\n\n### EXIT — 终止\n```\nEXIT FILE      // 终止整个脚本\nEXIT WIN       // 退出当前窗口（销毁窗口环境）\nEXIT _SUB      // 退出当前函数\nEXIT LOOP      // 跳出循环（同 EXIT BREAK）\nEXIT FORX      // 跳出 FORX 循环（同 EXIT BREAK）\nEXIT CONTINUE  // 继续下一次迭代（LOOP/FORX）\nEXIT BLOCK     // 跳到当前 {} 块尾部\nEXIT -         // 同 EXIT BLOCK\nEXIT _SIB      // 跳过当前 FORX 迭代的剩余兄弟命令，进入下一迭代\nEXIT ToWin     // 中止函数执行，立即返回窗口消息循环（推荐使用）\n```\n\n### IMPORT — 包含库文件\n```\nIMPORT path\\to\\library.wcs\n```\n从另一个文件导入函数。被导入文件中 `_ENDFILE-IMPORT` 会排除尾部内容。\n\n### LAMBDA — 匿名代码块\n```\n[]参数列表{ 函数体 }\n```\n`[]` 分隔参数列表，`{}` 分隔函数体。在文件级立即执行（非可调用函数）。\nLAMBDA 拥有独立栈，退出时 PE 变量、锁、控件、HKEY 自动销毁。\n`_SUB` 本质上是 LAMBDA；LAMBDA 的独特之处在于可访问调用者栈。\n在命令群组（TEAM）内的 LAMBDA 函数体被解释为变量字符串，`%` 必须写为 `%%`。\n```\n// 示例：文件级内联块\n[]P1 P2{ WRIT -,$+0,%P1% %P2% }\n\n// 在 _SUB 内使用\n_SUB MyFunc\n    []%~1%{ MESS Hello %1! }\n_END\n```\n\n### LOAD — 执行脚本文件\n```\nLOAD path\\to\\script.ini [args]\nLOAD #101 [args]                           // 从 EXE 资源中执行内置脚本\nLOAD --mem &var [args]                     // 执行变量中存储的代码\nLOAD --Local --EnviMode path.ini           // 以 ForceLocal=1 + EnviMode=1 模式运行\nLOAD --ncd path.ini                        // 不转移当前目录和环境变量（多线程安全）\nLOAD --logs:[*]logFile path.ini            // 日志输出重定向（* = 同时输出到 stdout）\nLOAD - path.ini                            // 不转移持久栈\nLOAD -* path.ini                           // 不转移持久栈和执行栈\nLOAD -del path.ini                         // 加载后删除该脚本\nLOAD path\\*.ini *FuncName args             // 调用脚本中的指定函数\n```\n加载优先级：PEI > #number > WCI/WCS/WCE/WCZ > EXE/COM/NTR/NTE/BAT/CMD > DLL。\n\n### THREAD / THRD — 创建线程\n```\nTHREAD[*][&][+][$][#] [-exp] [-wait[x][-here]] [-tid:var] [--st:stackSize] command\n```\n`*` = 立即执行，`&` = 强制 PE 变量模式，`$` = 预解释，`+` = 抛弃式线程，\n`#` = 代理/线程模式（线程结束后代理退出），前缀 `&*+$` 无固定顺序。\n`-wait` = 等待完成，`-tid:var` = 获取线程 ID\n\n附加标志：\n`-link` = 维护父子窗口连接，\n`-waitp` = 线程前等待进程结束，\n`-here` = 当前栈子线程（修改执行栈），\n`-htid:var` = 获取线程句柄\n\n---\n\n## 变量与数据\n\n### ENVI / SET — 设置/查询变量\n```\nENVI (SET) [&][$][@]VarName=Value\nENVI^ EnviMode=1|ForceLocal=1|FORCELOCAL=1|LoadEnvi [...]\nENVI $var=val              // 设置环境变量\nENVI &var=val  (alias: SET var=val)   // 设置局部 PE 变量\nSET &::var=val             // 设置类/全局 PE 变量\nENVI-def var=val  (alias: SET-def var=val)  // 仅当变量尚未定义时设置\nENVI-ret[level] %~1=%val%  // 按引用返回（默认 level=1）\nENVI~ &&Dst=Source.Key     // ~ = 间接展开\n```\n控件操作：\n```\nENVI @Ctrl=Text                   // 设置控件文本\nENVI @Ctrl.Enable=0|1             // 禁用/启用\nENVI @Ctrl.Visible=0|1|*4        // 隐藏/显示/最小化\nENVI @Ctrl.POS=l:t:w:h            // 移动/调整大小\nENVI @Ctrl.POS=?&L:&T:&W:&H     // 查询位置\nENVI @Ctrl.Check=0|1|2|-1|-2       // 复选框状态（1/-1=选中，0/2/-2=未选，<0=灰色，±16=不可见）\nENVI @Ctrl.Val=data               // 设置内容\nENVI @Ctrl.Val=?row.col;&var      // 获取单元格（分号分隔）\nENVI @Ctrl.Val=?*;&count          // 获取行数\nENVI @Ctrl.Val=-*                 // 清除所有行\nENVI @Ctrl.Val=1*;%&data%         // 从变量批量设置\nENVI @Ctrl.Sel=idx|idx;0          // 选中/取消选中\nENVI @Ctrl.MSG=_msgId:cmd         // 消息映射（控件通知使用 _）\nENVI @Ctrl.POSTMSG=#msg;wp;lp     // 异步发送消息\nENVI @Ctrl.SENDMSG=#msg;wp;lp     // 同步发送消息\nENVI @Ctrl.*del=                  // 销毁控件\nENVI @Ctrl.ID=?&hwnd               // 获取控件 HWND\nENVI @Ctrl.Font=size:name\nENVI @Ctrl.bkcolor=0xRRGGBB\nENVI @Ctrl.Cursor=32649           // 手型光标\nENVI @@POS=wid:l:t:w:h:layer:trans:front:activate  // 设置窗口位置\nENVI @@POS=?wid:&L:&T:&W:&H:&SX:&SY::&Z  // 查询（含屏幕坐标和层叠序）\nENVI @@Visible=wid:0|1|*4        // 跨进程可见性（0=SW_HIDE, 1=SW_SHOW, 3=SW_MAXIMIZE, 4=SW_MINIMIZE 等）\nENVI @@Enable=wid:[#]0|1         // 跨进程禁用/启用（#=子线程）\nENVI @@Visible=?wid:&var         // 查询跨进程可见状态\nENVI @@Enable=?wid:&var          // 查询跨进程可用状态\nENVI @@IsWindow=?wid:&var        // 查询是否为有效窗口\nENVI @@SENDMSG=hwnd:#msg;wp;lp  // 跨进程同步发送消息（如 SendMessage）\nENVI @@POSTMSG=hwnd:#msg;wp;lp  // 跨进程异步投递消息（如 PostMessage）\nENVI @Win.Paint=funcName         // 画布回调（参数：HDC 宽 高）\nENVI @Win.HitTest=[-]h[:w:x:y]  // 拖动敏感区域（高=0取消，-=半透明穿透）\nENVI @Win.trans=0|1|0x2[*]      // 背景透明（0x1=透明模式，0x2=完全透明，*=透明色）\nENVI @Win.style=[@*]remove[:add] // 窗口风格操作（@=直接，*=扩展）\nENVI @Win.InvalidateRect=[左:上:右:下]|#WID|@SubName[~扩量][:擦除]  // 刷新区域\nENVI @Win.cmd[?]=var|cmd         // 动态设定/查询响应命令（?需 ENVI^ QueryCmd=1）\nENVI @Win.nxp=                   // 禁用 XP 视觉样式\nENVI^ Clipboard=text             // 写入剪贴板\nENVI^ Clipboard?=var             // 读取剪贴板到变量\nENVI^ EXPORTLOCAL=1|0|&1|&0      // PE 变量继承：1=继承，0=隔离（默认），&1=仅本级及以下继承，&0=仅本级及以下隔离\nENVI^ DisX64=1[,Old]             // 禁用 WOW64 文件系统重定向（Old=保存原状态用于恢复）\nENVI^ Arg=*                      // 将单词拆分为参数\nENVI @@DeskTopFresh=[clearicon][;][1|2|4|8|16][;[-+]path]  // 桌面刷新\nENVI @@TaskIcoMenu=0|1|2         // 托盘菜单切换\nENVI^ HelpColor=[*cmdHeight] [fgColor][#bgColor]  // HELP 显示颜色\nENVI^ Alias name=cmd              // 命令别名：替代命令前半部\nENVI^ Alias -opt name=cmd         // -opt 优化模式\nENVI^ WndProc[1|2|3][C][,ptr]    // Win32 回调绑定（C=C 调用约定）\nENVI^ memvar=[?返回名,][:字节数:]偏移,值  // 修改/查询 PECMD 内存变量\nENVI^ LoadPlugin=basename         // 加载插件\nENVI^ zero=0|1                    // 私密模式：内存用完清零\nENVI^ EnviBroad=0|1|-             // 环境变量广播开关：1=开启，0=关闭，-=后台\nENVI^ __arg=0|1                   // 兼容模式：启用 &&__arg 参数表\nENVI^ LoadEnvi [路径|-] [变量名]  // 从注册表刷新环境变量\nENVI^ QueryCmd=1                   // 启用 @控件.cmd?=变量名 动态命令查询\n```\n\n### ENVI ? — 系统查询\n```\nENVI ?返回名=PPID,进程号           // 查询父进程 ID\nENVI ?返回名=ISADMIN               // 是否管理员（1/0）\nENVI ?返回名=ispe                  // 是否 PE 环境\nENVI ?字符串名,数字名=PEBIT,[path] // 查询位数（32/64）\nENVI ?返回名=WinVer[+][;...]       // Windows 版本信息\nENVI ?[$.]返名[,属性名]=FVAR,varName[;GUID]  // EFI 固件变量\nENVI ?[单个名],[全部名]=DROPFILE,wParam  // 拖放文件信息\nENVI ?文件版本名[,产品版本名][,2]=FVER,文件路径  // 文件版本查询（2=文件自身版本）\nENVI @@Cur=?[X名][;Y名]           // 鼠标位置查询\nENVI @@EATEKEYS=组合键1 ...        // 按键拦截\nENVI @@RMENU=变量名;文件名         // 获取文件右键菜单（多行，空行为分隔符）\n```\n\n### CALC — 计算/求值\n```\nCALC[-u|-txt|-cb-[Lfr:Lto[:Rfr:step]]] [-gui] [-base=[u]2|8|10|16|N] [-err=defaultValue] [#][变量=]表达式[#[#][小数位][E|F|G]]\n```\n`#` 前缀 = 整数模式。支持：`+ - * / % ^`，位运算 `& | @`，比较 `= <> > >= < <=`，\n逻辑 `&& ||`。函数（共34个）：`abs sin cos tan ctg sqrt ln lg log pow exp pow10`，\n`floor ceil round int frac div mod rand shl shr xor not lnot`，\n`arcsin arccos arctan arcctg deg rad hypot max min`。\n`lnot` = 逻辑非（`!a`），`not` = 按位非（`~a`）。常量：`e`，`pi`。\n⚠ `log()` 需两参数 `log(底数,值)`，单参数返回 0；用 `lg()` 代替 log₁₀，`ln()` 为自然对数。\n尺寸后缀：`K`=1024，`M`=1024^2，`G`=1024^3，`T`=1024^4，`S`=512。\n结果加 `#` = 整数，结果加 `$` = 双精度（INT64/float）。\n`-base=[u]2|8|10|16|N` — 输出进制（`u` = 无符号）。`-gui` — 图形界面计算器。\n`-err=defaultValue` — 出错时返回默认值。\n`-u` — 无符号输出修饰符（直接跟在 CALC 后面，无空格）。\n`-txt` — 文本模式（直接跟在 CALC 后面）。\n`-cb` — 剪贴板模式（直接跟在 CALC 后面）。\n`-[Lfr:Lto[:Rfr:step]]` — 向量操作模式（`Lfr:Lto` 为左侧行从/到范围，`Rfr` 为右侧起始，`step` 为步长）。\n`CALC -base=16 #&hex=shl(0x07,16)|0x20` — 十六进制位运算。\n`CALC &sz=%&bytes%/1G#3` — 字节转 GB，3 位小数。\n多个表达式：用 `;` 或换行分隔。子变量：`#subName` = 整数子变量，`$subName` = 浮点子变量。\n\n### CODE — 编码转换\n```\nCODE -srcFmt,srcFile,-dstFmt,dstFile\nCODE **-GBK,&src,**-UNI,&dst\n```\n格式：`-ANSI`，`-UNICODE`，`-UTF8`，`-UTF7`，`-GBK`，`-BIG5`，`-UNICODEB`，`-BOM`\n\n### SET$ / ENVI$ — 从十六进制创建字符串\n```\nSET$ &Var=0d 0a                   // 变量 = CR+LF（Unicode 宽字符串）\nSET$# &Buf=*4096 0                 // 分配零填充的原始字节缓冲区\nENVI$ &data=*1M 30 0d 0a          // 可变长度分配\n```\n\n### SET-def — 仅当未定义时设置\n```\nSET-def Var=DefaultValue\n```\n\n### SET-copy — 原始字节复制\n```\nSET-copy Dst=&src;srcOff;len;dstOff\n```\n\n### SET-long / SET-short / SET-ptr — 写入类型化值\n```\nSET-long &buf=value:offset         // 在缓冲区偏移处写入 32 位整数\nSET-short &buf=value:offset        // 16 位\nSET-ptr &buf=value:offset           // 指针大小\n```\n\n### SET?int / SET?longlong / SET?char — 读取类型化值\n```\nSET?int &buf=&&Var:offset\nSET?longlong &buf=&&Var:offset\nSET?char &buf=&&Var:offset\nSET?short &buf=&&Var:offset              // 读取 SHORT\nSET?ptr &buf=&&Var:offset                // 读取指针大小值\n```\n\n### ENVI-* — 内存基元（二进制数据操作）\n```\nENVI-mkfixdummy &&var=源变量@偏移       // 创建固定虚拟变量（内存不可变）\nENVI-mkdummy &var=地址;字节数            // 从地址创建虚拟变量\nENVI-addr &&ptr=源变量                   // 获取变量内存地址和长度\nENVI-long &buf=value:offset              // 写入 LONG (32位)\nENVI?long &var=源变量:offset             // 读取 LONG\nENVI?short &var=源变量:offset            // 读取 SHORT\nENVI?char &var=源变量:offset             // 读取 CHAR\nENVI?int64 &var=源变量:offset            // 读取 INT64\nENVI?ptr &var=源变量:offset              // 读取指针\n```\n\n### struct — C 风格结构体定义\n```\nstruct 结构体名\n{\n    __virtual 返回类型 STDMETHODCALLTYPE 方法名(参数列表);\n    成员类型 成员名;\n    ...\n};\ntypedef 类型别名 原类型;\n```\n配合 `SET-*结构体 变量.成员=值` 和 `SET?*结构体 变量.成员=&目标` 读写。\n\n### SET-make / ENVI-make — 从缓冲区取子串\n```\nSET-make &&Str=&buf@offset;$length           // $ 固定长度\nSET-make &&Str=&buf@offset;(%expr%*2)        // ;(...) 计算表达式作为长度（⚠语法待确认）\n```\n\n### SET< / ENVI< — 追加到变量\n```\nSET< Var=text to append\n```\n\n### ENVI-addr — 获取缓冲区地址\n```\nENVI-addr &&ptr=&buf                // 获取地址（单返回值）\nENVI-addr ;&len=&buf                // 获取地址和字节长度（双返回值，分号分隔）\n```\n\n### ENVI-mkdummy — 虚拟指针/长度描述符\n```\nENVI-mkdummy &&Name=&buf@offset;length\n```\n\n### SET-cmp — 二进制比较\n```\nSET-cmp dst=src;srcOff;len;dstOff;[S|s|I|i]\n```\nS/I = 宽字符，s/i = 窄字符，I/i = 不区分大小写。\n\n### SET-tom / SET-tow — 编码转换\n```\nSET-tom dst=src       // UNICODE 转多字节（如 GBK）\nSET-tow dst=src       // 多字节转 UNICODE\n```\n\n### SET-swap — 交换变量内容\n```\nSET-swap var1=var2\n```\n\n### SET-zero — 清除变量内存\n```\nSET-zero var=[value][@offset][;count]\n```\n`$` 前缀用于宽字符模式。\n\n### ENVI-ex — 检查变量是否存在\n```\nENVI-ex retVar=varName\n```\n\n### ENVI-tom — 字符串转指针\n```\nENVI-tom &&dst=&src    // 将字符串转换为内存指针\n```\n\n### SET-mkfixdummy — 固定虚拟变量（内存不可变）\n```\nSET-mkfixdummy PE变量名=[地址][;[*][字节数]]\n```\n同 `SET-mkdummy`，但所引用的内存不会变动（fixed dummy）。\n\n### SET-addr — 获取地址和长度\n```\nSET-addr [地址名][;长度名]=源PE变量名\n```\n返回源 PE 变量的内存地址和字节长度到指定变量。\n\n### SET-*结构体 / SET?*结构体 — 结构体读写\n```\nSET-*结构体 PE变量名.成员=数值[:[~]附加总偏移字节数]         // 写入结构体成员\nSET?*结构体[:0[@]s] 源PE变量名.成员=变量名[:[~]附加总偏移字节数]  // 读取结构体成员\n```\n`0`=补零，`@`=去掉 0x 前缀，`s`=带符号。`~`=偏移以类型大小为单位。\n配合 `struct` 块定义的 C 风格结构体使用。\n\n### ENVI 后缀变体 — 临时模式切换\n```\nENVI -env ...                     // 临时取消 forceLocal（必须为第一个后缀）\nENVI -std ...                     // 临时设置 EnviMode=1（必须为第一个后缀）\nENVI -raw ...                     // 等号右侧不解释\nENVI -get[N] ...                  // 回溯 N 级（默认 1）获取 PE 变量\nENVI -ret[N] ...                  // 回溯 N 级（默认 1）操作 PE 变量名\nSET-env ...                       // 等价于 ENVI -env &...（SET 也可用 -env 后缀）\n```\n`-env` 和 `-std` 便于操作环境变量；`-get` 用于函数传入 PE 变量名时获取；`-ret` 用于函数返回时操作。\n`SET-env` 临时取消 ForceLocal，用于 SET 命令需要读写环境变量的场景。\n\n### 析构函数语法\n```\nENVI ~析构函数~变量名=初始值       // 定义时指定析构函数，退出变量定义范围时自动调用\n// 调用形式：析构函数 变量引用 变量值\n_SUB 函数名,*,,析构命令            // _SUB 也支持析构命令（返回前自动执行）\n```\n\n---\n\n## 流程控制\n\n### FIND — 字符串比较\n```\nFIND $str1=str2, command        // 等于（不区分大小写，*c 后缀区分）\nFIND $str1<>str2, command       // 不等于\nFIND $=%var%, command           // 变量为空\nFIND $%var%=, command           // 变量为空（同上，变量在左侧）\nFIND *=var, command              // 惯用法：变量为空（主要源模式）\nFIND *<>var, command             // 惯用法：变量非空\nFIND $str1=str2,! cmd1! cmd2   // if else（用 ! 分隔）\nFIND $str1=str2,!! command      // 仅 else\nFIND |num1>num2, command        // 数值比较\nFIND $'%var%'='', command       // 安全的空值检查（单引号保护）\nFIND [$][A & B], command         // 复合 AND（条件之间用 &）\nFIND [$][A | B], command         // 复合 OR（条件之间用 |）\nFIND --pid &var,ProcessName            // 获取进程 PID\nFIND --pid &var                        // 返回 5 个值：空闲时间 总时间 CPU个数 1秒时钟数 一时钟100ns数\nFIND --pid*@[.ext|#parentPID] &var,    // 进程列表（可选：扩展名过滤或父进程 PID）\nFIND [--user] --pid*@[.ext|#parentPID] &var,prog[|用户名]  // 按用户名过滤进程\nFIND [--sub][--forpid:PID|--fortid:TID] --wid*@[parentWID] &var,[title]   // 窗口列表（* = 标题前缀匹配）\n                                         // --sub=递归子窗口，--forpid=按进程过滤，--fortid=按线程过滤\nFIND --wid#ParentWID &var,ControlID    // 查询控件的窗口 ID\nFIND --class:ClassName --wid*@ &var    // 按窗口类名过滤窗口列表\nFIND --menu &var,WindowID              // 查询窗口的 MENU 句柄\nFIND --menu#Index &var,MenuID          // 按索引查询子 MENU\nFIND $!=%var%,                         // 与字面量 \"!\" 比较（特殊：$ 后跟比较操作符）\nFIND C:\\=?,&var                        // 查询磁盘总空间（字节）\nFIND MEMB<比较符>数值, command            // 字节级内存比较（单位：字节）\nFIND R:\\<比较符>数值, command             // 磁盘空间比较（R: 为盘符，单位 MB）\nFIND R:\\<比较符>*数值, command            // 磁盘空间比较（* = 字节单位）\n```\n\n**FIND --pid 输出字段（@=列表模式）：**\n`进程ID  父进程ID  内存K  CPU使用时间(100ns)  总时间  [用户]  文件名  命令行`\n一行一条，以 TAB 间隔。0 进程的 \"CPU 使用时间\" 为系统 \"空闲时间\"。\n\n### IFEX — 文件测试 / 数值比较 / 系统查询\n> **注意**：IFEX 的 `$`/`|` 前缀与 FIND **相反**。IFEX: `$`=数值比较，`|`=字符串比较。\n```\nIFEX path\\|file, command         // 文件存在\nIFEX path\\|file,! command        // 不存在\nIFEX x:\\, command                // 盘符存在且有文件系统\nIFEX $num1>=num2, command        // 数值比较\nIFEX #num1=#num2, command        // 强制整数\nIFEX [ cond1 & cond2 ], command  // AND 复合（条件间用 &、| 或 @）\nIFEX [ cond1 | cond2 ], command  // OR 复合\nIFEX [ cond1 @ cond2 ], command  // XOR 复合\nIFEX MEMU=?,&var                 // 查询可用内存（单位 MB）\nIFEX MEMA=?,&var                 // 查询总内存（单位 MB）\nIFEX MEMBU=?,&var                // 查询可用内存（单位字节）\nIFEX MEMBA=?,&var                // 查询总内存（单位字节）\nIFEX drv:\\=?,&var               // 查询磁盘可用空间\nIFEX KEY=?                       // 等待按键\n```\n\n> **复合条件类型前缀：** `[前的$` 或 `[前的|` 表示后续所有条件默认为 `$`（数值）或 `|`（字符串）比较，可省略逐个标注。\n\n### LOOP — While 循环\n```\nLOOP [#]condition,\n{\n    // 循环体\n}\n// BREAK：EXIT LOOP 或 EXIT BREAK\n// CONTINUE：EXIT CONTINUE\n```\n\n### FORX — 迭代\n```\nFORX * list,&&item,                              // 空格分隔迭代\nFORX *NL &multiLine,&&line,                      // 换行分隔\nFORX *NL:| &data,&&item,                         // 自定义分隔符（|为分隔符）\nFORX *v &a &b &c,&&name,                          // 迭代变量名\nFORX /S[:depth] path\\*.ext,&&name,0               // 文件枚举（0=文件，1=目录）\nFORX /S:3 /O:N path\\*.ext,&&f,0                  // 最大深度 3，按名称排序\nFORX /S /O:-N path\\*.ext,&&f,0                   // 深度不限，反向排序\nFORX /S /size:0:1048576:512 path\\*.ext,&&f,0     // 大小 0-1MB，512 对齐（已分配大小）\nFORX /S /size*:0:1048576:512 path\\*.ext,&&f,0    // 同上（* = 实际文件大小，非已分配大小）\nFORX @\\Windows,&&dir,1                            // 搜索目录根\nFORX !\\*.ext,&&f,0                                // 反向目录顺序\nFORX @\\*.ext,&&d,1                                // 仅目录（@ 前缀）\nFORX *ab \\*.ext,&&f,0                             // 排除 A/B 可移动驱动器\nFORX *cur \\*.ext,&&f,0                            // 搜索时优先当前驱动器\nFORX *qu[~] \\*.ext,&&name,0                       // 支持路径中的引号\nFORX *off \\*.ext,&&name,0                         // 仅返回变化部分\nFORX *bf \\*.ext,&&name,0                          // 广度优先目录搜索\nFORX *L start step end,&&val,                     // 数值循环：FORX *L 0 2 10,&&val,\nFORX . \\*.ext,&&f,0                               // ; 可替代 , 作为分隔符\nFORX : \\*.ext,&&f,0                               // : 可替代 , 作为分隔符\n```\n\n### TEAM — 多命令\n```\nTEAM cmd1 | cmd2 | cmd3 ...\n```\n嵌套分隔符：`|`（第1层），`||`（第2层），`|||`（第3层）。\n\n### LOCK — 临界区 / 互斥锁\n```\nLOCK #lockName,&retVar           // 创建/获取命名锁\nLOCK --exist #lockName,&retVar   // 检查锁是否存在（1=是，0=否）\n{ LOCK #pecmd ... }              // 用花括号包裹以创建原子作用域\n```\n\n---\n\n## 文件 I/O\n\n### READ — 读取文件\n```\nREAD[-UNICODE|-UNICODEB|-UTF8|-GBK|-BIG5|-ANSI|-<codepage>] [*fix] path,*r,&var     // 原始（不转换行尾符）\nREAD path,*,&var      // UNIX LF -> 本地\nREAD path,**,&var     // DOS CRLF -> 本地\nREAD -,-1,&count,&var // 获取行数\nREAD -,lineNo,&line,&var  // 读取指定行（lineNo=-1 获取行数）\nREAD -,10,&line,&var  // 从 stdin 读取最多 10 字节\nREAD -*[?],lineNo,&line,&var  // 从变量读取（? = 测试/查询编码）\n```\n编码缩写：`-UNI` = `-UNICODE`，`-UNIBE` = `-UNICODEB`。\n`*[?]` 变量名后缀：用于测试编码（`?` 探测变量内容的编码格式）。\n\n### WRIT — 写入文件\n```\nWRIT[-UNICODE|-UNICODEB|-UTF8|-GBK|-BIG5|-ANSI|-<codepage>] [*fix] [*-nl] [*v] [*fv] [*c] [*nobom]\n    path,[$][+|-]lineID,text\n```\n编码标志（在文件名之前）：`-UNICODE`=带 BOM 的 UTF-16LE，`-UNICODEB`=UTF-16BE，`-UTF8`=带 BOM 的 UTF-8，`-GBK`，`-BIG5`，`-ANSI`，`-<code_number>`=指定代码页。当现有文件有 BOM 时，BOM 优先。\n缩写：`-UNI` = `-UNICODE`，`-UNIBE` = `-UNICODEB`。\n\n星号前缀修饰符：`*fix`=单独的 CR 视为换行，`*-nl`=不添加尾部换行，`*v`=写入变量，`*fv`=FileData 是变量名，`*c`=先清空文件，`*nobom`=写入时不添加 BOM。\n\n位置：`$`=展开环境变量，`+`=插入新行，`-`=删除行，纯数字=替换行。`0` = 最后一行。\n\n**标准 I/O（特殊文件名）：**\n| 文件名 | 含义 |\n|--------|------|\n| `-` | stdin（READ）/ stdout（WRIT）|\n| `--` | stderr |\n| `CONOUT$` | 调试终端 |\n\n```\nREAD -,10,&line,&var     // 从 stdin 读取一行\nWRIT -,$+0,Hello         // 写入 stdout\nWRIT --,$+0,Error        // 写入 stderr\nWRIT C:\\BOOT.INI,+0,text              // 追加新行\nWRIT path,$0,a=%var%                  // 替换最后一行，展开变量\nWRIT -,$+0,result                     // 写入 stdout\nWRIT path,$-3,                        // 删除第 3 行\n```\n\n### GETF — 二进制文件读取\n```\nGETF# path,offset#size,&var       // 从偏移读取原始字节，共 size 字节\nGETF# path,0#*,&var               // 读取整个文件\nGETF -bin &src,offset#size,&hexOut // 读取为十六进制字符串输出\n```\n\n### PUTF — 二进制文件写入\n```\nPUTF -dd -len=0 path,0,zero       // 创建/截断\nPUTF path,offset,#&data            // 在偏移处写入\nPUTF -dd -bs=1M src,0,dst,0,-len=size  // 磁盘到磁盘复制\n```\n\n### FILE — 文件/目录操作\n```\nFILE src -> dst               // 复制\nFILE -force src -> dst        // 强制覆盖\nFILE src                      // 删除\nFILE -r dir                   // 递归删除\nFILE -md dir                  // 创建目录\nFILE -simpleprogress src -> dst  // 带进度条\n```\n\n### DIR — 列出目录\n```\nDIR &var /s /b path            // 获取目录列表到变量\n```\n\n### FDIR / FEXT / FNAM / NAME — 路径各部分\n```\nFDIR &var=fullPath              // 目录部分\nFEXT &var=fullPath              // 扩展名（如 \"EXE\"）\nFNAM &var=fullPath              // 带扩展名的文件名\nNAME &var=fullPath              // 不带扩展名的文件名\n```\n\n### SIZE — 文件大小\n```\nSIZE &var=filePath\n```\n\n### HASH — 计算哈希\n```\nHASH filePath,&var,MD5|SHA1|SHA256|CRC32\nHASH $string,&var,SHA1          // 对字符串内容计算哈希\nHASH *PEvarName,&var,SHA256     // 对 PE 变量内容直接计算哈希（`*` 可省略如果变量有 `&` 前缀）\n```\n默认算法：MD5。不指定变量时，在消息框中显示结果并复制到剪贴板。\n\n### MDIR — 创建目录\n```\nMDIR dirPath\n```\n\n### FLNK — 符号链接/硬链接\n```\nFLNK targetPath,sourcePath             // 硬链接（默认，类型=0）\nFLNK targetPath,sourcePath,1           // 符号链接（类型=1）\nFLNK -j targetPath,sourcePath          // 目录联接\nFLNK targetPath,                       // 删除链接（源为空）\n```\n\n---\n\n## 磁盘与分区\n\n### PART — 分区管理（全面）\n```\n// 列出/信息操作\nPART list disk,&var                         // 列出所有磁盘号\nPART list disk N,&var                       // 磁盘信息（大小、柱面、磁头、介质类型、签名、总线、类型、可移动）\nPART list part N,&var                       // 列出磁盘 N 上的分区号\nPART -hextp list part N#M,&var              // 分区信息（十六进制类型 0xNN）\nPART -hextp -phy list part N#M,&var         // 分区信息，含物理编号（1-4 主分区，5-N 逻辑分区）\nPART -hextp -phy# list part N#M,&var        // 分区信息 + 追加物理#字段\nPART -fill list part N#M,&var               // 空盘符用 * 占位\nPART -devid list disk N,&var                // 设备路径/ID（如 \\\\.\\PHYSICALDRIVE0）\nPART -devidx list disk N,&var               // 型号 + 序列号\nPART -devidn list disk N,&var               // 仅名称\nPART -devida list disk N,&var               // 完整：产品号 + 序列号 + 版本 + 设备类型 + 可移动介质 + 命令队列 + 供应商ID + 产品修订版\nPART -iv=N list disk N,&var                 // 查询磁盘信息的第 N 个子字段\nPART -raw list disk N,&var                  // 原始磁盘信息（设备路径、介质 GUID、卷名）\nPART list drv D:,&var                       // 盘符 → 磁盘号 分区号 类型 总线 驱动器 介质\nPART -raw list drv D:,&var                  // 原始盘符信息：设备号 分区号 盘符类型 总线 盘符 媒体类型\nPART list volume volumeName,&var            // 卷信息\nPART -drv list volume N,&var                // 按驱动器号列出卷\nPART -phy list volume N,&var                // 卷信息（含物理设备号/分区号）\nPART -report[:retvar][diskNum]              // 显示/列出报告（忽略其他参数）\nPART -floppy list disk N,&var               // 列出软盘设备\nPART [-cdrom|-floppy] list parent <devOrDrv>,&var  // 列出父设备\nPART [-cdrom] list dep <devOrDrv>,&var      // 列出依赖/源文件名\nPART [-devid[x|n|a]] list cdrom [N],&var    // 列出 CDROM 设备\n\n// 修改操作\nPART -super -up -xup N#M type [attr]        // 设置分区类型+属性（-super 和 -up 均需指定）\nPART -super -up -axup N#M type [attr]       // 可移动磁盘的增强 xupdate\nPART -super -up -swap:M N#P                 // 交换物理分区号\nPART -super -up N#M a|A|-a|-A type start len// 创建（a=活动，A=扩展，-a=非活动）\nPART -super -up del N#M                     // 删除分区\nPART -super -up N#M a|A|-a|-A               // 切换现有分区的活动标志\nPART -super -up -fs0 N#M init               // 初始化为原始状态（无文件系统）\nPART -super -up -force N#M ...              // 强制执行危险操作\nPART update N                               // 从系统刷新磁盘信息\nPART hupdate[f] N                           // 硬盘刷新（f=强制重新编号）\nPART -ahup -up N#M ...                      // 可移动磁盘重新编号的额外硬更新\n\n// MBR/PBR 操作\nPART /mbr[=nt6|=win|=nt5|=dos|=file] N      // 重写磁盘 N 上的 MBR\nPART /pbr[=nt6|=win|=nt5|=dos|=file] N#M    // 重写分区上的 PBR\nPART -img=[*offs*len*]file|disk[/mbr|/pbr]  // 对镜像文件而非物理磁盘操作\n\n// GPT 操作\nPART -gpt init N                            // 初始化为 GPT\nPART -super -up -gpt N#M a type start len guid attr name  // 创建 GPT 分区\nPART -super -up -gpt -fs0 -mbr init N       // 初始化 GPT+MBR 混合，原始文件系统\nPART -gpt -cmp N                            // 压缩 GPT 表（从1开始编号，连续排列）\nPART fix N                                  // 修复 GPT：纠正校验和、标志、分区计数\n\nGPT 属性：\n| 值 | 含义 |\n|---|---|\n| `0x1000000000000000` | 只读 |\n| `0x2000000000000000` | 影子 |\n| `0x4000000000000000` | 隐藏 |\n| `0x8000000000000000` | 无盘符 |\n| `0x0000000000000001` | 计算机必须的分区 |\n\n// 智能盘符控制\nPART -lock[:\\\\\\\\.\\D:] N                     // 锁定盘符（阻止自动分配）\nPART -locku[:\\\\\\\\.\\D:] N                    // 解锁\nPART -lock *                                // 锁定所有卷\nPART -dvol N#M,&volGUID                     // 动态校正的 VolumeGUID\nPART -mount-                                // 不显示未分配分区的标签\nPART -fill                                  // 填充空盘符槽位\n\n// 实用工具\nPART -gui                                   // 启动 GUI 分区管理器\nPART -usb                                   // 仅 USB 模式\nPART -admin                                 // 高级模式（危险）\nPART -align[=size]                          // 对齐（默认或指定值）\nPART -CHS=C:H:S                             // 覆盖柱面/磁头/扇区几何参数\nPART -clear                                 // 强制清除分区内有效信息（不可恢复）\n```\n\nPART MBR 输出字段：`分区号 类型(hex) 激活 起始(字节) 长度(字节) 隐藏扇区 结束(字节) 物理# 盘符`\nPART GPT 输出字段：`分区号 GUID 属性 起始(字节) 长度(字节) 结束(字节) 物理# 盘符`\n\n### MOUN — WIM/VHD/UDM 挂载\n```\n// WIM 挂载\nMOUN [-svr] WimPath,MountDir,[ImageID],[TempDir]  // 只读挂载 WIM（ID=1 可省略）\nMOUN -u MountDir                                   // 卸载 WIM\nMOUN -query VarName[=rw],MountDir,WimPath          // 查询挂载状态（=rw 仅返回 RW 标志）\n\n// VHD 挂载\nMOUN-vhd [-c[x]|-d|-u|-r|-s:sectsz] VHDPath,MountDir|Size|ParentVHD,[ID],[RetVar][,PEVar]\n// -c 创建 VHD（-cx 创建 VHDX），-r 只读，-d 动态，-iso:ISO 模式\nMOUN-vhd -query [-r] VHDPath,BufPEVar[,SizeVar][,cmd]  // GET_VIRTUAL_DISK_INFO 查询\n\n// UDM 挂载子命令\nMOUN-udm [-ud|-uh|-muh[g]] [-u+] [-udfs] [-udm-] [-w] [-m] [-mall] [-mhide[1]]\n    [-findboot[Only]] [-CurDrv[R][+]] [-udmid:pt#] [-udmask:掩码]\n    [-udimg:文件] [-check[-]] [-ret:返名] 设备名 [盘符表]   // 主挂载命令\nMOUN-udm listudm -ret:返名 设备名 [UD通配符]         // 列出 UDM 分区\nMOUN-udm listud -ret:返名 [-udmask:掩码] 设备名 [通配符]  // 详细 UD 文件列表\nMOUN-udm findboot -ret:返名                           // 查找启动设备\nMOUN-udm findudm [-img] [-norm] -ret:返名 盘符        // 查找对应 UDM\nMOUN-udm setboot -ret:返名 启动菜单 [UDM盘符|#udm号] [类型] [自动加载盘符]\nMOUN-udm sync \"盘符列表\"                               // 刷新数据到存储体\nMOUN-udm mapsub [-check] [-r] 文件名 盘符             // 只读 UDm 盘的可写加载\nMOUN-udm ud2fs [-efi] 设备名 [bClr=1] [bMkNew=1] [FS=FAT]  // UD 扩展区转文件系统\nMOUN-udm OnlyApp [-noauto]                             // 检测并执行一键恢复\nMOUN-udm Server [-FreshDriver] [-quit] [-safe]         // UDM 自动挂载服务\nMOUN-udm setbootcfg 启动菜单 \"值\" [\"标签头\"]           // 设置启动配置\nMOUN-udm getbootcfg [-x[+|a]] 返回名 标签头           // 获取启动配置\n```\n\nUDM 掩码（`-udmask`）：`0x20000`=UD 扩展区，`0x40000`=仅 UD 扩展区，`0x80000`=检查 UD 扩展区，`0xA0001`=组合。\n\n### SHOW — 显示/隐藏分区\n```\nSHOW -1:-1                                // 显示所有分区\nSHOW * hd:part,driveLetter                 // 分配盘符（hd=磁盘，part=分区）\nSHOW *- hd:part,                           // 移除盘符\nSHOW & hd:part,driveLetter                 // 本地模式分配\nSHOW =1 * hd:part,driveLetter              // 已加载则跳过\nSHOW -check * hd:part,driveLetter          // 无有效文件系统则跳过\nSHOW * F:,driveLetter                      // 固定磁盘\nSHOW * U:,driveLetter                      // USB 磁盘\nSHOW * #physicalPart,driveLetter            // 物理分区号\nSHOW * -1,driveLetter                       // 所有未分配盘符的分区\nSHOW * hd:part,ChineseChar                  // 分配中文字符盘符\nSHOW * hd:part,letter,WaitMs               // 分配并等待设备就绪（等待毫秒数）\n```\n\n> **help.txt 标准语法**: `SHOW [=1] [-SKIP=类型] [-check] [-skiptp:tp1;tp2] [-skippt:hd1:lpt1;hd1:lpt2] [-from:盘符[表]] [*&-] [磁盘分区],[盘符[表]],[等待时间],[起始盘符[表]]`\n\n### SUBJ — 挂载/卸载\n```\nSUBJ D:,\\Device\\Harddisk0\\Partition1       // 挂载\nSUBJ -D:                                   // 卸载\n```\n\n### FDRV — 驱动器枚举\n```\nFDRV &var=*:                               // 所有有卷的盘符\nFDRV *idle &var=*:                         // 空闲（未分配）盘符\nFDRV *vol &label,&fs=D:                   // 获取卷标和文件系统\nFDRV *rsort &var=*:                        // 反向排序\n\n// 返回格式变体\nFDRV &var=                                 // 返回 C:|D:|E:|F:...（管道分隔）\nFDRV &var=*                                // 返回 C D E F...（空格分隔，无冒号）\nFDRV &var=*:                               // 返回 C: D: E: F:...（空格分隔，带冒号）\nFDRV &var=?                                // 返回所有 DOS 设备名\n\n// 卷标操作\nFDRV -vol [卷标名],[文件系统名],[序列号名],[最大文件名长度名],[标志名],[UUID名]=驱动器名\nFDRV -setvol 驱动器名=卷标                 // 设置卷标\n\n// 排序与过滤\nFDRV -ab &var=*:                           // 排除 A/B 软盘驱动器\nFDRV -idle[c][:盘符集] &var               // 空闲盘符（-idlec 排除 A/B）\nFDRV -link? 返名,所有名,终极名=符号名      // 返回链接对象\n```\n\n### FORM — 驱动器类型（全面）\n```\n// 基本文件系统查询\nFORM &var=D:                               // 文件系统类型字符串（如 \"NTFS\"、\"FAT32\"、\"CDFS\"）\nFORM -raw &var=D:                          // 驱动器类型常量（见下表）\nFORM TYPE,&var,BUS=D:                      // 总线类型字符串（如 \"USB\"、\"SATA\"、\"SCSI\"、\"NVMe\"）\nFORM -raw &type,&bus,&drvType=&dsk,<drive>  // 全面：一次调用获取所有类型信息\n\n// 驱动器类型常量（FORM -raw 返回）\n```\n| 常量 | 值 | 描述 |\n|---|---|---|\n| DRIVE_UNKNOWN | 0 | 未知驱动器类型 |\n| DRIVE_NO_ROOT_DIR | 1 | 无效/未挂载 |\n| DRIVE_REMOVABLE | 2 | 可移动介质（U盘、软盘） |\n| DRIVE_FIXED | 3 | 固定磁盘（HDD、SSD） |\n| DRIVE_REMOTE | 4 | 网络/映射驱动器 |\n| DRIVE_CDROM | 5 | 光盘（CD/DVD/BD） |\n| DRIVE_RAMDISK | 6 | RAM 磁盘 |\n| DRIVE_CDROMUSB | 7 | USB 光盘 |\n| DRIVE_USBFLASH | 8+ | USB 闪存驱动器 |\n| DRIVE_USBDISK | 9+ | USB 磁盘 |\n| FUNCTION_ERROR | -1 | API 错误 |\n\n### 总线类型常量（FORM -raw &busType,&bus,drvType=&id,D:）\n| 常量 | 值 | 描述 |\n|---|---|---|\n| BusTypeUnknown | 0x00 | 未知 |\n| BusTypeScsi | 0x01 | SCSI |\n| BusTypeAtapi | 0x02 | ATAPI |\n| BusTypeAta | 0x03 | ATA |\n| BusType1394 | 0x04 | 1394 (FireWire) |\n| BusTypeSsa | 0x05 | SSA |\n| BusTypeFibre | 0x06 | 光纤通道 |\n| BusTypeUsb | 0x07 | USB |\n| BusTypeRAID | 0x08 | RAID |\n| BusTypeiScsi | 0x09 | iSCSI |\n| BusTypeSas | 0x0A | SAS |\n| BusTypeSata | 0x0B | SATA |\n| BusTypeSd | 0x0C | SD |\n| BusTypeMmc | 0x0D | MMC |\n| BusTypeVirtual | 0x0E | 虚拟 |\n| BusTypeFileBackedVirtual | 0x0F | 文件支持虚拟 |\n| BusTypeSpaces | 0x10 | 存储空间 |\n| BusTypeNvme | 0x11 | NVMe |\n| BusTypeSCM | 0x12 | SCM |\n| BusTypeUfs | 0x13 | UFS |\n| BusTypeMax | 0x14 | |\n| BusTypeMaxReserved | 0x7F | 保留最大值 |\n\n### DFMT — 格式化\n```\nDFMT d:,NTFS,label,quick\nDFMT d:,FAT32,,quick\n```\n\n### EJEC — 弹出\n```\nEJEC D:                       // 弹出光驱 D:\nEJEC * D:                     // 弹出可移动 USB 磁盘 D:\nEJEC C-                       // 关闭所有光驱托盘\nEJEC U-                       // 弹出所有 USB 磁盘\nEJEC C- X:                    // 关闭 X: 的托盘\nEJEC U- X:                    // 弹出 USB 磁盘 X:\nEJEC C- HDD#1                 // 关闭磁盘 1 的托盘\nEJEC U- HDD#1                 // 弹出磁盘 1 上的 USB 磁盘\n```\n\n### DISK — 磁盘操作\n```\nDISK [varName],[diskNum],[partNum],function,[USBDriveLetters][,options]\n  // function 1=分配，2=释放，3=重新分配，22=第一个主分区\n  // USBDriveLetters：例如 \"UW\" 表示 USB 从 W: 开始分配（盘符表）\n```\n| 功能 | 描述 |\n|---|---|\n| 1 | 分配盘符 |\n| 2 | 释放盘符 |\n| 3 | 重新分配（重排 + 分配） |\n| 22 | 第一个主分区分配 |\n| **varName 特殊形式：** | |\n| `&drvLetter,diskNum,partNum` | 获取指定分区的盘符 |\n| `uAllPart,diskNum,partNum` | 分配 USB → 新分区盘符 |\n| `Vol:volLabel,diskNum,partNum` | 按卷标查找 |\n| `Part:partName,diskNum,partNum` | 按分区名查找 |\n| `\\Windows\\|\\WinXP\\|\\WinNT\\|` | 跨驱动器搜索系统目录 |\n| **选项（0x**）：** ||\n| 0x1 | 仅重排已有盘符的分区 |\n| 0x2 | 验证分区有效性 |\n| 0x4 | 跳过 0xEE/0xEF 分区 |\n| 0x10 | 也包含隐藏分区 |\n| 0x20 | 也包含 CDROM |\n| 0x40 | 限制盘符表 |\n| **标志：** ||\n| `-check` | 已加载则跳过 |\n| `-skiptp:tp1;tp2` | 跳过分区类型 |\n| `-skippt:hd:pt` | 跳过指定 disk:partition |\n| `-from:D:` | 从 D: 开始分配盘符 |\n| `-from:UW` | USB 盘符表 \"UW\" |\n| `-cdrom` | 包含 CDROM |\n\n---\n\n## 挂载 (WIM / VHD / UDM)\n\n### WIM 挂载\n```\nMOUN[-svr] [!] wimFile,mountDir,[imageID],[tempDir]    // 挂载（读写）\nMOUN[-svr] -w [!] wimFile,mountDir,[imageID],[tempDir]  // 挂载为可写\nMOUN[-svr] -m [!] wimFile,mountDir,[imageID],[tempDir]  // 挂载为只读（无 -w）\nMOUN -u mountDir                                         // 卸载\nMOUN -query &var                                        // 查询已挂载镜像\nMOUN[-svr] -u [!] wimFile,mountDir,[imageID],[tempDir]   // 卸载并提交\nMOUN[-svr] -rw [!] wimFile,mountDir,...                  // 挂载为读写（别名）\n```\n选项：`-dll WIMDLLpath:` 指定 wimgapi.dll 位置。\n\n### VHD/VHDX 挂载\n```\nMOUN-vhd -c[x] file.vhd,size                            // 创建（x=先扩展到指定大小）\nMOUN-vhd -c[x] -d file.vhd,size                         // 创建动态（稀疏）\nMOUN-vhd -c[x] -s:512 file.vhd,size                     // 扇区大小覆盖\nMOUN-vhd -r file.vhd,mountDir                           // 挂载为只读\nMOUN-vhd -d file.vhd,mountDir                           // 挂载动态 VHD\nMOUN-vhd -u mountDir                                    // 卸载\nMOUN-vhd -iso file.iso,mountDir                         // 挂载 ISO\nMOUN-vhd -query file.vhd,&var                          // 查询 VHD 信息\n```\nPECMD 私有 PE 变量：当变量超出作用域时自动卸载。使用 `PEvar` 作为第 3 个参数。\n\n### UDM（超深度挂载）— 隐藏分区挂载\n```\nMOUN-udm [flags] \\\\\\\\.PhysicalDriveN                     // 挂载全部或指定\nMOUN-udm -findboot -ret:&retVar                         // 查找并挂载引导设备\nMOUN-udm -u mountDir                                    // 卸载\n```\n| 标志 | 描述 |\n|---|---|\n| `-ud` | UD 分区 |\n| `-uh` | UD 高端 |\n| `-muh` | 挂载 UD 高端 |\n| `-u+` | U+ 分区 |\n| `-udfs` | UD 文件系统 |\n| `-udm-` | 禁用 UDM |\n| `-mall` | 挂载全部（不仅是隐藏的） |\n| `-mhide` | 仅挂载隐藏分区 |\n| `-mhide1` | 仅挂载隐藏分区（变体 1） |\n| `-onlys` | 仅挂载特定系统类型 |\n| `-findboot` | 自动查找引导设备 |\n| `-ret:` | 返回设备路径到变量 |\n| `-CheckFile[+]:path` | 按文件存在验证 |\n| `-CheckVol[R]` | 按卷标验证 |\n| `-CheckUuid[R]` | 按 UUID 验证 |\n| `-CheckPtType` | 按分区类型验证 |\n| `-check[-]` | 仅挂载有效文件系统分区 |\n| `-tag[+]:name` | 标签标识用于匹配 |\n| `-opts:`/`-opt:` | 挂载选项（分隔或合并） |\n| `-nbrd[-]` | 不广播盘符 |\n| `-ainf:var` | 存储分区表缓冲区到变量 |\n| `-udmid:pt#physicalNum` | 按物理分区号软挂载（默认只读） |\n| `-udmdev:device` | 指定引导设备和 UDM |\n\n---\n\n## 系统\n\n### MAIN — WinPE 入口点\n```\nMAIN path\\to\\PECMD.INI\n```\n启动桌面，挂钩 Ctrl+Alt+Del，运行配置文件，并进入消息循环。这是标准的 PE 引导入口命令。\n\n### INIT — 初始化\n```\nINIT [options],[timeout],[USB起始盘符]\n```\n选项：`C`=将光驱盘符写入环境变量，`I`=安装托盘图标菜单，`K`=立即安装低级键盘钩子，`U`=USB 移动硬盘即插即用\n常用：`INIT IU,3000`（USB 起始盘符默认为 U）\n\n### SHEL — 设置 Windows 外壳\n```\nSHEL %SystemRoot%\\explorer.exe\nSHEL PECMD.EXE LOAD MyShell.ini\n    cmd_on_shell_change\n```\n缩进的行在外壳切换时执行。\n\n### DISP — 显示设置\n```\nDISP W1024H768B32F60                             // 宽，高，色深，刷新率\nDISP                                             // 自动检测最佳模式\nDISP =N W1024H768B32F60                         // 目标显示器 N（从 0 开始）\nDISP W1024H768B32F60 T15                         // 应用并设 15 秒超时（自动恢复）\nDISP W1024H768B32F60 P                           // 设为主显示器\nDISP W1024H768B32F60 O0                          // 方向（0=默认，1=90°, 2=180°, 3=270°）\nDISP -confirm W1024H768B32F60                    // 确认提示\nDISP -nwb W1024H768B32F60                        // 不等待广播\nDISP -delay W1024H768B32F60                      // 仅写注册表（不应用），等待广播\nDISP @X0:Y0:X1:Y1:...                            // 多显示器位置（矩阵）\nDISP S0x84                                        // 多显示器模式：0x81=单屏，0x82=克隆，0x84=扩展，0x88=双屏\nDISP ?[?*] [=N] &var                             // 查询当前（*=所有可能）模式\nDISP -reset                                       // 重置为默认值\nDISP -bright[?]:value/&var                        // 亮度控制\nDISP -ori [?] &var                                // 查询方向\nDISP -guis                                        // 图形界面\nDISP -sort[-r|-n]                                 // 排序模式（r=反向，n=按名称）\n```\n\n### PAGE — 虚拟内存\n```\nPAGE [*force] C:\\pagefile.sys 256 512   // 最小 256MB，最大 512MB（*force 强制创建）\n```\n\n### RAMD — RAM 磁盘（ImDisk）\n```\nRAMD ImDisk,L100,FAT32,C:,MyRam      // 创建\nRAMD ImDisk* -D -m G:                 // 移除\n```\n\n### SERV — 服务管理\n```\nSERV [-wait] servicename                     // 启动（-wait=等待完成）\nSERV [-wait] !servicename                    // 停止（! 前缀，-wait=等待完成）\nSERV [?返回名] servicename                   // 查询状态\nSERV -create [?返回名] name,path,type,start[,error,dep,user,pass,display,group,tag]\nSERV -delete [-stop-] [?返回名] name         // 删除（-stop-=删除前自动停止）\n```\n启动类型：`-boot`，`-system`，`-auto`，`-demand`，`-disabled`，`-delayed-auto`\n\n### HOTK — 系统级热键\n```\nHOTK [--delall] [?[.]返回名] Ctrl+Alt+#0x41,command  // 注册（全局，系统级）\nHOTK Ctrl+Shift+Alt+Win+#0x42,command       // 多修饰键\nHOTK #0x0D,--del                            // 按键码取消注册\nHOTK --del:keyname                          // 按名称取消注册\nHOTK --delall                               // 取消所有已注册热键\nHOTK ?返回名 #0x41                          // 查询指定键的热键名\n```\n修饰键：`Ctrl`，`Alt`，`Shift`，`Win`。用 `+` 组合。\n虚拟键码使用 `#` 前缀（十进制或十六进制：`#0x41`）。\n\n### HKEY — 窗口/程序级热键\n```\nHKEY #0x41,command                          // 默认 = 窗口级（此窗口有焦点时响应）\nHKEY *#0x41,command                         // * = 窗口激活时响应（不同窗口可重用，个数不限）\nHKEY $#0x41,command                         // $ = 程序级全局（此 PECMD 实例的任何窗口）\nHKEY Ctrl+Shift+#0x42,command               // 多修饰键\nHKEY #0x0D,--del                            // 按键码取消注册\nHKEY --del:keyname                          // 按名称取消注册\n```\n\n### DATE — 日期/时间变量和子变量\n```\nDATE &var                                  // 获取当前日期（yyyy mm dd HH MM SS ms weekday 格式）\nDATE &var yyyy-mm-dd-HH-MM-SS-ms-wd        // 设置系统日期/时间（可部分设置）\nDATE -h &var                               // 高精度计时器（微秒）\nDATE -r &var                               // 同步 + 读取高精度计时器\nDATE -space0 &var                          // 空格分隔，0 填充\nDATE -space &var                           // 空格分隔（默认紧凑）\nDATE -bsys &var                            // 输出系统时间\nDATE -utc:UTCtime &var                     // 从 UTC 时间转换\nDATE -gmt:GMTtime &var                     // 从 GMT 时间转换\nDATE -local:LOCALtime &var                 // 从本地时间转换\nDATE -sys:internTime &var                  // 国际/UTC 时间\nDATE -us &var                              // 微秒（4 位小数）\n```\n子项（使用 `MSTR` 或直接 `%&var:item%` 语法）：\n| 子项 | 含义 |\n|---|---|\n| `y` / `year` | 年（4位） |\n| `mon` / `month` | 月（2位） |\n| `d` / `day` | 日（2位） |\n| `w` / `weekday` | 星期几（1=周一..7=周日） |\n| `h` / `hour` | 小时（24小时制，2位） |\n| `min` / `minute` | 分钟（2位） |\n| `s` / `second` | 秒（2位） |\n| `ms` / `msec` | 毫秒（3位） |\n| `ws[1]` | 年内第几周（[1]=周日为周末边界） |\n| `ds` / `daysofyear` | 年内第几天（1-366） |\n| `Freq` / `frequency` | 计数器频率 |\n| `Counter` / `counter` | 硬件计时器计数器值 |\n| `gmt` | GMT 秒数（自 1970-01-01 起） |\n| `uptime` / `uptime_ms` | 自开机以来的毫秒数 |\n| `utc` | 自 1601-01-01 至今的 100ns 单位数 |\n| `uptimens` | 自开机以来的纳秒数 |\n\n### TEMP — 临时文件/目录管理\n```\nTEMP [[@]Delete|[$]Setting] [初始目录][,变量名]           // 查询/设置临时目录\nTEMP @[$]Setting 新临时目录,[变量名]                       // 静默设置\nTEMP [*del] [*tmpl:[前部]*[尾部]] *tmpdir [,]变量名        // 生成唯一临时目录\nTEMP [*del] [*tmpl:...]*tmpfile [,]变量名[,目录变量名]      // 生成唯一临时文件\n```\n`@` = 静默模式。`*del` = 退出时自动删除。`*tmpl:` = 自定义名称模板（`*` = 随机部分）。\n\n### RUNS — 运行注册表项\n```\nRUNS prog,Name                       // 添加到 HKLM\\...\\Run\nRUNS -d Name                         // 删除条目\n```\n\n### PATH — 设置搜索路径\n```\nPATH C:\\Tools;%PATH%                 // 设置 PATH 环境变量\nPATH %CurDir%\\Tools                  // 追加到现有值\n```\n\n### RECY — 设置回收站容量\n```\nRECY D:,10                           // NT5.x: D: 盘回收站最大 10%\nRECY C:,2048                         // NT6.x: C: 盘回收站最大 2048MB\nRECY D:,0                            // 禁用 D: 盘回收站\nRECY *:,0                            // 禁用所有分区回收站\n```\n\n### USER — 设置所有者信息\n```\nUSER 用户名,公司名                    // 设置\"我的电脑\"属性值\n```\n\n### HOME — 设置 IE 主页 / 锁定主页 / 禁用注册表编辑器\n```\nHOME http://example.com              // 设置 IE 主页\nHOME http://example.com,1            // 锁定主页（禁止修改）\nHOME http://example.com,1,1          // 锁定主页 + 禁用注册表编辑器\n```\n\n---\n\n## 音频与显示\n\n### SCRN — 截图 / 捕获屏幕\n```\nSCRN &w,&h                             // 获取屏幕宽度和高度\nSCRN -win &w,&h                        // 最大化窗口尺寸\nSCRN -desk &w,&h                       // 桌面分辨率（不考虑 DPI 缩放）\nSCRN -cur &x,&y                        // 获取光标位置\nSCRN -cap scrn.bmp,&wid                // 捕获全屏为 BMP，返回窗口 ID\nSCRN -cap scrn.bmp,&wid,WxH            // 按指定分辨率捕获\nSCRN -cap scrn.bmp,&wid,WxH,x,y        // 捕获 (x,y) 处大小为 WxH 的区域\nSCRN -cap -capwid:WID scrn.bmp,&wid    // 捕获指定窗口\nSCRN -cap -cur scrn.bmp,&wid           // 捕获时包含光标\nSCRN -cap scrn.jpg,&wid,0,0,0,80       // 捕获为 JPG（质量 80）\nSCRN -cap :image/png:screenshot.png,0  // 捕获为 PNG（格式前缀）\nSCRN -cap :image/bmp:file.bmp,0        // 捕获为 BMP（格式前缀）\nSCRN -cap file.bmp,#WindowID           // 按句柄捕获指定窗口\nSCRN -cap file.bmp,<x:y:R:B>           // 捕获矩形区域\n```\n捕获格式：`.bmp`，`.jpg`，`.png`（按扩展名或 `:image/format:` 前缀）。\n捕获目标：`0`=全屏，`#WindowID`=指定窗口，`<x:y:R:B>`=矩形区域。\n扩展尺寸参数：`SCRN -taskbar W,H,X,Y,TaskBarPos,DpiX,DpiY,ScaleX,ScaleY` 用于 DPI 感知信息。\n\n### FONT — 注册/注销字体\n```\nFONT fontPath                           // 注册字体文件\nFONT \\Windows                           // 从所有分区的 Windows\\Fonts 注册字体\nFONT - fontPath                         // 注销字体（- 前缀）\nFONT -p:retName:fontName:lang fontRes   // 私有字体（不注册系统）\n```\n\n### WALL — 设置桌面壁纸\n```\nWALL imagePath                           // 设置壁纸（BMP、JPG、PNG、GIF）\nWALL %SystemRoot%\\Web\\Wallpaper\\img.jpg  // 绝对路径\nWALL \"\"                                  // 清除壁纸（纯色）\n```\n\n### SITE — 文件属性查询/设置\n```\n// 查询\nSITE ?filePath                           // 在消息框中显示属性\nSITE &var,filePath                       // 获取属性到变量（如 \"A--RHS-\"）\nSITE ?-attr,&var=&attr                   // 查询原始属性标志\n\n// 设置\nSITE +R,filePath                         // 设置只读\nSITE +H,filePath                         // 设置隐藏\nSITE +S,filePath                         // 设置系统\nSITE +A,filePath                         // 设置存档\nSITE -R,filePath                         // 移除只读\nSITE +R+H+S+A,filePath                   // 组合多个\nSITE +R-H,filePath                       // 设置只读并移除隐藏\nSITE -R-H-S-A,filePath                   // 清除所有属性\nSITE +R+H,dirPath\\*                      // 应用于目录中所有文件（路径末尾加反斜杠）\n\n// 编码变量（安全）\nSITE ?-all,VAR=variable                  // 编码变量（PECMD 风格）\nSITE ?-sys,VAR=variable                  // 以系统标志编码\nSITE ?H:hWnd,variable1[,variable2]       // 复制到剪贴板\n\n// 文件版本查询\nSITE ?fileVerVar[,prodVerVar]=FVER,filePath  // 查询文件版本（如 \"1.2.3.4\"）\n\n// 文件时间查询\nSITE ?[-local -ws -link] [[*]creationVar,[*]writeVar,[*]accessVar]=FTIME,filePath\n  // * 前缀 → 返回 UTC 时间整数（可直接比较）\n  // 无 * → 返回 \"yyyy mm dd HH MM SS us weekday\"（固定宽度字段）\n  // -local → 本地时间（默认：UTC）\n  // -ws → 追加年内周数；-ws1 → 周日为周末边界\n  // -link → 跟随符号链接\n\n// 文件属性查询\nSITE ?[attrVar][,hidVar][,roVar][,sysVar][,fullVar]=FATTR,filePath\n\n// 更新文件时间戳\nSITE *touch[:[cr][*local:|*local0:|*sys:|*sys0:|*utc:]time],<file>[,retVar]\n```\n查询结果中的属性标志：`R`=只读，`H`=隐藏，`S`=系统，`A`=存档，\n`N`=普通，`D`=目录，`C`=压缩，`E`=加密，`T`=临时，`O`=脱机。\n\n---\n\n## 驱动与设备\n\n### DEVI — 设备驱动安装\n```\n// 从 CAB/INF/文件夹安装\nDEVI [$]<CAB文件>[,匹配级别[,解压目录]]         // 从 CAB 安装\nDEVI [*nocheck] <INF文件>[,DevClass]           // 从 INF 安装\nDEVI [*rescan] <含有INF的目录>[,DevClass]       // 从目录安装\nDEVI $<INF文件>,[安装节],[操作码]               // 高级安装\nDEVI *extract <CAB>[,匹配级别],解压目录          // 仅解压\n\n// 列出设备\nDEVI listdev:var [*devclass:Class] [*ALL] [*listdev=i|c|+]\nDEVI listdev:var *many *devid:PCI\\VEN_14E4*     // 按筛选条件列出\n\n// 控制设备\nDEVI *enable:[h|c|+:]devID                      // 启用设备\nDEVI *disable:[h|c|+:]devID                     // 禁用设备\nDEVI *remove:[h|c|+:]devID                      // 移除设备\nDEVI *restart:[h|c|+:]devID                     // 重启设备\nDEVI *status:retVar:[h|c|+:]devID               // 查询状态\nDEVI *update:hardwareID:INF                      // 更新驱动\nDEVI *install:hardwareID:INF                     // 安装驱动\n\n// 其他\nDEVI *rescan[:Fun]                               // 重新扫描设备\nDEVI buildcache:[-a:arch] dir                    // 构建驱动缓存\n```\n高级标志：`*dummy`=测试模式，`*7pe[-]`=强制 DrvLoad，`*inner`=强制不使用 DrvLoad，`*drvload/*devcon`=优先级选择，`*retid:var`=返回安装的设备 ID，`*auto`=自动转换 INF，`*sys:`=复制到系统目录，`*cab`=强制 CAB 类型，`*comp+`=匹配兼容 ID，`*ret:retVar`=返回报告，`*IdCah:PeVar`=重用 ID 缓冲区，`*infcache:`=加速缓存，`*optsys[:val]`=系统工具优先级，`*num:count`=计数限制，`*disverify/*autodisverify`=签名检查控制，`*sub/*self`=搜索模式，`*showdev:`=显示设备信息，`*norescan`=跳过重新扫描。\nListdev 选项：`*comp[+]`=兼容 ID，`*hwid`=硬件 ID，`*inst`=实例 ID，`*many`=多行，`*rescan`=先重新扫描。\n\n### FBWF — FBWF 缓存控制\n```\nFBWF [Ppercent] [Lmin] [Hmax] [Fremain]\n```\n所有值单位为 MB。示例：`FBWF P50 L200 H300` — 内存的 50%，最小 200MB，最大 300MB。\n\n---\n\n## 注册表\n\n### REGI — 读写注册表\n```\n// 读取（所有类型前缀）\nREGI $HKLM\\SOFTWARE\\Key\\Val,&var          // REG_SZ\nREGI #HKLM\\SOFTWARE\\Key\\Val,&var          // REG_DWORD\nREGI @HKLM\\SOFTWARE\\Key\\Val,&var          // REG_BINARY\nREGI *HKLM\\SOFTWARE\\Key\\Val,&var          // REG_MULTI_SZ\nREGI **HKLM\\SOFTWARE\\Key\\Val,&var         // REG_MULTI_SZ（特殊）\nREGI *$HKLM\\SOFTWARE\\Key\\Val,&var         // 多行 REG_MULTI_SZ\nREGI ~HKLM\\SOFTWARE\\Key\\Val,&var          // REG_EXPAND_SZ\nREGI ~~HKLM\\SOFTWARE\\Key\\Val,&var         // REG_EXPAND_SZ（~~ 读取并重新解释注册表数据中的环境变量）\nREGI +HKLM\\SOFTWARE\\Key\\Val,&var          // REG_QWORD\nREGI ^HKLM\\SOFTWARE\\Key\\Val,&var          // REG_LINK\nREGI bHKLM\\SOFTWARE\\Key\\Val,&var          // REG_QWORD_BIG_ENDIAN\nREGI uHKLM\\SOFTWARE\\Key\\Val,&var          // REG_MUI_SZ\nREGI nHKLM\\SOFTWARE\\Key\\Val,&var          // REG_NONE\nREGI .HKLM\\SOFTWARE\\Key\\Val,&var          // 离线注册表（离线 Windows/system）\nREGI HKCU\\Software\\Key\\,&&keys            // 枚举子键（换行分隔）\n\n// 写入\nREGI $HKLM\\SOFTWARE\\Key\\Val=string         // 写入 REG_SZ\nREGI #HKLM\\SOFTWARE\\Key\\Val=#0x100        // 写入 REG_DWORD（十六进制）\nREGI $HKLM\\SOFTWARE\\Key\\Val=               // 删除值\nREGI HKCU\\abc=\"\"                           // 写入空字符串（\"\" 表示空值写入）\n\n// 高级操作\nREGI --ak HKCU\\Software\\Key\\,&all             // 枚举所有子键 (k=keys)\nREGI --av HKCU\\Software\\Key\\,&all             // 枚举所有值 (v=values)\nREGI .?\\HKLM\\SOFTWARE\\Key\\Val,&type           // 查询值类型（点+问号）\nREGI --16 ...                                 // 十六进制数据输入\nREGI --su path\\val=value                      // 以 SYSTEM 身份运行（提升权限）— 用于 32 位在 64 位系统上\nREGI --init path\\val,&var                     // 读取失败时返回空字符串\nREGI --name path\\val,&var                     // 数据变量名模式\nREGI --k path\\key\\                            // 仅创建键（不设置值）\nREGI --byte path\\val,&var                     // 字节流模式\nREGI --v[-] path\\val,&var                     // 不保存更改（读取快照）\nREGI --qk path\\val,&var                       // 快速模式\nREGI --r10 path\\val,&var                      // 输出十进制（用于 DWORD）\nREGI --t:NUM path\\val,&var                    // 按数字指定任意注册表类型\nREGI --0[:N] path\\key\\                        // 清除键：1=清除默认值，2=删除子键，4=删除值（组合：5=1+4）\n\n// 查询存在性（找不到返回 ERROR）\nREGI ?HKLM\\SOFTWARE\\Key\\,&&VT\nFIND $%&VT%=ERROR, MESS Key not found! MESS Key exists\nREGI ?HKLM\\SOFTWARE\\Key\\Val,&&VT           // 检查值是否存在\nREGI ?HKLM\\SOFTWARE\\Key\\,&&VT               // 检查键是否存在\nFIND $%&VT%=NI, MESS Data not set!          // NI = 键存在但无数据\n```\n\n### HIVE — 加载/卸载离线注册表配置单元（全面）\n> help.txt 文档化标志：`-u`（加载到 HKU）、`-super`/`-super_r`（强制权限）、`-quick`（不添加权限）、`*`（导出到文件）。\n> 以下 `-tmp`、`-restore`、`ACL` 为未文档化扩展，实测可用但可能因版本而异。\n```\n// 将离线配置单元挂载到 HKLM（或 HKU）下的挂载点\nHIVE E:\\Windows\\System32\\config\\SOFTWARE,HKLM\\PE-SYS     // 加载离线 SOFTWARE 配置单元\nHIVE E:\\Windows\\System32\\config\\SYSTEM,HKLM\\PE-SYS       // 加载离线 SYSTEM 配置单元\nHIVE E:\\Users\\Default\\NTUSER.DAT,HKU\\PE-DEF             // 加载离线用户配置单元\nHIVE HKLM\\PE-SYS,                                        // 卸载（路径为空，相同挂载点）\n\n// [未文档化] 加载时保留安全描述符（保留 ACL）\nHIVE E:\\...\\SOFTWARE,HKLM\\PE-SYS,ACL                    // 带安全/ACL 加载\n\n// [未文档化] 作为临时配置单元加载（卸载时丢弃更改）\nHIVE -tmp E:\\...\\SOFTWARE,HKLM\\PE-TMP                   // 使用临时配置单元（只读意图）\n\n// [未文档化] 加载并在卸载时还原（将更改保存回配置单元文件）\nHIVE -restore E:\\...\\SOFTWARE,HKLM\\PE-SYS               // 卸载时还原（写回）\nHIVE -restore HKLM\\PE-SYS,                               // 卸载并还原（保存更改）\n```\n挂载点语法：`HKLM\\PE-SYS` = 将配置单元挂载到 `HKEY_LOCAL_MACHINE\\PE-SYS`。\n挂载后，使用 `REGI .HKLM\\PE-SYS\\...` 访问（点前缀表示离线注册表）。\n要卸载，提供相同的挂载点并留空路径（或使用 `-restore` 前缀来保存更改）。\n\n---\n\n## GUI 控件\n\n所有 GUI 控件文档参见 [pecmd-gui.md](pecmd-gui.md)。\n\n---\n\n## 网络\n\n### ADSL — 宽带/WiFi\n```\n// 拨号（PPPoE）\nADSL userEncoded,passEncoded,[retries],[name|*|retVar]     // 拨号\nADSL start[+] userEncoded,passEncoded,[retries],[retVar]    // 开始（连接）\nADSL stop,connectionName                                    // 挂断\nADSL list[on],connectionName                                // 列出连接\n\n// WiFi (ADSL-wlan)\nADSL-wlan SSID|&profileVar,password,encType,[index]        // 连接（加密默认=WPA2PSK AES）\nADSL-wlan -start SSID|&profileVar,password,encType,[index]  // 显式开始\nADSL-wlan index,,list,&&result                              // 列出 WiFi 配置文件\nADSL-wlan index,,query[all],&&result                        // 查询详情（序号 guid State Desc）\nADSL-wlan index,,scan,&&result                              // 扫描网络\nADSL-wlan index,,-list,&&result                             // 网络广播扫描\n// 结果格式（list）：SSID SignalQuality Flags BssType NumBssid bConnectable ...\n// 结果格式（query[all]）：index guid State Description\n// Flags & 1 = 当前已连接\n```\n\n### PCIP — IP 配置\n```\nPCIP 192.168.1.100,255.255.255.0,192.168.1.1,[DNS1],[DNS2]  // 固定IP\nPCIP -,-,-,-,,                                                // DHCP（动态IP）\n```\n\n### 其他网络\n```\nNTPC time.server.com                                // 时间同步（默认仅同步）\nNTPC -q ,现在时间                                     // 同步并查询（-qo 仅查询）\nSITE ftp://user:pass@server/path,local,get|put        // FTP（下载/上传）\nUPNP add|del TCP|UDP,port,internalIP                  // 端口转发\n```\n\n---\n\n## 外部执行\n\n### EXEC — 执行程序（全面）\n```\nEXEC [=][!][@][^][&][*] [flags] program [args]\n```\n基本：`=`=等待完成，`!`=隐藏运行，`@`=不等待+隐藏，`^`=不等待，`*`=不等待\n\n附加标志（最常用）：\n```\n-err+                  // 捕获 stderr 到同一输出\n-err                   // 单独捕获 stderr\n-cmd:::Callback        // 实时输出行回调\n-wd:path               // 设置工作目录\n-pid:var               // 获取进程 PID\n-su[acde]              // 以 SYSTEM 身份运行\n-doc:mode              // 打开/编辑/打印/属性 文档\n-min|-max|-show|-hide  // 窗口状态\n-user:name -passwd:pwd // 以指定用户身份运行\n-timeout:ms[:code]     // 超时\n-waiti                 // 等待 UI 初始化\n-raw                   // 捕获原始数据（不重新编码）\n-nowin                 // CREATE_NO_WINDOW\n-incmd                  // 在新的 PECMD 实例中运行命令（无消息循环）\n-hook                   // 修改进程关机代码\n-no64                   // PECMD32：不释放 X64 文件系统限制\n-ex1                    // 继承父进程 PE 变量为环境变量\n-nfb                    // 禁用等待光标\n-hpid:var               // 获取进程句柄（非 PID）\n-exe:filename           // 执行指定文件名（可执行非标准后缀文件如 .tmp）\n--exe:#resID            // 执行内嵌资源程序（#=资源 ID，无*=内存执行，有*=临时文件执行）\n--exe:[*[*]][?.ext:][cab:]传递  // 内嵌程序高级语法\n\n// 附加 EXEC 标志：\n-clone:var            // 克隆 PECMD 运行脚本变量\n-mem                  // 幽灵进程（内存中执行）\n-io                   // 接管子进程 I/O\n-code:<enc>           // 指定源编码\n-REALTIME|-HIGH|-ABOVENORMAL|-NORMAL|-BELOWNORMAL|-LOW|-IDLE  // 进程优先级\n-shel:\"auto_cmd\"      // 在 SHEL 模式下执行\n-svrsys|-svrusr|-svr- // 服务到桌面执行\n/InstallService /name // 安装为 Windows 服务\n/RemoveService name   // 卸载服务\n-poprmenu|-runrmenu   // 弹出/执行文件右键菜单\n-runs                 // 写入注册表自动运行（= 前导: HKLM\\...\\Run, 否则 HKCR\\...\\Run）\n// 服务模式附加标志（配合 /InstallService）：\n--wait|--nowait       // 等待/不等待进程结束（默认等待）\n--idle ms             // 空闲 ms 毫秒后执行命令\n--idlewait            // 有输入时不终止已运行程序\n--killwin             // 监控并关闭 MESS-svr 窗口\n--nojob               // 不杀子进程\n--gui-                // 无界面交互\n--desk[-]:[不]切换显示 // 桌面切换控制\n--delayservice ms     // 服务启动延迟毫秒数\n--hide                // 隐藏进程窗口\n```\n\n### EXEC* — 捕获输出\n```\nEXEC* [*1|*N|*-] [-catch] [-cmd:::Callback] [-err+] [&]outputVar=program [args]\n```\n`*1`=仅第一行，`*N`=合并行，`*-`=去除尾部换行，`*$`=首行+变量展开，`*^`=首行+推迟展开\n`NAME+=` — 追加模式（在 EXEC* 中，NAME+= 将输出追加到变量而非覆盖）\nEXEC| [flags] program [args]                        // 管道模式（支持 > >> < 2> >& 重定向）\n\n#\n\nFile v1.7.1:references/how-tos/gui.md\n\n# GUI 控件/窗口/绘制 — 写法示例\n\n> **版本兼容性：** 部分示例使用 DLL 调用（`CALL $--qd`）。DLL 调用需要 PECMD2012 v1.88+ 完整版支持（32-bit 和 64-bit 行为一致）。\n> 如果 DLL 调用不工作，可使用 `FIND --wid*@`、`EXEC*` 等内置命令替代。\n\n## 7. GUI 模式\n\n### 完整窗口模板\n\n```wcs\n#code=65001\nENVI^ EnviMode=1\nENVI^ ForceLocal=1\nSET$ &NL=0d 0a\nSET$ &TAB=09\n\nCALL @主窗口\n\n_SUB 主窗口,W400H300,我的工具,,#1,,\n    ENVI @this.Font=12:Microsoft YaHei\n    ENVI @this.bkcolor=0xF0F0F0\n    ENVI @this.MSG=0x0010:CALL OnClose           // WM_CLOSE (window-level, no _)\n    LABE -vcenter -trans 标签1,L20T20W360H30,欢迎使用本工具,,0x000000,14\n    EDIT 编辑1,L20T60W360H120,,CALL OnEdit,,12\n    ITEM 确定,L150T200W100H35,确定,CALL OnOK\n    ITEM 取消,L260T200W100H35,取消,KILL \\\n_END\n\n_SUB OnOK\n    MESS 你点击了确定@提示#OK\n_END\n\n_SUB OnClose\n    KILL \\\n_END\n```\n\n### DPI 感知窗口与手动布局\n\n```wcs\n_SUB DPIWindow,W600H400,DPI Demo,,,,, -scalef -scale\n    TEAM SET &dpi=| REGI #HKCU\\Control Panel\\Desktop\\WindowMetrics\\AppliedDPI,&dpi|\n    FIND $%&dpi%=, SET dpi=96\n    // Check if system already auto-scaled (if actual = requested, skip manual scaling)\n    ENVI @this.POS=?::&actualW:&actualH\n    IFEX [ %&actualW%=600 & %&actualH%=400 ], SET dpi=96\n    SET &DPI=%&dpi%/96\n    // Save initial positions for resize handling\n    ENVI @this.POS=?::&InitW:&InitH\n    CALC #&x=20*%&DPI%\n    ITEM Btn,L%&x%T120W100H30,DPI Button,CALL OnClick\n    ENVI @this.MSG=0x0005::&&wp,&&lp,CALL OnResize %&wp% %&lp%\n_END\n\n_SUB OnResize\n    IFEX $%1=1, EXIT _SUB                        // SIZE_MINIMIZED, skip\n    CALC #&newW= %2 & 0xFFFF                     // LOWORD of lParam\n    CALC #&newH= %2 / 0x10000                    // HIWORD of lParam\n    IFEX [ %&newW%<600 | %&newH%<400 ],         // enforce minimum\n    {\n        ENVI @DPIWindow.POS=::%&InitW%:%&InitH%\n    }\n_END\n```\n\n### TABL 数据操作（综合）\n\n```wcs\n// Title with formatting flags\nENVI &&Title=100:名称%&TAB%=60:PID%&TAB%+80:内存%&TAB%*0:隐藏列%&TAB%*200:路径\n//   default=left, =  =right-align, +  =center, *0: =hidden column\n\nTABL Table1,L10T10W500H300,%&Title%,,0x10040\n\n// Bulk-set from variable (typical after FIND --pid*@)\nFIND --pid*@ &&processList,\nENVI @Table1.Val=1*;%&processList%\n\n// Read individual cells\nENVI @Table1.Sel=?;&sel\nENVI @Table1.Val=?%&sel%.1;&name\nENVI @Table1.Val=?%&sel%.2;&pid\n\n// Row count\nENVI @Table1.Val=?*;&count\n\n// Clear all\nENVI @Table1.Val=-*\n\n// Select/deselect\nENVI @Table1.Sel=3\nENVI @Table1.Sel=3;0\n\n// Set full row (tab-separated columns)\nENVI @Table1.Val=%&row%;%&col1%%&TAB%%&col2%%&TAB%%&col3%\n\n// Sort rows by reading and swapping values\nENVI @Table1.Val=?%&a%;&rowA\nENVI @Table1.Val=?%&b%;&rowB\nENVI @Table1.Val=%&a%;%&rowB%\nENVI @Table1.Val=%&b%;%&rowA%\n```\n\n### LIST 下拉操作\n\n```wcs\nLIST -h List1,L10T10W200H200,,CALL OnSelect,,0x100\nENVI @List1.VAL=                        // clear all\nENVI @List1.ADD=选项1                    // add item\nENVI @List1.ADD=选项2\nENVI @List1.ADDSEL=默认选项              // add and select\nENVI @List1.DEL=选项1                    // remove item\nENVI @List1.isel=2                       // select by 1-based index\nENVI @List1.QUERY=;&allItems             // get all items (NL-delimited)\n```\n\n### 右键弹出上下文菜单\n\n```wcs\nENVI @Table1.MSG=_%&::WM_RBUTTONDOWN%: CALL @--popmenu MyMenu\n\n_SUB MyMenu\n    MENU MnuOpenLoc,打开文件位置,TEAM ENVI @Table1.Sel=?&s| CALL FileDir\n    MENU -\n    MENU 复制,复制到剪贴板,CALL Clipboard\n    MENU -\n    MENU 结束进程,结束进程,CALL KillProc\n_END\n```\n\n### SWIN 子窗口（选项卡页）\n\n```wcs\nSWIN :Page1,L10T40W380H200\nSWIN :Page2,L10T40W380H200\nENVI @Page2.Visible=0                    // hidden initially\n\n_SUB Page1\n    ENVI @this.bkcolor=0xFFFFFF\n    LABE ,L10T10W200H20,This is page 1\n_END\n// Switch: ENVI @Page1.Visible=0 | ENVI @Page2.Visible=1\n```\n\n### 动态标签创建（变量中的命令）\n\n```wcs\nENVI &&cmdString=LABE -vcenter -trans Lbl%&i%,L%&x%T%&y%W%&w%H%&h%,%&text%,CALL OnClick %&i%,0x000000,14\n%&cmdString%                                      // execute the dynamically-built command\n```\n\n### 带关联控件的复选框\n\n```wcs\nCHEK Check1,L20T50W200H20,Auto refresh,CALL OnCheck,1\n\n_SUB OnCheck\n    IFEX $%Check1.Check%=1, ENVI @Timer1=1000! ENVI @Timer1=0\n_END\n```\n\n\n### 动态控件创建与删除\n\n```wcs\n// Create controls programmatically from a command string in a variable\nSET &x=100 & &y=50 & &w=200 & &h=30\nENVI &&cmd=LABE -vcenter -trans Lbl%&i%,L%x%T%y%W%w%H%h%,%&text%,,0x000000,14\n%&cmd%                                              // execute the command to create the control\n\n// Delete controls dynamically\nENVI @Lbl%A.*del=                                   // delete label A\nENVI @Edit%B.*del=                                  // delete edit field B\n// This is essential for dynamic GUIs that rebuild control sets\n```\n---\n\n## 26. 窗口样式标志与窗口隐藏\n\n```wcs\n// Common window creation flags\n_SUB MyWin,W400H300,Title,,,,, -trap -nocap -ntab -nfocus\n//   -trap: close button doesn't exit (window survives close)\n//   -nocap: no title bar (frameless window)\n//   -ntab: no Tab key navigation (no keyboard focus cycling)\n//   -nfocus: no keyboard focus on creation\n//   -nosysmenu: no system menu (no icon, no min/max/close)\n//   -top: always on top (TOPMOST)\n//   -maxb: enable maximize button\n//   -minb: enable minimize button\n\n// Cross-process window hide/show\nENVI @@Visible=%&WID%:0                           // 不可见\nENVI @@Visible=%&WID%:1                           // 可见\nENVI @@Visible=%&WID%:2                           // 正常显示\nENVI @@Visible=%&WID%:3                           // 最大化\nENVI @@Visible=%&WID%:*4                          // 最小化（* = 第2种方案）\nENVI @@Visible=%&WID%:5                           // 恢复\nENVI @@Visible=?%&WID%:&&state                    // query visibility state\n```\n\n---\n\n## 27. @this. 自引用与窗口属性\n\n`@this.` 引用当前窗口自身，无需知道窗口 ID。SDK 示例广泛使用。\n\n```wcs\n_SUB MyWin,W400H300,Test,\n    // --- 属性设置（@this = 当前窗口）---\n    ENVI @this.Font=12:Microsoft YaHei\n    ENVI @this.bkcolor=0xF0F0F0\n    ENVI @this.Cursor=32649                         // 手型光标 (IDC_HAND)\n    ENVI @this.trans=1*                             // 背景透明（*=透明色模式）\n    ENVI @this.trans=0x2                            // 完全透明\n    ENVI @this.style=0x00040000:0x00C00000          // 去掉WS_SIZEBOX,加上WS_CAPTION\n    ENVI @this.nxp=                                  // 禁用 XP 视觉样式\n    ENVI @this.Paint=OnPaint                        // WM_PAINT 回调\n    ENVI @this.HitTest=20                           // 顶部20像素可拖动（高=20）\n    ENVI @this.HitTest=-20                          // 半透明穿透拖动\n\n    // --- 控件属性 ---\n    ENVI @Edit1.ReadOnly=1                          // EDIT 只读\n    ENVI @Edit1.LINE=10                             // EDIT/MEMO 滚动到第10行\n    ENVI @this.MouseCapture=1                       // 捕获鼠标（0=释放）\n\n    // --- 动态命令 ---\n    ENVI @this.cmd=CALL MyHandler                   // 设置窗口响应命令\n    ENVI @this.cmd?=&currentCmd                     // 查询当前命令（需先 ENVI^ QueryCmd=1）\n\n    // --- 跨进程查询 ---\n    ENVI @@Pos=?%&WID%:&L:&T:&W:&H                 // 查询位置\n    ENVI @@Pos=?%&WID%:&L:&T:&W:&H:&SX:&SY::&Z    // 扩展：含屏幕坐标和层叠序\n\n    // --- 完整 POS 设置语法 ---\n    // ENVI @@POS=wid:L:T:W:H:Z:trans:front:activate\n    // Z 值: 1=底部, 2=移除置顶, 3=置顶, 4=始终置顶(钉住)\n    // trans: 0-255 透明度\n    // front: 1=前台激活\n    // activate: 0=不改变焦点\n    // @前缀: 绝对屏幕坐标; 无@: 客户区坐标\n    ENVI @@POS=%&WID%:100:100:400:300:3:$200       // 置顶+半透明（$=0-255格式透明度）\n    ENVI @this.POS=100:100:400:300                  // 设置位置（相对）\n    ENVI @this.POS=?;&L;&T;&W;&H                   // 查询位置（分号分隔）\n    ENVI @@IsWindow=?%&WID%:&valid                  // 检查窗口是否有效\n    ENVI @@Enable=?%&WID%:&enabled                  // 查询启用状态\n\n    // --- 跨进程消息发送 ---\n    ENVI @@SENDMSG=%&hwnd%:#0x0010;0;0             // 同步发送 WM_CLOSE\n    ENVI @@POSTMSG=%&hwnd%:#1;0;0                  // 异步投递自定义消息 #1\n    ENVI @this.MSG=0x1000: CALL OnMouseEnter       // WM_MOUSEENTER (PECMD 自定义 0x1000)\n```\n\n---\n\n## 28. 缺少的控件类型（DTIM/IPAD/SLID/SBAR/GROU）\n\n### DTIM — 日期时间选择器\n\n```wcs\nDTIM DTIM1,L10T10W200H25,初始值,命令,类型\n// 初始值: \"2008;5;12\" 等年;月;日格式（分号分隔）\n// 查询值（最多5个：年月日周标志 或 时分秒标志）:\nENVI @DTIM1.VAL=?&&year;&&month;&&day;&&weekday;&&flag\n// 设置值（3字段：年;月;日 或 时;分;秒）:\nENVI @DTIM1.VAL=2024;1;15\n// 鼠标悬停/离开消息:\nENVI @DTIM1.MSG=0x1000: CALL OnMouseEnter   // WM_MOUSEENTER\nENVI @DTIM1.MSG=0x1001: CALL OnMouseLeave   // WM_MOUSELEAVE\n```\n\n### IPAD — IP 地址编辑器\n\n```wcs\nIPAD IPAD1,L10T10W200H25,,命令,状态\n// 查询 IP:\nENVI @IPAD1.VAL=?&&ip1;&&ip2;&&ip3;&&ip4        // 无前缀点：分别返回4段\nENVI @IPAD1.VAL=?.FullIP                         // 带前缀点：返回完整IP字符串\n// 设置 IP:\nENVI @IPAD1.VAL=192.168.1.100                    // 点分格式\n// 设置焦点:\nENVI @IPAD1.VAL=#3                               // #前缀+段号，聚焦到第3段\n// 设置范围:\nENVI @IPAD1.VAL=#3:0:255                         // #段号:最小:最大（段号1-4）\n```\n\n### SLID — 滑块控件\n\n```wcs\nSLID [-right] [-left] [*] SLID1,形状[,值信息,命令,状态]\n// 值信息: [起始值][:终到值][:初值][:页大小]，默认 0:100:0\nSLID SLID1,L10T10W200H30,0:100:50:1,CALL OnSlide,0\n// 查询/设置值:\nENVI @SLID1.VAL=?&&val                           // 查询当前值\nENVI @SLID1.VAL=75                               // 设置值\n```\n\n### SBAR — 滚动条控件\n\n```wcs\nSBAR SBAR1,L10T10W200H20,,命令,状态\n// 查询/设置值:\nENVI @SBAR1.VAL=?&&pos:&&min:&&max:&&page         // 查询位置、范围和页大小\nENVI @SBAR1.VAL=50:0:100:20                      // 当前值:起始值:终到值:页大小\n// 启用/禁用和可见性:\nENVI @SBAR1.Enable=0                             // 禁用\nENVI @SBAR1.Visible=0                            // 隐藏\n```\n\n### GROU — 分组面板\n\n```wcs\nGROU [-right] [-center] [*] GROU1,形状,[标题],[状态],[前景色#背景色],[字体]\nGROU GROU1,L10T10W380H200,设置选项,,0x000000#0xF0F0F0,12\n// 状态 ±16 = 不可见（正负均可）\nGROU GROU1,L10T10W380H200,高级,,-0x10             // 隐藏的分组\n// -right: 标题右对齐, -center: 标题居中\n```\n\n---\n\n## 32. SWIN 嵌套窗口（选项卡页）\n\n完整的属性页模式：将每个子窗口定义为 `_SUB`，在父窗口中使用 `SWIN` 嵌入，通过 `TABS.SEL` 在选项卡点击时切换可见页面。\n\n```wcs\n#code=65001\nENVI^ EnviMode=1\nENVI^ ForceLocal=1\nSET$ &NL=0d 0a\n\nCALL @主窗口\n\n_SUB 主窗口,W500H380,Tabbed Settings,,#1,,\n    ENVI @this.Font=12:Microsoft YaHei\n    TEAM ENVI &&nTab=0| ENVI &&TabSel=1\n\n    // --- TABS control (page buttons) ---\n    TABS TabMain,L10T10W480H40\n\n    // --- SWIN containers for each page ---\n    SWIN :PageGeneral,L10T55W480H290\n    SWIN :PageNetwork,L10T55W480H290,,0x10         // hidden initially\n    SWIN :PageAdvanced,L10T55W480H290,,0x10        // hidden initially\n\n    // --- Populate tabs ---\n    LOOP #%&nTab%<3,\n    {\n        CALC &nTab=%&nTab%+1\n        IFEX $%&nTab%=1, ENVI @TabMain.ADD=General\n        IFEX $%&nTab%=2, ENVI @TabMain.ADD=Network\n        IFEX $%&nTab%=3, ENVI @TabMain.ADD=Advanced\n    }\n    ENVI @TabMain.SEL=%&TabSel%                     // select first tab by default\n\n    ITEM BtnOK,L200T352W100H30,OK,CALL OnOK\n_END\n\n_SUB OnTabSel\n    ENVI @TabMain.SEL=?&&sel\n    ENVI @PageGeneral.Visible=0\n    ENVI @PageNetwork.Visible=0\n    ENVI @PageAdvanced.Visible=0\n    IFEX $%&sel%=1, ENVI @PageGeneral.Visible=1\n    IFEX $%&sel%=2, ENVI @PageNetwork.Visible=1\n    IFEX $%&sel%=3, ENVI @PageAdvanced.Visible=1\n_END\n\n_SUB PageGeneral\n    ENVI @this.bkcolor=0xFFFFFF\n    LABE ,L10T10W200H20,General Settings,,0x000000,10\n    CHEK ChkAutoRun,L10T40W200H20,Auto start with Windows,,1\n    EDIT EdtName,L10T70W460H24,MyApp,,12\n_END\n\n_SUB PageNetwork\n    ENVI @this.bkcolor=0xFFFFFF\n    LABE ,L10T10W200H20,Network Configuration,,0x000000,10\n    EDIT EdtIP,L10T40W200H24,192.168.1.100,,12\n    EDIT EdtPort,L10T74W200H24,8080,,12\n_END\n\n_SUB PageAdvanced\n    ENVI @this.bkcolor=0xFFFFFF\n    LABE ,L10T10W200H20,Advanced Options,,0x000000,10\n    CHEK ChkDebug,L10T40W200H20,Enable debug logging,,1\n    CHEK ChkEncrypt,L10T70W200H20,Encrypt traffic,,0\n_END\n\n_SUB OnOK\n    IFEX $%ChkAutoRun.Check%=1, MESS AutoRun: ON\n    MESS IP=%&EdtIP%:%&EdtPort%@Info#OK\n    KILL \\\n_END\n```\n\n关键点：\n- `_SUB` 类定义可在文件中任意位置（PECMD 解析时解析），但 SWIN 实例需引用已定义的类名。\n- 使用 `0x10` 标志初始隐藏页面。\n- `TABS.SEL=<n>` 选择选项卡；`TABS.SEL=?` 查询当前选择。\n- 通过 `ENVI @PageName.Visible=0` / `=1` 切换可见性。\n\n---\n\n## 33. 动态行创建与批量删除\n\n运行时通过变量展开的命令字符串构建控件。在循环中批量删除控件组。\n\n```wcs\n_SUB CreateRow\n    SET &row=%~1\n    CALC #&y=50 + %&row% * 35\n    ENVI &&cmd=LABE -vcenter LblName%&row%,L20T%&y%W150H30,Item %&row%,,0x000000,12\n    %&cmd%\n    ENVI &&cmd=EDIT EdtVal%&row%,L180T%&y%W100H24,value%&row%,,12\n    %&cmd%\n    ENVI &&cmd=ITEM BtnDel%&row%,L290T%&y%W60H28,Del,CALL OnDelRow %&row%\n    %&cmd%\n_END\n\n_SUB OnDelRow\n    SET &row=%~1\n    ENVI @LblName%&row%.*del=                    // destroy label\n    ENVI @EdtVal%&row%.*del=                     // destroy edit\n    ENVI @BtnDel%&row%.*del=                     // destroy button\n_END\n\n_SUB ClearAllRows\n    SET &i=0\n    LOOP #%&i%<10,\n    {\n        CALC &i=%&i%+1\n        ENVI @LblName%&i%.*del=\n        ENVI @EdtVal%&i%.*del=\n        ENVI @BtnDel%&i%.*del=\n    }\n_END\n\n// --- Usage in a window context ---\n// Create 5 rows:\nSET &n=0\nLOOP #%&n%<5,\n{\n    CALC &n=%&n%+1\n    CALL CreateRow %&n%\n}\n```\n\n关键点：\n- `ENVI @CtrlName.*del=` 销毁控件并释放其资源。\n- 变量中的命令字符串（`%&cmd%`）是使用动态计算控件名的唯一方法。\n- 批量删除循环必须注意在控件已预索引时不要跳过索引。\n\n---\n\n## 36. TABL 通过 LVM 消息控制滚动条\n\n使用 `SENDMSG` 发送列表视图消息以控制滚动。消息作用于底层的 SysListView32 控件。\n\n```wcs\n#code=65001\nSET$ &NL=0d 0a\nSET$ &TAB=09\n\n// LVM constants\nSET &::LVM_FIRST=0x1000\nSET &::LVM_SCROLL=%&::LVM_FIRST% + 20               // 0x1014\nSET &::LVM_ENSUREVISIBLE=%&::LVM_FIRST% + 19        // 0x1013\nSET &::LVM_GETITEMCOUNT=%&::LVM_FIRST% + 4          // 0x1004\nSET &::LVM_GETCOUNTPERPAGE=%&::LVM_FIRST% + 40      // 0x1028\nSET &::LVM_GETTOPINDEX=%&::LVM_FIRST% + 39          // 0x1027\n\nCALL @主窗口\n\n_SUB 主窗口,W600H400,Table Scroll Demo,,#1,,\n    ENVI @this.Font=12:Microsoft YaHei\n    ENVI &&Title=100:Name%&TAB%=60:PID%&TAB%+80:Memory\n\n    TABL Table1,L10T10W580H300,%&Title%,,0x10040\n\n    // Fill table with sample data\n    SET &i=0\n    LOOP #%&i%<100,\n    {\n        CALC &i=%&i%+1\n        ENVI @Table1.Val=%&i%;Process%&i%%&TAB%%&i%00%&TAB%%&i%M\n    }\n\n    ITEM BtnBottom,L10T320W140H35,Scroll to Bottom,CALL ScrollBot\n    ITEM BtnSel,L160T320W140H35,Scroll to Selection,CALL ScrollSel\n    ITEM BtnPageDn,L310T320W140H35,Page Down,CALL ScrollPgDn\n    ITEM BtnEnsure,L460T320W130H35,Ensure Row 77,CALL EnsureRow\n_END\n\n_SUB ScrollBot\n    // Get item count, scroll by that many lines down\n    ENVI @Table1.POSTMSG=%&::LVM_GETITEMCOUNT%\n    WAIT 50\n    ENVI @Table1.SENDMSG=%&::LVM_SCROLL%,0,50                     // 0=dx, 50=dy (lines)\n    // Alternative: scroll to very large line offset\n    // ENVI @Table1.SENDMSG=%&::LVM_SCROLL%,0,999999\n_END\n\n_SUB ScrollSel\n    ENVI @Table1.Sel=?&&sel\n    IFEX $%&sel%<1, EXIT _SUB\n    ENVI @Table1.SENDMSG=%&::LVM_ENSUREVISIBLE%,%&sel% - 1,0       // 0-based index, partialOK=0\n_END\n\n_SUB ScrollPgDn\n    // Get visible rows per page, scroll by that amount\n    // Simplistic: send a fixed vertical scroll\n    ENVI @Table1.SENDMSG=%&::LVM_SCROLL%,0,20                       // scroll down 20 lines\n_END\n\n_SUB EnsureRow\n    ENVI @Table1.SENDMSG=%&::LVM_ENSUREVISIBLE%,76,0               // row 77 (0-based)\n_END\n```\n\n注意：`SENDMSG` 发送到最后获得焦点/前台窗口。在 GUI 上下文中，可能需要先聚焦表格或使用 `ENVI @Table1.SENDMSG`（PECMD 2012 扩展）。跨进程或精确控制时使用 `CALL $ user32.dll,SendMessageW`。\n\n---\n\n## 37. TABL 行内排序（冒泡排序）\n\n将所有行读入内存，按目标列冒泡排序，重写表格。\n\n```wcs\n_SUB SortTableByCol\n    SET &col=%~1                                    // 1-based column to sort by\n    ENVI @Table1.Val=?*;&&rows                       // total rows\n\n    // --- Read all rows into array variables ---\n    SET &i=0\n    LOOP #%&i%<%&rows%,\n    {\n        CALC &i=%&i%+1\n        ENVI @Table1.Val=?%&i%;&&Row[%&i%]\n    }\n\n    // --- Numeric sort: bubble sort ---\n    SET &i=0\n    LOOP #%&i%<%&rows%,\n    {\n        CALC &i=%&i%+1\n        SET &j=%&i%\n        LOOP #%&j%<%&rows%,\n        {\n            CALC &j=%&j%+1\n            MSTR &&vA=<%&col%>%%&Row[%&i%]%%\n            MSTR &&vB=<%&col%>%%&Row[%&j%]%%\n            // Numeric comparison (use # for number):\n            SED &&nA=0,[^0-9],,%&vA%\n            SED &&nB=0,[^0-9],,%&vB%\n            FIND $=&nA=, SET nA=0\n            FIND $=&nB=, SET nB=0\n            // Swap if a > b (ascending)\n            IFEX $%&nA%>%&nB%,\n            {\n                SET &tmp=%%&Row[%&i%]%%\n                SET &Row[%&i%]=%%&Row[%&j%]%%\n                SET &Row[%&j%]=%&tmp%\n            }\n        }\n    }\n\n    // --- String sort alternative (by column text) ---\n    // LOOP ...\n    //     MSTR &&sA=<%&col%>%%&Row[%&i%]%%\n    //     MSTR &&sB=<%&col%>%%&Row[%&j%]%%\n    //     FIND $%&sA%>%&sB%,                             // lexicographic \"greater\" for ascending\n    //     {\n    //         SET &tmp=%%&Row[%&i%]%%\n    //         SET &Row[%&i%]=%%&Row[%&j%]%%\n    //         SET &Row[%&j%]=%&tmp%\n    //     }\n\n    // --- Rewrite table ---\n    SET &i=0\n    LOOP #%&i%<%&rows%,\n    {\n        CALC &i=%&i%+1\n        ENVI @Table1.Val=%&i%;%%&Row[%&i%]%%\n    }\n_END\n\n// Usage:\n// CALL SortTableByCol 3          // sort by 3rd column\n```\n\n关键点：\n- 双百分号 `%%&Row[%&i%]%%` 解引用：第一个 `%%` 求值为 `%`，然后 `%&Row[3]%` 读取变量。\n- `FIND $str1>str2` 进行字典序\"大于\"比较（比较两个字符串，第一个 > 第二个时为真）。数值比较请改用 `|` 前缀。\n- 数值比较前用 `SED` 移除非数字字符以提取数值。\n\n---\n\n## 38. 自定义标题栏窗口（无边框 + 手动标题）\n\n无边框窗口，使用 LABE 控件构建仿标题栏。处理最小化、关闭、悬停颜色效果以及通过 `WM_NCHITTEST` 实现的窗口拖动。\n\n```wcs\n#code=65001\nENVI^ EnviMode=1\nENVI^ ForceLocal=1\n\nSET &::WM_LBUTTONDOWN=0x0201\nSET &::WM_LBUTTONUP=0x0202\nSET &::WM_MOUSEMOVE=0x0200\nSET &::WM_NCHITTEST=0x0084\nSET &::HTCAPTION=2\n\nCALL @CustomWin\n\n_SUB CustomWin,W500H350,My Custom Tool,,#1,, -trap -nocap\n    ENVI @this.Font=12:Microsoft YaHei\n    ENVI @this.bkcolor=0xF0F0F0\n\n    // --- Fake title bar background ---\n    LABE -center TitleBar,L0T0W500H32,,,0xFFFFFF#0x2D2D30\n\n    // --- Fake icon ---\n    LABE -center -vcenter LblIcon,L8T4W24H24, ,0xFFFFFF#0x2D2D30#0xFFFFFF#0x3D3D40\n    ENVI @LblIcon.MSG=%&::WM_LBUTTONDOWN%: CALL @--popmenu SysMenu\n\n    // --- Title text ---\n    LABE -center -vcenter LblTitle,L36T4W360H24,My Custom Tool,,0xFFFFFF#0x2D2D30\n\n    // --- Minimize button ---\n    LABE -center -vcenter BtnMin,L412T4W36H24,_,CALL OnMin,0xCCCCCC#0x2D2D30#0xFFFFFF#0x3D3D40\n\n    // --- Close button ---\n    LABE -center -vcenter BtnClose,L452T4W40H24,X,CALL OnClose,0xCCCCCC#0x2D2D30#0xFFFFFF#0xE81123\n\n    // --- Drag support: whole title bar reports as HTCAPTION ---\n    ENVI @TitleBar.MSG=%&::WM_NCHITTEST%: ENVI @TitleBar.POSTMSG=%&::HTCAPTION%\n    ENVI @LblTitle.MSG=%&::WM_NCHITTEST%: ENVI @LblTitle.POSTMSG=%&::HTCAPTION%\n\n    // --- Main content area ---\n    LABE -vcenter LblContent,L20T50W460H280,Content goes here,,0x000000,12\n\n    // --- Fake status bar ---\n    LABE -vcenter LblStatus,L0T330W500H20,Ready,,0xAAAAAA#0x2D2D30\n_END\n\n_SUB SysMenu\n    MENU 关于,About,CALL OnAbout\n    MENU -\n    MENU 退出,Exit,KILL \\\n_END\n\n_SUB OnMin\n    ENVI @@Visible=%&__WinID%:4                      // PECMD @@Visible 常量: 0=隐藏, 1=显示, 2=正常, 3=最大化, 4=最小化, 5=恢复\n_END\n\n_SUB OnClose\n    KILL \\\n_END\n\n_SUB OnAbout\n    MESS Custom Title Bar Demo v1.0@About#OK\n_END\n```\n\n关键点：\n- `-nocap` 移除系统标题栏；`-trap` 防止关闭按钮自动退出。\n- 在 LABE 控件上通过 `WM_NCHITTEST` 返回 `HTCAPTION` 使其可拖动。\n- 4段颜色格式 `文本色#背景色#悬停文本色#悬停背景色` 启用悬停效果。\n- 按钮字形使用 ASCII 字符（`_` = 最小化、`X` = 关闭），或直接写入 Unicode 字符（UTF-8 编码）。\n\n---\n\n## 64. TREE 控件（层级节点视图）\n\n### 创建带图标和节点层级的树形控件\n\n```wcs\n// TREE 格式: TREE [名称],<形状>,[图片数据],[节点数据],[状态]\n// 节点数据格式: \\图标索引:选择图标索引:文本，0x09分隔节点，0x0B开始子节点，0x0C结束子节点\n// 图片数据格式: 表头.[:图标宽:图标高]图标1%TAB%图标2...\n\n// 用 SET$ 构建含控制字符的节点数据\nSET$ &TAB=09\nSET$ &CHILDBEGIN=0b\nSET$ &CHILDEND=0c\nSET &MUI_NODE_DATA=\\0:0:Root1%&CHILDBEGIN%\\0:0:Child1.1%&TAB%\\0:0:Child1.2%&CHILDEND%\\1:1:Root2%&CHILDBEGIN%\\1:1:Child2.1%&CHILDEND%\n\n// 图片数据（可选，不需要图片时留空）\nSET &IMAGELIST=icons.16:16%&TAB%icon1.ico%&TAB%icon2.ico\n\nTREE Tree1,L10T10W300H300,%&IMAGELIST%,%&MUI_NODE_DATA%,0x10000127\n\n// Expand / Collapse nodes（格式: 节点;值，值: 1=折叠 2=展开 3=切换）\nENVI @Tree1.Expand=1;2               // expand node 1\nENVI @Tree1.Expand=2.1;1             // collapse node 2.1\nENVI @Tree1.Expand=4;3               // toggle node 4\n\n// Select a node\nENVI @Tree1.Sel=2.2                 // select node 2.2\nENVI @Tree1.Sel=?*2;&&node1         // query selected node path\nENVI @Tree1.Sel=?@&&hnode           // query selected node handle\n\n// Checkbox state\nENVI @Tree1.Check=3.1;2             // toggle (0=unchecked, 1=checked, 2=toggle/乒乓)\nENVI @Tree1.Check=?*;&&state        // query checkbox state\n```\n\n### 处理 TVN_ITEMCHANGEDW（复选框变更通知）\n\n```wcs\nENVI @Tree1.ID=?;&&Tree1_ID                        // 获取控件 ID\nCALC -base=16 #&&TVN_ITEMCHANGEDW=0x100000000-419\nENVI @this.MSG=NOTIFY#%&Tree1_ID%#%&&TVN_ITEMCHANGEDW%::&&wp,&&lp, CALL OnItemChanged %&&wp% %&&lp%\n\n_SUB OnItemChanged\n    // parse NMTREEVIEW struct for changed item\n_END\n```\n\n---\n\n## 65. TIPS/TIPS* 系统托盘与 TABL 高级操作\n\n### 系统托盘（TIPS/TIPS*）\n\n```wcs\n// 创建全局托盘图标（与任务栏共享）\nTIPS 托盘名,提示文本,图标路径,命令\nTIPS* 托盘名,提示文本,图标路径,命令           // * = 窗口私有托盘图标\n\n// 在窗口 _SUB 中使用\n_SUB MyWin,W400H300,Tray App,,#1,,\n    TIPS* MyTray,My App,shell32.dll#43,        // 创建私有托盘图标\n_END\n\n// 更新托盘提示文本\nTIPS* MyTray,新提示文本,,\n\n// 最小化到托盘\n_SUB OnMin\n    ENVI @this.Visible=0                       // 隐藏窗口\n    // 点击托盘图标时恢复：\n_END\n\n_SUB DoMenu\n    IFEX $%2=%&WM_RBUTTONDOWN%, CALL @--popmenu TrayMenu\n    IFEX $%2=%&WM_LBUTTONDOWN%, ENVI @this.Visible=1\n_END\n\n_SUB TrayMenu\n    MENU 显示窗口,Show,ENVI @this.Visible=1\n    MENU -\n    MENU 退出,Exit,KILL \\\n_END\n```\n\n### TABL 行内着色与高级操作\n\n```wcs\n// 创建带颜色的表格（4 色格式：背景#文字背景#默认文字#选中行）\nTABL -color:0x00F000#0x808000#0xF0E0FF#0x80 Table1,L10T10W500H300,%&Title%,,0x10040\n\n// 单元格着色（格式：行.列;;颜色）\nENVI @Table1.Color=3.2;;0xFF                         // 第3行第2列，红色（BGR）\n// 行着色（* 前缀）\nENVI @Table1.Color=*5;;0xFFFF00                       // 第5行整行，黄色\n// 查询鼠标下单元格\nENVI @Table1.Sel=?.&&Row;&&Col                        // 获取鼠标所在的行.列\n\n// 行内进度条（Percent）\nENVI @Table1.Percent=3.2;75                           // 第3行第2列显示75%进度条\nENVI @Table1.Percent=3.2;50;C:::0xFF0000:Loading      // 红色进度条+文字\n// C=居中, R=右对齐, L=左对齐, F=填充, K=块模式\n\n// 行级使能/禁用（~ 前缀）\nENVI @Table1.Enable=~3;0                               // 禁用第3行\nENVI @Table1.Enable=~?*;&disabledRows                  // 查询禁用行\n\n// TABS 动态修改标签\nENVI @TabMain.Title1=新标题                             // 修改第1个标签的标题\nENVI @TabMain.Tip1=新提示                               // 修改第1个标签的提示\nENVI @TabMain.SEL=?&&sel                                // 查询当前选中的标签索引\n```\n\n---\n\n## 67. GDI 绘制（WM_PAINT 绘图）\n\n### 将 GDI 函数注册为别名\n\n```wcs\nENVI^ Alias -opt Rectangle=CALL $--qd# --ret:* Gdi32.dll,Rectangle,*dummy,\nENVI^ Alias -opt Ellipse=CALL $--qd# --ret:* Gdi32.dll,Ellipse,*dummy,\nENVI^ Alias -opt Polyline=CALL $--qd# --ret:* Gdi32.dll,Polyline,*dummy,\n```\n\n### 带绘制回调和动画的窗口\n\n```wcs\n_SUB CanvasWin,W260H320,Canvas Demo,\n    ENVI @this.Paint=OnPaint               // set WM_PAINT handler\n    SET &aw=2\n    SET &w=10\n    TIME &Timer1,50, ENVI @this.InvalidateRect=;;;230;\n_END\n\n_SUB OnPaint                               // %1=HDC, %2=width, %3=height\n    SET &w0=115 & &h0=115                           // 中心点\n    CALC #L=%&w0% - %&w%\n    CALC #T=%&h0% - %&w%\n    CALC #R=%&w0% + %&w%\n    CALC #B=%&h0% + %&w%\n    Rectangle %1,%L%,%T%,%R%,%B%\n    Ellipse %1,%L%,%T%,%R%,%B%\n    CALC #&w=%&w% + %&aw%\n    IFEX $%&w%>100, TEAM SET &aw=-2| CALC #&w=%&w% + %&aw%!\n    IFEX $%&w%<0, TEAM SET &aw=2| CALC #&w=%&w% + %&aw%\n_END\n```\n\n### 使用 POINT 数组绘制折线\n\n```wcs\nSET$ &Pt= 0x0064 0x0000  0x0000 0x0000  0x00C8 0x0000  0x0064 0x00C8  *200 0\nENVI-addr &&PtAddr=&Pt\n\n_SUB OnPaint\n    Polyline %1,%&PtAddr%,4\n_END\n```\n\n---\n\n## 68. PBAR / SPIN 控件（进度条与微调器）\n\n### 带颜色和文字覆盖的进度条\n\n```wcs\nPBAR PBAR1,L22T13W200H16,20               // initial value = 20%\nENVI @PBAR1.color=0xFF                     // text color (BGR red)\n\n// Update progress with text overlay (help.txt: 进度[;[#颜色:]文本])\nENVI @PBAR1=50;#00FF00:Processing...       // 50%, green text\nENVI @PBAR1=%&p%;%&K%s  %&p%%%            // value;text\n```\n\n### 绑定到 EDIT 的 SPIN 微调控件\n\n```wcs\nEDIT EDIT1,L28T14W158H29,0,,\nSPIN SPIN1,L192T13W22H30,EDIT1:-20:5,&&npos:&&button:&&old,\n    ENVI @LABE3= SPIN1 [%&&npos%] [%&&button%] [%&&old%], 0xA0\n\n// Query value and range\nENVI @SPIN1.VAL=?&&POS:&&FROM:&&TO\n\n// Set value and range\nENVI @SPIN1.VAL=%&POS%:-20:5               // current, min=-20, max=5\n```\n\n---\n\n## 69. WM_DROPFILES 拖放\n\n### 在窗口或控件上启用文件拖放\n\n```wcs\nSET &WM_DROPFILES=0x0233\n\n// Register drop handler on EDIT control (type 0x100 = accept dropped file)\nEDIT|- EDIT1,L10T10W400H200,,0x100\nENVI @EDIT1.MSG=%&WM_DROPFILES%::&&wp,&&lp, CALL OnDrop %&wp% %&lp%\n\n// Register drop handler on window\nENVI @this.MSG=%&WM_DROPFILES%::&&wp,&&lp, CALL OnDrop %&wp% %&lp%\n```\n\n### 提取拖放的文件路径\n\n```wcs\n_SUB OnDrop\n    ENVI ?&&firstFile,&&allFiles=DROPFILE,%1    // %1 = wParam\n    MESS Dropped: %&&allFiles%\n    ENVI @EDIT1=%&&allFiles%\n_END\n```\n\n---\n\n## 70. RICHEDIT 富文本格式化\n\n### 创建富文本编辑控件\n\n```wcs\n// -rich flag enables rich text mode on EDIT/MEMO\nEDIT|- -rich RichEdit1,L10T10W400H300,Default text,,0x200\nMEMO-+ -rich &&RichBox,L10T10W400H300,,0x200\n```\n\n### 对特定文本范围着色和格式化\n\n```wcs\n// Format: [:fontsize[:fontname:]BITUL;][color[#bgcolor]][;start_pos[;end_pos]]\n// B=Bold, I=Italic, U=Underline, T=Strikeout, L=Link\nENVI @RichEdit1.COLOR=:20:Consolas:BI;0xFF;0;3      // Bold+Italic, red, pos 0-3\nENVI @RichEdit1.COLOR=:12;0xFF00;3;6                  // green, pos 3-6\nENVI @RichEdit1.COLOR=:9;0xFF0000;6;9                 // red (BGR), pos 6-9\nENVI @RichEdit1.COLOR=:10;0xFF00FF;2:;4:              // magenta, line 2 to line 4\n```\n\n### 编程式文本替换\n\n```wcs\nSET &EM_SETSEL=0x00B1\nSET &EM_REPLACESEL=0x00C2\nENVI @RichEdit1.SENDMSG=%&EM_SETSEL%,startPos,endPos\nENVI @RichEdit1.SENDMSG=%&EM_REPLACESEL%,0,$newText\n```\n\n---\n\n## 71. IMAG 高级（GIF 动画与动态更新）\n\n### GIF 动画显示\n\n```wcs\nIMAG IMAG1,L10T10W200H150,animation.gif,EXEC calc.exe     // click runs calc\nENVI @IMAG1.delay=2000                                     // set frame delay to 2s\n```\n\n### 运行时动态更新图像\n\n```wcs\n// Update: update=w:h[:x:y:border_color:border_width][;filename]\nENVI @IMAG1.update=32:32;shell32.dll#52                    // replace with icon #52\nENVI @IMAG1.update=64:64::;*newimage.png                   // * = new image\nENVI @IMAG1.update=32:32::;?overlay.png                    // ? = overlay on existing\n\n// Source rectangle: <X:Y:W;H>filename\nENVI @IMAG1.update=64:64::<0:0:32;32>source.bmp            // crop region\n```\n\n### IMAG 作为交互式图像按钮\n\n```wcs\nIMAG ImgBtn,L10T10W64H64,#1000,CALL OnImageClick          // resource icon as button\nCHEK -scale:(51*96/12)<123:51>:bg.png ImgChk,L100T100W123H53,,CALL OnCheck\nRADI -scale:(51*96/12)<123:51>:bg.png ImgRad,L100T200W123H53,,CALL OnRadio\n```\n\n---\n\n### 52. 通过 GetScrollInfo API 控制滚动条\n\n```wcs\nSET &SIF_RANGE=0x0001\nSET &SIF_PAGE=0x0002\nSET &SIF_POS=0x0004\nSET &SIF_TRACKPOS=0x0010\nSET &SIF_ALL=0x0017\n\nSET &SCROLLINFO.SIZE=28  // cbSize(4)+fMask(4)+nMin(4)+nMax(4)+nPage(4)+nPos(4)+nTrackPos(4)\nENVI$ &&si=*28 0\nSET-long &&si=28:0           // cbSize=28\nSET-long &&si=%&SIF_ALL%:4    // fMask\n\nCALL $--qd --ret:&bret user32.dll,GetScrollInfo,#%&TBID%,#0,*&si  // SB_HORZ=0\nSET?int &&si=&&nPos:20        // current scroll position\n\n// Horizontal column position:\nCALC &&col=ceil(%&nPos% / %&ColumnWidth%) + 1\n\n// Scroll to specific position via message:\nSET @@sendmsg=%&TBID%;%&lvm_scroll%;%&Pos%;0\n// Or scroll to row: SET @@sendmsg=%&TBID%;%&lvm_ensurevisible%;%&index%;0\n```\n\n---\n\n## 72. TABS 跨页控件访问\n\n### 从子函数访问同级页面控件\n\n```wcs\n_SUB Page1,W289H249,P1,,,#\n    LIST L01,L18T20W240H20,,,,0x100\n_END\n_SUB Page2,W289H249,P2,,,#\n    LIST L02,L18T20W240H20,,,,0x100\n_END\n_SUB WIN3,W350H333,Tab Switch,\n    TABS TABS1,L21T4W300H188,Page1:Name1:Title1:tip1;Page2:Name2:Title2:tip2\n    ITEM ITEM2,L218T272W96H30,Close,KILL \\\n_END\n\n// From a child function (e.g., called by Page1's event handler):\n_SUB ADD2LIST\n    ENVI &&PARENT=-:-:                               // two levels up in execution stack\n    ENVI @%&PARENT%Name1:L01.VAL=%&ToList%           // access Page1's LIST\n    ENVI @%&PARENT%Name2:L02.VAL=%&ToList%           // access Page2's LIST\n_END\n\n// Shortcut from parent window (WIN3 itself):\n// ENVI @Name1:L01.VAL=%&ToList%   // no \"-\" needed when directly in parent\n```\n\n关键点：`-` 沿执行栈向上导航（非窗口层级）。每个 `-` = 一级。\n名称沿窗口-控件树向下导航。\n\n---\n\nFile v1.7.1:references/how-tos/net.md\n\n# 网络/SOCK/COM/WMI — 写法示例\n\n> **版本兼容性：** 部分示例使用 DLL 调用（`CALL $--qd`）。DLL 调用需要 PECMD2012 v1.88+ 完整版支持（32-bit 和 64-bit 行为一致）。\n> 如果 DLL 调用不工作，可使用 `EXEC*`（外部命令）、`REGI`（注册表）等内置命令替代。\n\n## 16. 网络操作\n\n### 获取网卡 IP\n\n```wcs\nEXEC* &&ipcfg=!ipconfig                          // EXEC* 捕获标准输出; ! = 隐藏执行\nFORX *NL &ipcfg,&&line,\n{\n    SED &&found=1,IPv4,,%&line%\n    IFEX $1=%&found%,\n    {\n        MSTR &&ip=<-1>%&line%                   // last field = IP address\n        MSTR &&ip=<2>%&ip%                       // strip leading space\n        MESS IP: %&ip%\n    }\n}\n```\n\n### WiFi 扫描与连接\n\n```wcs\nADSL-wlan ,,list,&&wifiInfo                     // scan nearby networks\nADSL-wlan ,,scan,&&detail                        // detailed scan\nADSL-wlan MyNetwork,mypassword,WPA2PSK          // connect (plain text SSID/password)\nADSL-wlan -start MyNetwork,mypassword           // connect and start\n```\n\n### Ping 检测\n\n```wcs\nEXEC* &result=!ping -n 1 192.168.1.1\nFIND TTL=,%&result%,MESS Host reachable             // substring search (no $ = contains)\n```\n\n---\n\n## 29. NET 与网卡操作\n\n```wcs\n// Full network adapter query\nPCIP ?* IP,MASK,GW,DNS,%NIC%?NAME,MAC,LINK,DHCP,bDHCP,STATUS,MEDIA,DESC,TYPE\n\n// Set static IP\nPCIP 192.168.1.100,255.255.255.0,192.168.1.1,192.168.1.1\n\n// DHCP\nPCIP DHCP\n```\n\n---\n\n## 65. SOCK 网络（TCP/UDP 客户端-服务器）\n\n### TCP 服务器（带 accept 循环）\n\n```wcs\nSOCK sk                                    // server listen socket (TCP default)\nENVI @sk.sock=&&err                        // create socket\nENVI#$ &&v=1\nENVI @sk.setsockopt=;;%&SO_REUSEADDR%,&&v  // SO_REUSEADDR\nENVI @sk.bind=&&err;%&MYIP%;%&MYPORT%      // bind to IP:port\nENVI @sk.listen=&&err;1                     // listen (backlog=1)\n\nTHREAD* CALL Server\n\n_SUB Server\n    SOCK sr                                // accept socket\n    ENVI @sk.fd=&&fd                       // get listen fd\n    ENVI @sr.accept=&&err;%&fd%            // accept connection\n    ENVI @sr.getname=;1;&&remoteIP         // get remote IP\n\n    // Read loop\n    ENVI @sr.read=&&err;&Len;&BRMSG        // read data\n    IFEX $%&Len%>0, ENVI @this.SENDMSG=#1  // notify main thread\n\n    // Send response\n    ENVI @sr.write=&&err;&Len;&Response    // write data\n_END\n```\n\n### TCP 客户端与 UDP\n\n```wcs\nSOCK sc                                    // client socket\nENVI @sc.sock=&&err\nENVI @sc.connect=&&err;%&TOIP%;%&TOPORT%   // connect\nENVI @sc.write=&&err;&Len;&MSG             // send data\nENVI @sc.read=&&err;&Len;&recvBuf          // receive\nENVI @sc.shutdown=                         // graceful shutdown\nENVI @sc.close=                            // close\n\n// UDP\nSOCK su;;%&SOCK_DGRAM%;%&IPPROTO_UDP%     // UDP socket\nENVI @su.write=&&err;&Len;&data;;;&destIP  // sendto\nENVI @su.read=&&err;&Len;&recvBuf;;;&srcIP // recvfrom\n```\n\n### 共享内存与命名管道\n\n```wcs\nSOCK --shm shm1;w;MySharedMem;1024         // writable shared memory\nENVI @shm1.mem=&&addr                      // get memory address\n\nSOCK --pipe pip1;MyPipe;5000;4096;0x1      // named pipe, immediate connect\nENVI @pip1.write=;;&data                   // write\nENVI @pip1.read=;;&buf                     // read\n```\n\n---\n\n## 66. COM/WMI 对象自动化\n\n### 通过 CoCreateInstance 创建 COM 对象\n\n```wcs\nLOCK .com**                                // initialize COM\nSOCK --unknown &&pObj                      // IUnknown pointer (auto-release)\n\nSET$# &CLSID=*16 0\nSET$# &IID=*16 0\nCODE *,%&CLSID_HEX%,*HEX,&CLSID\nCODE *,%&IID_HEX%,*HEX,&IID\n\nCALL $--qd --16 OLE32.DLL,CoCreateInstance,*&CLSID,#0,#1,*&IID,*&pObj\n\n// Call vtable method (index 3)\nCALL $--16 --ret:&&hr #,*&pObj.%&iMethod%,arg1,arg2\n```\n\n### WMI 查询模式\n\n```wcs\nLOCK .com**\nSOCK --unknown &&pLoc                       // IWbemLocator\nSOCK --unknown &&pSvc                       // IWbemServices\n\nCALL $--qd --16 OLE32.DLL,CoCreateInstance,*&CLSID_WbemLocator,#0,#1,*&IID_IWbemLocator,*&pLoc\n\nCALL $--16 --qd #,*&pLoc.%&iConnectServer%,$ROOT\\CIMV2,#0,#0,#0,#0,#0,#0,*&pSvc\n\nCALL $--16 --ret:&&hr --qd #,*&pSvc.%&iExecQuery%,$WQL,*&wqlCmd,#0x30,#0,*&pEnum\n\nSOCK --BSTR &&bstrProp,,PropertyName\nSOCK --unknown &&pRow\nCALL $--16 --qd #,*&pEnum.%&iNext%,#0xFFFFFFFF,#1,*&pRow,*&count\nSET$# &vProp=*24 0\nCALL $--16 --ret:&&hr --qd #,*&pRow.%&iGet%,#%&bstrProp?ptr%,#0,*&vProp,#0,#0\nSET &value=%&vProp?ptr:8\n```\n\n### ITaskbarList3（任务栏进度条）\n\n```wcs\nSOCK --unknown &&pTaskbar\nCALL $--qd --16 --ret:&&hr OLE32.DLL,CoCreateInstance,*&CLSID_TaskbarList,#0,#1,*&IID_ITaskbarList3,*&pTaskbar\nCALL $--ret:&&r #,*&pTaskbar.%&iHrInit%\nCALL $--ret:&&r --qd# #,*&pTaskbar.%&iSetValue%,%&hwnd%,0,%&total%\nCALL $--ret:&&r #,*&pTaskbar.%&iRelease%\n```\n\n---\n\n### 45. GetIfTable — 网络速率监控\n\n```wcs\nENVI$ &&buf=*0x1000 0\nSET$# &&dwSize=*4 0\nCALL $--qd --ret:&&bret Iphlpapi.dll,GetIfTable,*&buf,*&dwSize,#0\n// If GetLastError==122 (ERROR_INSUFFICIENT_BUFFER), re-allocate with returned size\nENVI-addr ;&&bufsize=&&buf\n// MIB_IFENTRY: 860 bytes per entry, name at offset 0, dwInOctets at offset 344, dwOutOctets at offset 356\n// Filter: skip dwType==24 (loopback), keep dwOperStatus==5 (operational)\n// Delta: save previous values, subtract for speed\n// CalcSize helper: B→KB→MB→GB→TB→PB→EB→ZB\n```\n\n---\n\n### 48. WiFi 连接 + 托盘 UI 模式\n\nCombined ADSL-wlan + TABL + minimize-to-tray typical pattern:\n\n```wcs\n// Scan WiFi networks\nADSL-wlan ,,scan,&&result\n// result format: one per line, TAB-delimited fields\n// Parse into TABL for display\nTABL TABL1,L10T10W400H200,SSID:150 Signal:60 Flags:80 Type:60\nFORX *NL &result,&&line,\n{   MSTR &&ssid,&&signal,&&flags,&&type=<1><2><3><4>%&line%\n    ENVI @TABL1.ADD=%&ssid%;%&signal%;%&flags%;%&type%\n}\n\n// Connect to selected SSID\nADSL-wlan %&ssid%,%&password%,,\n\n// Minimize to tray\n_SUB OnClose\n    ENVI @@Visible=::0        // hide window\n    // Show tray icon with notification\n_END\n```\n\n---\n\nFile v1.7.1:references/how-tos/storage.md\n\n# 磁盘/分区/文件/注册表/设备 — 写法示例\n\n> **版本兼容性：** 部分示例使用 DLL 调用（`CALL $--qd`）。DLL 调用需要 PECMD2012 v1.88+ 完整版支持（32-bit 和 64-bit 行为一致）。\n> 如果 DLL 调用不工作，可使用 `PART`、`FDRV`、`REGI`、`EXEC*` 等内置命令替代。\n\n## 1. 磁盘枚举与信息\n\n### 列出所有物理磁盘及详细信息\n\n```wcs\nPART list disk,&&全部磁盘\nFORX * %&全部磁盘%,&&磁盘,\n{\n    PART list disk %&磁盘%,&&磁盘信息\n    MSTR &&sz,&&bus,&&mbr,&&sign=<2><7><8><9>%&磁盘信息% // ⚠ 字段索引因 PART 输出格式而异\n    MESS Disk#%&磁盘%: Size=%&sz% bytes, Bus=%&bus%, Type=%&mbr%\n}\n```\n\n### 列出磁盘所有分区（兼容 GPT + MBR）\n\n```wcs\nSET &dsk=0    // 0 = first disk\n// Step 1: get partition numbers (plain list)\nPART list part %&dsk%,&&全部分区\n// Step 2: iterate and get detailed info per partition\nFORX * %&全部分区%,&&pt,\n{\n    FIND $%&pt%=0, EXIT -                         // skip partition 0 (SD card issue)\n    PART -hextp -phy# list part %&dsk%#%&pt%,&&分区信息\n    MSTR &&tp,&&start,&&len,&&attr,&&drv=<2><4><5><7><9>%&分区信息%\n    // For GPT: MSTR has different field layout\n    // MSTR &&guid,&&attr,&&start,&&len,&&nr=<2><3><4><5><8>%&分区信息%\n    CALC &&lenGB=%&len%/1G#1\n    IFEX $%&lenGB%G<1G, TEAM CALC &&lenMB=%&len%/1M#1| SET lenDisplay=%&lenMB%M! SET lenDisplay=%&lenGB%G\n    MESS Part#%&pt%: Type=%&tp%, Size=%&lenDisplay%, Drv=%&drv%\n}\n```\n\n### 盘符与磁盘号对应关系\n\n```wcs\nFDRV &Drvs=*:\nFORX * %&Drvs%,&&D,\n{\n    PART list drv %&D%,&&V\n    MSTR &&hd=<9>%&V%\n    ^SET &Drv[%&hd%]=%%&Drv[%&hd%]%%%%&D%      // append with delayed expansion\n}\n// &Drv[0], &Drv[1], etc. now hold concatenated drive letters per disk\n```\n\n### 获取卷标和文件系统（带自动挂载回退）\n\n```wcs\n_SUB GetVol\n    TEAM ENVI %1=| ENVI %2=| ENVI &&v=| ENVI &&b=0| ENVI &&VL=%~3| ENVI &&dsk=%~4| ENVI &&pt=%~5\n    SET &r1=\n    SET &r2=\n    FIND $X=X%&VL%,! FDRV *vol r1,r2=%&VL%      // vol exists: direct query\n    FIND $X=X%&VL%,                               // vol doesn't exist: auto-assign letter\n    { LOCK #pecmd\n        SET b=1\n        FDRV *idle *rsort &&VL=*:\n        LSTR VL=2,%&VL%\n        SHOW & %&dsk%#%&pt%,%&VL%                // assign temp letter\n        FDRV *vol r1,r2=%&VL%                     // query\n        SHOW & ,%&VL%                              // release letter\n    }\n    ENVI-ret %1=%&r1%\n    ENVI-ret %2=%&r2%\n_END\n```\n\n---\n\n## 2. 通过 Win32 API 枚举设备\n\n### 通过 SetupAPI 枚举物理磁盘\n\n```wcs\n// Canonical method: CLSIDFromString produces binary GUID\nSET &GUID_STR={53f56307-b6bf-11d0-94f2-00a0c91efb8b}\nSET$# &guid=*16 0\nCALL $--qd --ret:&&r ole32.dll,CLSIDFromString,${%&GUID_STR%},*&guid\n// Alternative: construct GUID from hex bytes\nSET &GUID_HEX=53 f5 63 07 b6 bf 11 d0 94 f2 00 a0 c9 1e fb 8b\nCODE *,%&GUID_HEX%,*HEX,&guid\nCALL $--qd --ret:&&hSetup Setupapi.dll,SetupDiGetClassDevsW,*&guid,#0,#0,#0x12\nIFEX $%&hSetup%<>-1,\n{\n    SET &i=0\n    LOOP #1=1,\n    {\n        IFEX $%&::bX64%<3, SET &dataSz=28! SET &dataSz=32\n        SET$# &devData=*%&dataSz% 0\n        SET-long &devData=%&dataSz%:0\n        CALL $--qd --bool --ret:&&ok Setupapi.dll,SetupDiEnumDeviceInterfaces,#%&hSetup%,#0,*&guid,#%&i%,*&devData\n        IFEX $%&ok%<>1, EXIT LOOP\n        // ... get detail data, open device, send IOCTL ...\n        CALC &i=%&i% + 1\n    }\n    CALL $--qd --bool Setupapi.dll,SetupDiDestroyDeviceInfoList,#%&hSetup%\n}\n```\n\n### 获取磁盘性能计数器（IOCTL_DISK_PERFORMANCE）\n\n```wcs\nSET &disk=\\\\.\\PhysicalDrive0\nCALC &&access=0x80000000 | 0x40000000\nCALC &&share=0x00000001 | 0x00000002\nCALL $--qd --ret:&&h Kernel32.dll,CreateFileW,$%&disk%,#%&access%,#%&share%,#0,#3,#0,#0\nIFEX $%&h%<>-1,\n{\n    SET &ioctl=0x70020\n    SET$# &buf=*0x58 0\n    SET$# &retSz=*8 0\n    CALL $--qd --ret:&&r Kernel32.dll,DeviceIoControl,#%&h%,#%&ioctl%,#0,#0,*&buf,#0x58,*&retSz,#0\n    SET?longlong &buf=&&bytesRead:0\n    SET?longlong &buf=&&bytesWritten:8\n    CALL $--qd --bool Kernel32.dll,CloseHandle,#%&h%\n}\n```\n\n---\n\n## 4. 文件与配置操作\n\n### 读取整个文件（文本 / 二进制）\n\n```wcs\nREAD C:\\config.ini,**,&content      // ** = DOS CRLF -> native, *r = raw, * = LF only\nGETF# C:\\data.bin,0#*,&raw          // binary read\n```\n\n### 解析 INI 风格配置文件到变量\n\n```wcs\nREAD %CurDir%\\config.ini,*,&cfg\nFORX *NL &cfg,&&line,\n{\n    SED &&key=1,=.*,,%&line%\n    SED &&val=1,.*=,,%&line%\n    FIND $=%&key%,! SET %&key%=%&val%         // skip empty key lines\n    // Alternative idiom (canonical in 代码大全 source):\n    // FIND *<>var,...  = \"var is NOT empty\"  (execute if var has content)\n    // FIND *=var,...   = \"var IS empty\"      (execute if var is blank)\n}\n```\n\n### 写入文件\n\n```wcs\nWRIT C:\\output.txt,1,First line           // 1 = 替换第1行\nWRIT C:\\output.txt,+0,Second line        // +0 = 在末尾追加新行\nWRIT C:\\output.txt,$0,a=%var%            // $ = 展开环境变量，0 = 替换最后一行\nPUTF -dd -len=0 C:\\file.bin,0,zero        // create/truncate\nPUTF C:\\file.bin,%offset%,#%&data%        // write at offset\n```\n\n### 获取文件时间戳和大小\n\n```wcs\nSIZE &&sz=C:\\file.txt\nMESS Size: %&sz% bytes\n```\n\n---\n\n## 5. 注册表操作\n\n### 读/写（所有类型）\n\n```wcs\n// Read\nREGI $HKLM\\SOFTWARE\\App\\Version,&str        // REG_SZ\nREGI #HKLM\\SOFTWARE\\App\\Count,&num           // REG_DWORD\nREGI @HKLM\\SOFTWARE\\App\\Binary,&data         // REG_BINARY\nREGI ~HKLM\\SOFTWARE\\App\\Path,&expand         // REG_EXPAND_SZ\nREGI +HKLM\\SOFTWARE\\App\\Big,&qword           // REG_QWORD\nREGI .HKLM\\SOFTWARE\\App\\OfflineKey,&val      // offline hive (PE mounted Windows)\n\n// Write\nREGI $HKLM\\SOFTWARE\\App\\Version=1.2.3\nREGI #HKLM\\SOFTWARE\\App\\Count=#0x100         // hex DWORD\n\n// Delete\nREGI $HKLM\\SOFTWARE\\App\\OldKey=              // empty = delete\n\n// Enumerate\nREGI --ak HKCU\\Software\\,&&keys              // enumerate subkeys (--ak)\nREGI --av HKCU\\Software\\MyApp\\,&vals         // enumerate all values (--av)\n```\n\n---\n\n## 20. PART 操作（完整工具包模式）\n\n```wcs\n// Change partition type\nPART -super -up -xup %&dsk%#%&pt% %&newType%\n\n// Toggle active flag\nFIND $%&ac%=1, SET a=-a! SET a=a\nPART -super -up %&dsk%#%&pt% %&a%\n\n// Toggle hide (bit 4)\nCALC -base=16 #&ntp=%&tp% @ 0x10                   // XOR with 0x10 to toggle\n\n// Delete partition (with safety)\nMESS 确定要删除该分区吗？@删除分区#YN*8000$N\nFIND $%&YESNO%<>YES, EXIT _SUB\nSHOW *- %&dsk%#%&pt%,                               // unload first (3 times for safety)\nSHOW *- %&dsk%#%&pt%,\nPART -super -up del %&dsk%#%&pt%\n\n// Swap physical partition numbers\nPART -up -hup -swap:%&v1% %&dsk%#%&v2%\n```\n\n---\n\n## 24. 跨盘符目录搜索（FORX @）\n\n```wcs\nFORX @\\Windows,&&winDir,1,                          // search ALL drives for \\Windows\n{\n    MSTR &&drive=1,2,%&winDir%                       // extract drive letter\n    IFEX %&winDir%\\System32\\config\\SOFTWARE,\n    {\n        MESS Found Windows on %&drive%: %&winDir%\n    }\n}\n// @\\DirName iterates ALL root drives looking for DirName\n// The 3rd param 1 returns the FIRST match only (vs 0 = all)\n```\n\n---\n\n## 25. 离线注册表（完整增删改查）\n\nPE 系统部署的关键技术。使用完整的 offreg.dll API 对离线 Windows 注册表配置单元进行创建/读取/写入/枚举操作。\n\n```wcs\n// --- Open offline hive ---\nSET &hHive=\nCALL $--qd --ret:&&ret offreg.dll,OROpenHive,$%&HiveFile%,*&hHive\nIFEX $%&ret%<>0, TEAM MESS Failed to open hive@错误#OK| EXIT\n\n// Alternative: ORLoadHive (loads with NT version context)\nCALL $--qd --ret:&bret offreg.dll,ORLoadHive,$%&hivepath%,*&hHive\n\n// --- Open or create key ---\nSET &hKey=\nCALL $--qd --ret:&&ret offreg.dll,OROpenKey,#%&hHive%,$%&SubKey%,*&hKey\nIFEX #%&ret%<>0,\n{\n    CALL $--qd --ret:&&ret offreg.dll,ORCreateKey,#%&hHive%,$%&SubKey%,#0,$,#0,*&hKey,#0\n}\n\n// --- Read REG_SZ (type 1, two-call buffer) ---\nSET$# &pdwType=*4 0\nSET$# &pcbData=*%&PtrSz% 0\nSET-long &pcbData=8192:0\nCALL $--qd --ret:&&ret offreg.dll,ORGetValue,#%&hKey%,#0,#0,$%&Value%,#1,#0,*&pcbData\nSET?int &pcbData=&&cbData:0\nSET$# &Data=*%&cbData% 0\nCALL $--qd --ret:&&ret offreg.dll,ORGetValue,#%&hKey%,#0,#0,$%&Value%,#1,*&Data,*&pcbData\n\n// --- Read REG_DWORD (type 4) ---\nSET$# &dwData=*4 0\nSET$# &lpcbData=*4 4\nCALL $--qd --ret:&bret offreg.dll,ORGetValue,#%&hKey%,#0,#0,$%&Value%,#4,*&dwData,*&lpcbData\nSET?int &dwData=&&dwVal:0\n\n// --- Read REG_QWORD (type 11) ---\nSET$# &qwData=*8 0\nSET$# &lpcbData=*8 8\nCALL $--qd --ret:&bret offreg.dll,ORGetValue,#%&hKey%,#0,#0,$%&Value%,#11,*&qwData,*&lpcbData\nSET?longlong &qwData=&&qwVal:0\n\n// --- Write value ---\nCALL $--qd --ret:&&ret offreg.dll,ORSetValue,#%&hKey%,$%&Value%,#1,*&Data,#%&DataSize%\n\n// --- Enumerate subkeys ---\nSET$# &keyCount=*4 0\nSET$# &maxSubKeyLen=*4 0\nSET$# &valCount=*4 0\nCALL $--qd --ret:&&ret offreg.dll,ORQueryInfoKey,#%&hKey%,#0,#0,*&keyCount,*&maxSubKeyLen,#0,*&valCount,#0,#0,#0,#0\nSET?int &keyCount=&&nKeys:0\nSET?int &maxSubKeyLen=&&maxLen:0\nCALC &nameBufSz=%&maxLen%*2+2\nSET$# &lpName=*%&nameBufSz% 0\nSET$# &lpcchName=*4 0\nSET &i=0\nLOOP #%&i%<%&nKeys%,\n{\n    SET-long &lpcchName=%&nameBufSz%:0\n    CALL $--qd --ret:&&ret offreg.dll,OREnumKey,#%&hKey%,#%&i%,*&lpName,*&lpcchName,#0,#0,#0\n    SET-make &&subName=&lpName;0\n    CALC &i=%&i%+1\n}\n\n// --- Enumerate values ---\nCALL $--qd --ret:&&ret offreg.dll,ORQueryInfoKey,#%&hKey%,#0,#0,#0,#0,#0,*&valCount,#0,#0,#0,#0\nSET?int &valCount=&&nVals:0\n\n// --- Save and close ---\nCALL $--qd --ret:&&ret offreg.dll,ORSaveHive,#%&hHive%,$%&HiveFile%,$0,$0\nCALL $--qd offreg.dll,ORCloseKey,#%&hKey%\nCALL $--qd offreg.dll,ORCloseHive,#%&hHive%\n```\n\n---\n\n## 27. BROW — 文件/目录浏览对话框\n\n```wcs\nBROW &saveFile,&%Desktop%\\output.iso,Save ISO file,iso           // save dialog\nBROW &openFile,,Select a file,INI|*.INI|All Files|*.*|           // open dialog with filter\nBROW &folder,*C:\\,Select a folder                                // folder browser (* prefix)\n// Additional flags: 0x10=edit box; 0x200=multi-select(文件对话框) / 无新建文件夹按钮(目录对话框)\n```\n\n---\n\n## 28. SUBJ — 挂载/卸载盘符\n\n```wcs\nSUBJ -X:                                            // remove drive letter X:\nSUBJ G:,\\Device\\HarddiskVolume3                     // mount volume as G:\n```\n\n---\n\n### 40. EFI 启动项管理（FVAR UEFI NVRAM）\n\n```wcs\n// Read EFI firmware variable\nENVI ?&var=FVAR,Boot0000;{8be4df61-93ca-11d2-aa0d-00e098032b8c}\n\n// Write EFI firmware variable\nENVI ?-v =FVAR+,BootXXXX,&&buf   // create/modify boot entry\n\n// Get buffer byte length\nENVI-addr ;&len=&&buf\n\n// Create view into buffer at offset (FVAR data starts at offset)\nENVI-mkdummy &&view=&&buf@8\n\n// 16-bit WORD access for BootOrder entries\nSET?short &buf=&val:offset\n\n// Need SeSystemEnvironmentPrivilege to write\nCALL $--qd --ret:&bret ntdll.dll,RtlAdjustPrivilege,#22,#1,#0,&&pEnabled\n\n// Boot entry ID naming: Boot%IDXX% where IDXX = BootID + 0x100000\n// Clean empty IDs, compact BootOrder array\n```\n\n---\n\n### 41. SSD 检测（寻道惩罚查询）\n\nIOCTL 计算公式：`CALC &ioctl = shl(0x2D,16) | shl(0,14) | shl(0x09,2) | 0` → 0x2D1400\n\n```wcs\nSET &STORAGE_PROPERTY_QUERY_Unknown=0\nSET &StorageDeviceSeekPenaltyProperty=7\nSET &STORAGE_PROPERTY_QUERY.INPUT=12  // PropertyId(4)+QueryType(4)+AdditionalParams(4)\nENVI$ &&input=*0xC 0\nSET-long &&input=7:0       // PropertyId=7 (SeekPenalty)\nSET-long &&input=0:4       // QueryType=0 (Standard)\nSET-long &&input=0:8       // AdditionalParams=0\nSET &output.SIZE=12         // DEVICE_SEEK_PENALTY_DESCRIPTOR: Version(4)+Size(4)+IncursSeekPenalty(1)+3pad\nENVI$ &&output=*0xC 0\nSET$# &&dwSize=*4 0\nCALL $--qd --ret:&bret kernel32.dll,DeviceIoControl,%&hdisk%,#0x2D1400,*&input,#0xC,*&output,#0xC,*&dwSize,#0\nSET?int &&output=&&IncursSeekPenalty:8\n// 0=SSD (no seek penalty), 1=HDD\n```\n\n---\n\n\n### 42. TRIM 支持检测\n\n相同的 IOCTL 0x2D1400，PropertyId=8（StorageDeviceTrimProperty）。\n\n```wcs\nSET &StorageDeviceTrimProperty=8\nSET-long &&input=8:0       // PropertyId=8\nSET-long &&input=0:4       // QueryType\nSET-long &&input=0:8       // AdditionalParams\nCALL $--qd --ret:&bret kernel32.dll,DeviceIoControl,%&hdisk%,#0x2D1400,*&input,#0xC,*&output,#0x20,*&dwSize,#0\n// DEVICE_TRIM_DESCRIPTOR: Version(4)+Size(4)+TrimEnabled(1)\nSET?int &&output=&&TrimEnabled:8\n```\n\n---\n\n### 43. STORAGE_GET_DEVICE_NUMBER（路径 → 磁盘/分区映射）\n\n```wcs\nCALC &IOCTL_STORAGE_GET_DEVICE_NUMBER = shl(0x2D,16) | shl(0,14) | shl(0x0420,2) | 0\n// 0x2D1080\nSET &STORAGE_DEVICE_NUMBER.SIZE=12  // DeviceType(4)+DeviceNumber(4)+PartitionNumber(4)\nENVI$ &&output=*0xC 0\nSET$# &&dwSize=*4 0\nCALL $--qd --ret:&bret kernel32.dll,DeviceIoControl,%&hdisk%,#%&IOCTL_STORAGE_GET_DEVICE_NUMBER%,#0,#0,*&output,#0xC,*&dwSize,#0\nSET?long &&output=&&DeviceType:0\nSET?long &&output=&&DeviceNumber:4\nSET?long &&output=&&PartitionNumber:8\n```\n\n通过设备路径打开：`\\\\.\\C:` → 返回分区信息。通过 `\\\\.\\PhysicalDrive0` 打开 → 返回磁盘信息（PartitionNumber=0）。\n\n---\n\n\n### 44. Drive Layout Information EX（完整磁盘布局）\n\n```wcs\nCALC &IOCTL_DISK_GET_DRIVE_LAYOUT_EX = shl(0x07,16) | shl(0,14) | shl(0x14,2) | 0  // 0x70050\nSET &outBufSz=0x1000                               // 4096 bytes (足够容纳布局+分区表)\nENVI$ &&output=*8M 0\nSET$# &&dwSize=*4 0\nCALL $--qd --ret:&bret kernel32.dll,DeviceIoControl,%&hdisk%,#%&IOCTL_DISK_GET_DRIVE_LAYOUT_EX%,#0,#0,*&output,#%&outBufSz%,*&dwSize,#0\n\n// MBR:  PartitionStyle=0, Header at offset 48: Signature(4)+CheckSum(4)\n// GPT:  PartitionStyle=1, Header at offset 48: DiskId(16)+StartingUsableOffset(8)+UsableLength(8)+MaxPartitionCount(4)\n// Then partition entries at offset 112, each 120 bytes (PARTITION_INFORMATION_EX)\n```\n\n完整 MBR 类型表（26 项）：0x00=空→0xEF=EFI 系统分区，包含 0x07=NTFS、0x0B/0x0C=FAT32、0x0E/0x0F=EFI FAT、0x27=Windows RE\n\n完整 GPT 类型 GUID 表（23 项）：包含 EBD0A0A2（MS 基本数据）、C12A7328（EFI 系统）、E3C9E316（MSR）、DE94BBA4（恢复）\n\n---\n\n\n### 47. SITE fattr — 文件属性位掩码解码\n\n```wcs\nSITE ?,,,,var=fattr,\"C:\\Windows\\notepad.exe\"\nCALC &isReadOnly=%&var% & 0x1\nCALC &isHidden=%&var% & 0x2\nCALC &isSystem=%&var% & 0x4\nCALC &isArchive=%&var% & 0x20\nCALC &isCompressed=%&var% & 0x800\n// FILE_ATTRIBUTE_ constants: 0x1=READONLY, 0x2=HIDDEN, 0x4=SYSTEM,\n//   0x10=DIRECTORY, 0x20=ARCHIVE, 0x80=NORMAL, 0x100=TEMPORARY,\n//   0x200=SPARSE, 0x400=REPARSE, 0x800=COMPRESSED, 0x1000=OFFLINE,\n//   0x2000=NOT_CONTENT_INDEXED, 0x4000=ENCRYPTED, 0x8000=INTEGRITY_STREAM,\n//   0x10000=VIRTUAL, 0x20000=NO_SCRUB_DATA, 0x40000=EA, 0x80000=PINNED,\n//   0x100000=UNPINNED, 0x80000000=DEVICE\n```\n\n---\n\n\n### 56. 通用 IOCTL 代码构造\n\n任意 IOCTL 控制码的通用计算公式：\n```\nIOCTL = shl(DeviceType, 16) | shl(Access, 14) | shl(Function, 2) | Method\n```\n其中：\n- DeviceType：FILE_DEVICE_ 前缀值（例如存储设备为 0x2D）\n- Access：FILE_READ_ACCESS=0、FILE_WRITE_ACCESS=1、FILE_ANY_ACCESS=0\n- Function：操作专用编号\n- Method：METHOD_BUFFERED=0、METHOD_IN_DIRECT=1、METHOD_OUT_DIRECT=2、METHOD_NEITHER=3\n\n| IOCTL Constant | DeviceType | Access | Function | Method | Result |\n|---|---|---|---|---|---|\n| IOCTL_STORAGE_QUERY_PROPERTY | 0x2D | 0 | 0x0500 | 0 | 0x2D1400 |\n| IOCTL_DISK_GET_DRIVE_GEOMETRY_EX | 0x07 | 0 | 0x28 | 0 | 0x700A0 |\n| IOCTL_DISK_GET_DRIVE_LAYOUT_EX | 0x07 | 0 | 0x14 | 0 | 0x70050 |\n| IOCTL_DISK_GET_PARTITION_INFO_EX | 0x07 | 0 | 0x12 | 0 | 0x70048 |\n| IOCTL_STORAGE_GET_DEVICE_NUMBER | 0x2D | 0 | 0x0420 | 0 | 0x2D1080 |\n| IOCTL_DISK_PERFORMANCE | 0x07 | 0 | 0x08 | 0 | 0x70020 |\n| IOCTL_DISK_UPDATE_PROPERTIES | 0x07 | 0 | 0x40 | 0 | 0x70100 |\n\n---\n\n## 74. 注册表 键/值/数据 存在性检查\n\n```wcs\n// Check if KEY exists:\nREGI ?HKCU\\Software\\MicrosoftXxX\\,&&VT\nFIND $%&VT%=ERROR, MESS KEY does not exist!  MESS KEY exists\n\n// Check if VALUE exists (key must exist):\nREGI ?HKCU\\Software\\Microsoft\\ABC,&&VT\nFIND $%&VT%=ERROR, MESS Value does not exist!  MESS Value exists\n\n// Check if DATA exists:\nREGI ?HKCU\\Software\\Microsoft\\,&&VT\nFIND $%&VT%=ERROR,! { MESS KEY does not exist }\nFIND $%&VT%<>ERROR,\n{\n    FIND $%&VT%=NI, MESS DATA does not exist!  MESS DATA exists\n}\n```\n\n---\n\n## 75. 文件与目录检测\n\n```wcs\nFDIR --fullfile &&F=%&NAME1%\nIFEX %&F%,   SET &bfile=1                           // file or directory exists\nIFEX %&F%\\,  SET &bfile=0                           // trailing slash = it's a directory\nFIND *=NAME1, SET &bfile=0                           // empty input check\n```\n\n---\n\nFile v1.7.1:references/how-tos/system.md\n\n# 进程/线程/系统信息/工具 — 写法示例\n\n> **版本兼容性：** 以下示例使用 DLL 调用（`CALL $--qd`）获取系统信息。DLL 调用需要 PECMD2012 v1.88+ 完整版支持（32-bit 和 64-bit 行为一致）。\n> 如果 DLL 调用返回空，说明当前版本不支持，可使用 `REGI`、`EXEC*`、`FIND --pid*@` 等内置命令替代。\n\n## 3. 启动环境与系统信息\n\n### 检测 BIOS 与 UEFI\n\n```wcs\n_SUB GetBootEnv\n    SET$# &buf=*16 0 *4 0 *8 0\n    CALL $--qd --ret:&&r ntdll.dll,NtQuerySystemInformation,#90,*&buf,#32,#0\n    IFEX #%&r%<>0, TEAM ENVI-ret %~1=Unknown| EXIT _SUB\n    SET?int &buf=&&type:16\n    IFEX #%&type%=1, ENVI-ret %~1=BIOS\n    IFEX #%&type%=2, ENVI-ret %~1=UEFI\n_END\n```\n\n### 检测 Secure Boot 状态\n\n```wcs\nSET$ &SSBI=*2 0\nCALL $--qd --ret:&&r ntdll.dll,NtQuerySystemInformation,#145,*&SSBI,#2,#0\nSET?char &SSBI=&&enabled:0\nIFEX #%&enabled%=0,MESS Secure Boot: Disabled! MESS Secure Boot: Enabled\n```\n\n### 获取 Windows 版本（RtlGetVersion）\n\n```wcs\nSET$# &verBuf=*4 0 *4 0 *4 0 *4 0 *4 0 *256 0\nSET-long &verBuf=276:0\nCALL $--qd --ret:&&r ntdll.dll,RtlGetVersion,*&verBuf\nSET?int &verBuf=&&major:4\nSET?int &verBuf=&&minor:8\nSET?int &verBuf=&&build:12\nSET-make &&sp=&verBuf@16;256\nMESS Windows %&major%.%&minor% build %&build%\n```\n\n### 检测是否在 WinPE 中运行\n\n```wcs\nENVI ?WinPE=&&isPE\nIFEX #%&isPE%>0, MESS Running in WinPE! MESS Normal Windows\n```\n\n### 获取文件版本\n\n```wcs\nENVI ?FVER &&ver,%SystemRoot%\\System32\\shell32.dll\nMESS Shell32 version: %&ver%\n```\n\n---\n\n## 6. 进程与程序执行\n\n### 运行并捕获输出\n\n```wcs\nEXEC* &output=!cmd.exe /c dir C:\\ /b\nSET &count=0\nFORX *NL &output,&&line, CALC &count=%&count%+1\nMESS %&count% lines:%&NL%%&output%\n```\n\n### 带实时输出回调的执行\n\n```wcs\nEXEC* -cmd:::OnLine -err+ &output=!\"%program%\" %args%\n\n_SUB OnLine\n    READ -,0,&output,%&output%              // read captured content so far\n    SED &&pct=1,\\(.*\\),,%&output%                    // remove parenthesized content (e.g. \"50%\")\n    MSTR &&w1,&&w2=<1><2>%&output%\n    ENVI @ProgressBar=%&w2% %&pct%          // update GUI\n_END\n```\n\n### 运行子 PECMD 并等待\n\n```wcs\nEXEC =!\"%MyNAME%\" TEAM WAIT 1000|LOAD other.ini\nENVI ?WinPE=&&isPE\nEXEC* &&ver=*PECMD                              // * prefix = capture stdout to variable\n```\n\n### 终止进程\n\n```wcs\nKILL process.exe            // by name\nKILL *12345                 // by PID\nKILL \\                      // kill current script's windows\nKILL \\WindowName            // kill specific window\n```\n\n---\n\n## 8. 线程与异步\n\n### 通过 POSTMSG 更新 UI 的后台线程\n\n```wcs\nENVI @MainWindow.MSG=#1: CALL OnThreadDone         // register custom message handler\nTHREAD* CALL LongTask\nMESS This runs immediately, without waiting@多线程#OK\n\n_SUB LongTask\n    SET &result=\n    FORX /S C:\\*.dll,&&f,0, SET< result=%&f%\n    ENVI @MainWindow.POSTMSG=#1                    // notify main thread when done\n_END\n```\n\n### 线程协调共享标志\n\n```wcs\nSET &::bWork=1\nTHREAD* CALL Worker\nWAIT 5000\nSET &::bWork=0                                      // signal thread to stop\n\n_SUB Worker\n    LOOP #%&::bWork%=1,\n    {\n        // do work...\n        WAIT 100\n    }\n_END\n```\n\n### 多工作线程 + 完成检查\n\n```wcs\nSET &::task1Done=0\nSET &::task2Done=0\nTHREAD* CALL Task1\nTHREAD* CALL Task2\n\n_SUB CheckDone\n    FIND $%&::task1Done%%&::task2Done%=11, MESS Both tasks completed!\n_END\n```\n\n---\n\n## 9. 单实例 / 互斥体模式\n\n```wcs\n_SUB CheckSingle *\n    { LOCK #pecmd                                   // atomic scope\n        LOCK --exist #MyApp_UniqueName,&&exists\n        REGI $HKCU\\Software\\MyApp\\WID,&&wid\n    }\n    IFEX $1=%&exists%,\n    {\n        IFEX $%&wid%>0,\n        {\n            ENVI @@Visible=%&wid%:2                 // restore window\n            ENVI @@POS=%&wid%:::::::1               // bring to foreground\n        }\n        EXIT FILE\n    }\n    LOCK #MyApp_UniqueName,&&ret\n_END\n\n// On window creation, save window ID:\n{ LOCK #pecmd\n    REGI $HKCU\\Software\\MyApp\\WID=%&__WinID%\n}\n\n// On exit, clean up:\n{ LOCK #pecmd\n    REGI $HKCU\\Software\\MyApp\\WID=\n}\n```\n\n---\n\n## 10. 热键注册\n\n```wcs\nHKEY Ctrl+Shift+#0x41, CALL OnHotkeyA            // Ctrl+Shift+A\nHKEY #0x0D, MESS Enter pressed                    // Enter (window scope)\nHKEY $#0x0D, MESS Enter pressed globally           // $ = system-wide\nHKEY Ctrl+Shift+#0x41,--del                       // unregister\n```\n\n---\n\n## 11. 字符串操作\n\n### MSTR — 字段与子串提取\n\n```wcs\nMSTR &&a,&&b=<1><3>%&data%                         // fields 1 and 3 (space-delimited)\nMSTR &&rest=<5->%&data%                             // fields 5 through end (`-` = to end)\nMSTR &&last=<-1>%&data%                             // last field (negative index)\nMSTR &&prefix=1,5,%&str%                           // chars 1-5\nMSTR &&suffix=6,0,%&str%                           // from position 6 to end\nMSTR -delims:. &&a,&&b,&&c,&&d=<1><2><3><4>%&ip%  // split by dot (IP: 192.168.1.1)\n```\n\n### SED — 正则替换\n\n```wcs\nSED &&r=0,pat,rep,%&source%                        // replace ALL occurrences\nSED &&r=1,find,replace,%&source%                   // replace FIRST only\nSED &&ext=-1,.*\\.,,%&filename%                      // get extension (from end)\nSED &&name=1,.*\\\\,,%&fullpath%                      // remove directory path\nSED &&clean=0,[^0-9], ,%&str%                       // remove all non-digits\nSED &&r=0:0,%&NL%,%&NL%ENVI ,%&source%             // transform newlines to commands (regex mode)\n```\n\n### LPOS / RPOS — 子串查找\n\n```wcs\nLPOS &&pos=needle,,%&haystack%                     // find first (case-insensitive)\nLPOS &&pos=needle,1,%&haystack%                    // ,1, flag (case sensitivity unconfirmed)\nRPOS &&pos=needle,,%&haystack%                     // find last\n```\n\n### RSTR — 取右边字符\n\n```wcs\nRSTR &&last3=3,%&str%                               // 从右边取3个字符: \"12345\" -> \"345\"\n```\n\n---\n\n## 12. 动态变量与数组\n\n### 间接解引用（伪数组）\n\n```wcs\nSET Arr.1.1=row1col1\nSET Arr.1.2=row1col2\nSET~ &&val=Arr.%&row%.%&col%                        // indirect read\n```\n\n### 延迟展开的动态变量名\n\n```wcs\nSET &hd=0\nSET &D=C:\n^SET &Drv[%&hd%]=%%&Drv[%&hd%]%%%%&D%             // append to Drv[0]\n// ^SET defers variable expansion: %% inside ^SET -> single % at execution time\n```\n\n### 动态代码执行\n\n```wcs\nSET$ &NA=0a\nREAD %CurDir%\\rules.ini,**,&A\nSED &&A=0:0,%&NA%,%&NA%ENVI ,{*ENVI %A%            // convert lines to ENVI commands\nSET< A=%&NL%}\n%&A%                                                // execute generated code block\n```\n\n---\n\n## 13. 定时器与调度模式\n\n```wcs\nTIME Timer1,1000, CALL OnTick                        // periodic timer\nTIME -t:1 Timer1,1000, CALL Once                     // one-shot\nENVI @Timer1=5000;3                                   // 5s interval, run 3 times only\nENVI @Timer1=0                                        // stop\nENVI @Timer1=-del                                     // destroy\n\n// Variable callback pattern\nSET &callback=CALL OnTimerA\nTIME Timer1,1000, %&callback%\n// ... later ...\nSET callback=CALL OnTimerB                            // switch handler on next tick\n```\n\n---\n\n## 14. 复合条件与流程控制\n\n### IFEX 复合条件\n\n```wcs\nIFEX [ %file% & %var%<> ], command                  // file exists AND var not empty\nIFEX [ %n%<=6 & %m%<6000 ], command                // numeric AND\nIFEX [ %a%<>%b% | %c%<>%d% ], command              // OR\n```\n\n### FIND 复合条件\n\n```wcs\nFIND [ $1=%&RET% & %WID%>0 ], command               // AND in FIND\n```\n\n### EXIT 变体\n\n```wcs\nEXIT LOOP       // break loop (同 EXIT BREAK)\nEXIT FORX       // break FORX (同 EXIT BREAK)\nEXIT CONTINUE   // continue to next iteration (LOOP/FORX)\nEXIT BLOCK      // jump to current {} block tail\nEXIT _SUB       // return from function\nEXIT FILE       // terminate entire script\nEXIT -          // same as EXIT BLOCK\n```\n\n---\n\n## 15. 加密与哈希\n\n```wcs\nBASE \"string\",&&encoded                     // PECMD custom base64 (for ADSL passwords)\nBASE* \"string\",&&encoded                    // standard base64\nBASE* -u \"%&encoded%\",&&decoded             // standard decode\nHASH C:\\file.exe,&&md5,MD5\nHASH $hello,&&sha1,SHA1\nHASH C:\\file.dat,&&crc,CRC32\nCMPS -m source.wcs,dest.wcz                 // compress\nCMPS -u source.wcz,dest.wcs                 // decompress\n```\n\n---\n\n## 17. 日期/时间\n\n```wcs\n// 默认格式: \"年-月-日|星期|时:分:秒\"（如 \"2025-1-15|3|14:30:0\"）\nDATE &&dateVar\nMSTR &&yr,&&mo,&&dy=<1><2><3>%&dateVar%            // 提取年、月、日\nMSTR &&hr,&&min,&&sec=<5><6><7>%&dateVar%          // 提取时、分、秒（<4>是星期）\n\n// -space 标志用空格分隔（更易解析）：\nDATE -space &&dateVarSp                             // \"2025 1 15 3 14 30 0\"\nMSTR &&yr,&&mo,&&dy=<1><2><3>%&dateVarSp%\n\n// 排序用字符串：\nSET &&dateSort=%&yr%%&mo%%&dy%%&hr%%&min%%&sec%\n```\n\n---\n\n## 18. 数学与计算\n\n```wcs\nCALC #&result=1000 * 2 + 300                        // integer math (#)\nCALC &result=3.14 * 2.5 #2                          // float, 2 decimal places\nCALC -base=16 #&hex=shl(0x07,16) | 0x20             // hex bitwise\nCALC &sz=%&bytes%/1G#3                              // bytes to GB, 3 decimal places\nCALC &&pct=100 - 100 * %&used% / %&total% ##1       // percentage, force decimals\n```\n\n---\n\n## 19. 跨进程窗口控制\n\n```wcs\n// From second instance, restore first instance:\nENVI @@Visible=%&windowID%:2                         // SW_RESTORE\nENVI @@POS=%&windowID%:::::::1                       // bring to foreground + activate\n\n// In Window, save its HWND:\nENVI @window.POS=?::&InitW:&InitH\n```\n\n---\n\n## 21. 资源嵌入与提取\n\n### 从 PECMD 资源加载嵌入脚本\n\n```wcs\nLOAD #102 arg1 arg2                                  // execute script at resource ID 102\nLOAD #103 /l zh-CN                                   // with language parameter\n```\n\n### 从 PECMD 资源执行嵌入二进制文件\n\n```wcs\nEXEC* --exe:#1003 &&out=*bcdboot64.exe %sysdir% /l %lang% /s %esp% /f uefi\nEXEC* --exe:#1005 =*MountESP64                       // wait for completion (=)\n```\n\n资源 ID 在构建时嵌入到 PECMD 可执行文件中。这是基于 PECMD 的工具打包依赖项的方式。\n\n\n### 图标和图像资源\n\n```wcs\nIMAG Btn,L0T0W64H64,#1000                           // display image from resource #1000\nTIPS* tooltip text,,,#1                              // use icon from resource #1\n```\n---\n\n## 22. 系统托盘图标（完整处理器）\n\n```wcs\n// Create tray icon\nTIPS* tooltip text,,,,shell32.dll#41                 // use system icon #41\nTIPS* tooltip text,,,#1                              // use icon #1 from EXE resources\n\n// Update tray icon dynamically\nTIPS* ,%&newStatus%,,,%&trayIconHandle%\nTIPS* ,%&newStatus%,,,-%&trayIconHandle%            // remove previous tip\nTIPS*                                                // remove tray icon entirely\n\n// WM_TRAYNOTIFY message handler for tray events\nENVI @this.MSG=_%&::WM_TRAYNOTIFY%::&&wp,&&lp, CALL OnTrayMenu %&wp% %&lp%\n```\n\nWM_TRAYNOTIFY message values:\n```wcs\nSET &::WM_TRAYNOTIFY=1109\nSET &::WM_LBUTTONDOWN=0x0201\nSET &::WM_RBUTTONDOWN=0x0204\n```\n\n\n### 完整托盘点击处理器（含可见性切换）\n\n```wcs\n_SUB OnTray\n    IFEX $%&::WM_LBUTTONDOWN%=%2, TEAM CALL OnSwitch| EXIT _SUB\n    IFEX $%&::WM_RBUTTONDOWN%=%2, CALL @--popmenu TrayMenu\n_END\n\n_SUB OnSwitch                                // toggle window visibility\n    ENVI @@Visible=?%&WID%:&&view\n    FIND |%&view%=0, ENVI @@Visible=%&WID%:1! ENVI @@Visible=%&WID%:0\n_END\n```\n---\n\n## 23. 系统电源与显示控制\n\n### 关机 / 重启 / 注销\n\n```wcs\nSHUT                        // shutdown (SHUTDOWN)\nSHUT R                      // reboot (RESTART)\nSHUT L                      // logoff\nSHUT S                      // standby (suspend)\nSHUT H                      // hibernate\nSHUT E                      // eject optical drive\nSHUT O                      // eject optical drive + wait 10s\nSHUT K                      // lock workstation\n```\n\n### 显示分辨率\n\n```wcs\nDISP W1920 H1080 B32 F60    // set 1920x1080, 32-bit color, 60Hz\nDISP W1024 H768 B16 F60     // set 1024x768, 16-bit color\nDISP                        // auto-detect best mode (no arguments)\n// After DISP, restart Explorer to refresh taskbar positioning:\nTEAM DISP| KILL explorer\n```\n\n### 屏幕尺寸\n\n```wcs\nSCRN &scrW,&scrH\nCALC &&rightEdge=%&scrW% - 300\n```\n\n### 查询任务栏高度\n\n```wcs\nFIND --class:Shell_TrayWnd --wid*@ &tbars\nFORX *NL &tbars,&&tb,\n{\n    MSTR* &tbtype=<7>%&tb%\n    FIND $%&tbtype%=Shell_TrayWnd,\n    {\n        MSTR* &tbWid=<2>%&tb%\n        ENVI @@POS=?%&tbWid%;;;;&TB_H\n    }\n}\nMESS Taskbar height: %&TB_H% px\n```\n\n---\n\n## 30. SEND / WAIT -cont — 键盘\n\n```wcs\nSEND VK_RETURN                                      // send Enter key\nSEND 0x11_,0x12_,0x2E,0x12^,0x11^                  // Ctrl+Alt+Del (press order)\nWAIT -cont -1000,&&key                              // wait up to 1s for key, returns VK code\n```\n\n---\n\n## 31. 多段颜色格式\n\nPECMD 支持 4 段颜色字符串，用于悬停感知控件：\n```\n文本色#背景色#悬停文本色#悬停背景色\n```\n\n```wcs\nLABE -center -vcenter Btn,L0T0W100H30,Refresh,CALL OnRefresh,0xffffff#0x0066CC#0xffffff#0x0088EE\n// Normal: white text on blue, Hover: white text on lighter blue\nENVI @Btn.color=0x000000#0xFFF0E0#0xFF0000#0xFFE0C0\n// Updates colors at runtime\n```\n\n---\n\n## 34. 参数验证守卫\n\n函数入口处的提前退出守卫模式。检查参数个数、非空值和格式有效性。\n\n```wcs\n_SUB SafeFunc\n    // --- Guard 1: argument count ---\n    FIND $%#<3, EXIT _SUB                            // need at least 3 args\n\n    // --- Guard 2: non-empty checks ---\n    FIND $X=X%~1, EXIT _SUB                           // arg1 empty\n    FIND $X=X%~2, EXIT _SUB                           // arg2 empty\n\n    // --- Guard 3: format validation (IP) ---\n    SET &ip=%~3\n    MSTR -delims:. &&a,&&b,&&c,&&d=<1><2><3><4>%&ip%\n    IFEX [ $%&a%<0 | $%&a%>255 | $%&b%<0 | $%&b%>255 | $%&c%<0 | $%&c%>255 | $%&d%<0 | $%&d%>255 ], EXIT _SUB\n    FIND $X=X%&a%, EXIT _SUB\n    FIND $X=X%&b%, EXIT _SUB\n\n    // --- Guard 4: numeric range ---\n    SET &port=%~4\n    SED &&cleanPort=0,[^0-9],,%&port%\n    FIND $0=%&cleanPort%, SET isNum=1\n    IFEX [ $%&isNum%=0 | $%&port%<1 | $%&port%>65535 ], EXIT _SUB\n\n    // --- Only now: do the actual work ---\n    MESS All valid! Processing %&ip%:%&port%@Info#OK\n_END\n\n// Top-level script guard\n_SUB MainGuard *\n    FIND $%~1=, TEAM MESS Usage: script.wcs <file> <option>@Error#OK| EXIT FILE\n    IFEX %~1,! TEAM MESS File not found: %~1@Error#OK| EXIT FILE\n\n    SET &opt=%~2\n    FIND $%&opt%=start, CALL OnStart %~1\n    FIND $%&opt%=stop, CALL OnStop %~1\n    FIND |%&opt%<>start & %&opt%<>stop, TEAM MESS Unknown option: %&opt%@Error#OK| EXIT FILE\n_END\n```\n\n`FIND $X=X%&var%` 是惯用的 PECMD \"为空\"测试：如果 `%&var%` 为空，左侧折叠为 `X=X` 与右侧 `X=X` 匹配（`X=` 后两者皆空），因此命令执行。\n\n---\n\n## 35. MSTR 字符串拆分 — 所有实用变体\n\n真实解析示例，涵盖末字段提取、第 N 字段、去空白拆分和自定义分隔符。\n\n```wcs\n// === Last segment (negative index) ===\n// Typical use: extract filename from path, IP from \"IPv4 ... x.x.x.x\"\nSET &line=   IPv4 Address. . . . . . . . : 192.168.1.100\nMSTR &&ip=<-1>%&line%                             // \"192.168.1.100\"\nMSTR &&ip=<1>%&ip%                                 // strip leading space → first field after trim\n\n// === N-th field and range ===\nSET &data=DISK 0 500107862016 GPT F6E0B 2048 976773127\nMSTR &&name,&&nr,&&sz=<1><2><3>%&data%              // \"DISK\" \"0\" \"500107862016\"\nMSTR &&rest=<4->%&data%                              // everything from field 4 onward (`-` = to end)\nMSTR &&mid=<3->%&data%                               // fields 3 through end\n\n// === Trimmed split (default whitespace strips leading blanks) ===\nSET &line=     Label:    BOOT      FS: NTFS\nMSTR &&label=<2>%&line%                              // \"BOOT\" (whitespace collapsed)\n\n// === Custom delimiter: IP address parsing ===\nSET &ip=192.168.1.100\nMSTR -delims:. &&a,&&b,&&c,&&d=<1><2><3><4>%&ip%    // \"192\" \"168\" \"1\" \"100\"\nMSTR -delims:. &&oct1,&&oct2,&&oct3=<1><2><3>%&ip%    // \"192\" \"168\" \"1\"\n\n// === Custom delimiter: PATH parsing ===\nSET &path=C:\\Windows\\System32\\drivers\\etc\\hosts\nMSTR -delims:\\ &&root,&&sub=<1><2>%&path%             // \"C:\" \"Windows\"\nMSTR -delims:\\ &&fil\n\nArchive v1.7.0: 12 files, 134156 bytes\n\nFiles: README.en.md (4738b), README.md (4635b), references/commands-full.md (93921b), references/how-tos/gui.md (31852b), references/how-tos/net.md (6065b), references/how-tos/storage.md (16594b), references/how-tos/system.md (33590b), references/pe-startup.md (11938b), references/pecmd-gui.md (75422b), references/troubleshooting.md (9864b), SKILL.md (34471b), _meta.json (132b)\n\nArchive v1.5.2: 12 files, 127085 bytes\n\nFiles: README.en.md (4738b), README.md (4635b), references/commands-full.md (88194b), references/how-tos/gui.md (24357b), references/how-tos/net.md (6065b), references/how-tos/storage.md (16594b), references/how-tos/system.md (33590b), references/pe-startup.md (11418b), references/pecmd-gui.md (75422b), references/troubleshooting.md (8516b), SKILL.md (31299b), _meta.json (132b)\n\nArchive v1.5.1: 12 files, 126743 bytes\n\nFiles: README.en.md (4736b), README.md (4633b), references/commands-full.md (87901b), references/how-tos/gui.md (24357b), references/how-tos/net.md (6056b), references/how-tos/storage.md (16565b), references/how-tos/system.md (33435b), references/pe-startup.md (11283b), references/pecmd-gui.md (75421b), references/troubleshooting.md (8516b), SKILL.md (31210b), _meta.json (132b)\n\nArchive v1.6.0: 12 files, 126743 bytes\n\nFiles: README.en.md (4736b), README.md (4633b), references/commands-full.md (87901b), references/how-tos/gui.md (24357b), references/how-tos/net.md (6056b), references/how-tos/storage.md (16565b), references/how-tos/system.md (33435b), references/pe-startup.md (11283b), references/pecmd-gui.md (75421b), references/troubleshooting.md (8516b), SKILL.md (31210b), _meta.json (132b)\n\nArchive v1.5.0: 12 files, 126247 bytes\n\nFiles: README.en.md (4736b), README.md (4633b), references/commands-full.md (87804b), references/how-tos/gui.md (24229b), references/how-tos/net.md (6007b), references/how-tos/storage.md (16549b), references/how-tos/system.md (33303b), references/pe-startup.md (11214b), references/pecmd-gui.md (75173b), references/troubleshooting.md (8516b), SKILL.md (30779b), _meta.json (132b)\n\nArchive v1.2.4: 11 files, 103701 bytes\n\nFiles: README.en.md (4731b), README.md (4628b), references/commands-full.md (67808b), references/how-tos/gui.md (23602b), references/how-tos/net.md (5699b), references/how-tos/storage.md (16052b), references/how-tos/system.md (32594b), references/pe-startup.md (10358b), references/pecmd-gui.md (66035b), SKILL.md (19538b), _meta.json (132b)\n\nArchive v1.2.3: 11 files, 101843 bytes\n\nFiles: README.en.md (4632b), README.md (4512b), references/commands-full.md (66390b), references/how-tos/gui.md (23602b), references/how-tos/net.md (5699b), references/how-tos/storage.md (16052b), references/how-tos/system.md (32594b), references/pe-startup.md (10358b), references/pecmd-gui.md (65856b), SKILL.md (17455b), _meta.json (132b)\n\nArchive v1.2.1: 11 files, 97647 bytes\n\nFiles: README.en.md (4631b), README.md (4510b), references/commands-full.md (66273b), references/pe-startup.md (10877b), references/pecmd-gui.md (66159b), references/recipes/gui.md (23781b), references/recipes/net.md (5706b), references/recipes/storage.md (16044b), references/recipes/system.md (32956b), SKILL.md (17614b), _meta.json (132b)\n\nArchive v1.2.0: 8 files, 113221 bytes\n\nFiles: README.en.md (4664b), README.md (4514b), references/codebook.md (85146b), references/commands-full.md (80371b), references/pe-startup.md (10881b), references/pecmd-gui.md (45788b), SKILL.md (56307b), _meta.json (132b)","readmeExcerpt":"Skill: PECMD Pro Max Owner: virtualhotbar Summary: PECMD2012 WinPE 脚本编程 — 轻量级 Windows GUI、系统工具、启动/初始化 脚本、自动化。适用于 .wcs/.wci/.wce 文件、磁盘分区、批处理转 PECMD、 系统信息收集、PE/预安装环境工具、PECMD 代码调试。 参考文件：references/commands-full.... Tags: automation:1.7.1, latest:1.7.1, pecmd:1.7.1, scripting:1.7.1, system-tools:1.7.1, windows:1.7.1, winpe:1.7.1 Version history: v1.7.1 | 2026-05-05T14:47:29.285Z | auto pecmd-pro-max 1.7.1 - Updated comma","codeSnippets":[],"executableExamples":[{"language":"wcs","snippet":"ENVI-env hwnd0=%&__WinID%           // 从环境变量读取 __WinID（绕过 ForceLocal）\nSET-env MyName=%MyName%             // 临时设为环境变量"},{"language":"wcs","snippet":"#code=65001\nENVI^ EnviMode=1\nENVI^ ForceLocal=1\nSET$ &NL=0d 0a\nSET$ &TAB=09"},{"language":"wcs","snippet":"SET$ &NL=0d 0a                  // 十六进制转宽字符串（Unicode）\nSET$# &buf=*4096 0              // 十六进制转原始字节（二进制缓冲区）\nENVI$ &data=*1M 30 0d 0a        // 可变长度十六进制分配"},{"language":"wcs","snippet":"_SUB 函数名 [*]                   // * = this-call（在调用者栈中运行）\n    SET &param1=%~1                 // %~1 剥离外层引号\n    ENVI-ret %~3=%&result%          // 通过引用参数返回值\n    // 函数参数：%0=函数名, %1~%n=各参数, %#=参数个数, %*=全部参数, %~=去掉引号\n_END"},{"language":"text","snippet":"CALL 函数名 [参数]                 // 调用函数\nCALL *函数名 [参数]                // this-call（调用者栈）\nCALL @窗口名 [参数]                // 创建/显示窗口（模态，阻塞）\nCALL @*窗口名 [参数]               // 并行窗口（可同时操作，但关闭前阻塞后续命令）\nCALL @-窗口名 [参数]               // 后台窗口\nCALL @~窗口名 [参数]               // 后台，完全非阻塞\nCALL @~~窗口名 [参数]              // 后台快速调用（非阻塞）\nCALL @^窗口名 [参数]               // 并行，父窗口不阻塞子窗口\nCALL @+窗口名 [参数]               // 弃养子窗口\nCALL @--                           // 销毁 Win 环境（无参数）\nCALL @--popmenu 窗口名 [x.y[:对齐]] // 在指定位置弹出菜单（对齐：对齐方式）\nCALL --mem &变量名 [*] [参数]      // 执行内存中的动态函数代码"},{"language":"wcs","snippet":"_SUB 窗口名,L200T100W400H300,窗口标题,[关闭命令],[图标],[样式],[遮罩] [-标志1 -标志2 ...]\n_END"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: pecmd-pro-max\nversion: 1.5.5\ndescription: |\n  PECMD2012 WinPE 脚本编程 — 轻量级 Windows GUI、系统工具、启动/初始化\n  脚本、自动化。适用于 .wcs/.wci/.wce 文件、磁盘分区、批处理转 PECMD、\n  系统信息收集、PE/预安装环境工具、PECMD 代码调试。\n  参考文件：references/commands-full.md、references/pecmd-gui.md、references/pe-startup.md、\n  references/how-tos/storage.md、references/how-tos/system.md、references/how-tos/gui.md、references/how-tos/net.md、\n  references/troubleshooting.md。\ncompatibility: 需要 PECMD2012 v1.88+ 解释器。脚本运行于 PECMD/WinCMD 环境，非 cmd.exe。\n---\n\n# PECMD Pro Max\n\n你是 PECMD 专家程序员。PECMD 是从 XCMD V2.2 演进而来的 WinPE 命令解释器与脚本语言——可将其视为 Windows PE 系统管理和轻量级 GUI 工具的领域特定语言。\n\n## $1 心智模型\n\nPECMD 有两种执行模式：\n- **命令行模式**：`PECMD.EXE ENVI $PPPoE=OK` — 单条命令，注释默认关闭\n- **脚本模式**：`PECMD.EXE LOAD C:\\PECMD.INI` — 多命令文件，注释默认开启\n\nPECMD 脚本是一组平铺的顶层语句。从上到下顺序执行。`_SUB` 块在解析时声明，仅在 CALL 时运行。所有 GUI 由定义窗口函数的 `_SUB` 块创建（通过 `CALL @窗口名` 调用）。\n\n关键运行时事实：\n- `PECMD.EXE MAIN 路径\\PECMD.INI` — 标准 WinPE 入口，执行 INI 并启动消息循环\n- 可在 PECMD 内运行 PECMD：`EXEC =!\"%MyNAME%\" <命令>` — 用于隔离的子操作\n- `EXIT FILE` 终止整个脚本；`EXIT _SUB` 从当前函数返回\n- 循环体内 `EXIT CONTINUE` 继续下一次迭代；`EXIT -` 跳到当前 `{}` 块尾部；`EXIT LOOP` / `EXIT FORX` / `EXIT BREAK` 跳出循环；`EXIT ToWin` 中止函数返回窗口消息循环\n- 脚本文件常用 `.wcs` 扩展名（也支持 `.wce`、`.wci`、`.wcx`、`.ini`、`.inf`、`.txt`、`.log` 等）。中文脚本首行加 `#code=65001` 声明 UTF-8 编码。若首行以 `#!` 开头，编码指令放在第二行。\n\n**标准 I/O（stdin/stdout/stderr）：**\n- `READ -,n,&var` — 从 stdin 读取一行\n- `WRIT -,$+0,text` — 写入 stdout\n- `WRIT --,$+0,text` — 写入 stderr\n- `LOGS * CONOUT$` — 输出到控制台（调试终端输出）\n\n## $2 变量系统\n\nPECMD 有**四种访问前缀**对应三种存储层级（加上就近查找机制）。搞错这一点是绝大多数错误的根源。\n\n| 层级 | 语法 | 设置方式 | 作用域 |\n|------|------|----------|--------|\n| 环境变量 | `%var%` | `ENVI var=val` 或 `ENVI $var=val` | 进程级，与子进程共享 |\n| PE 全局变量 | `%&::var%` | `ENVI &::var=val` 或 `SET &::var=val` | 跨函数、跨线程、文件级，永不消失 |\n| PE 局部变量 | `%&&var%` | `SET &&var=val` 或 `ENVI &&var=val` | 当前 `_SUB`/`{}` 块，退出自动销毁 |\n| PE 变量引用 | `%&var%` | `ENVI &var=val` 或 `SET var=val` | 就近解析：从内向外查找，找到谁就是谁；找不到则创建为 `&&var` |\n\n**`&a` 解析顺序**（反向匹配，从内向外）：\n1. 先找当前范围的 `&&a` → 找到就用它\n2. 再往外层找 `&::a`（全局）→ 找到就用它\n3. 都没找到 → 当作 `&&a` 在当前范围新建\n\n**关键规则：**\n1. `ENVI^ ForceLocal=1` 放在文件顶部——强制 `ENVI` 和 `SET` 默认创建局部 PE 变量。**务必始终使用**（默认 `ForceLocal=0`，变量按就近查找链解析）。\n2. `ENVI^ EnviMode=1` — 空变量引用返回空字符串。务必始终使用（默认 `EnviMode=0`，兼容 4.0 模式：空变量不解释为字面文本，自动多轮次非顺序解释）。\n3. `SET` **始终**等价于 `ENVI &`（SET 总是创建 PE 变量而非环境变量）。ForceLocal=1 同时影响 SET 和 ENVI 的作用域（默认局部）。\n4. `%Desktop%` 是**环境变量**版本；`%&Desktop%` 是**PE 变量**版本。\n5. 多线程代码中务必使用 PE 变量（`&var`）——环境变量跨线程共享会竞态。跨线程通信用 `&::` 类变量。\n6. `SET~ &&dest=Source.Key` — `~` 运算符执行**间接解引用**：将右侧展开为变量名，再读取该变量的值。伪数组必备。\n7. `^` 前缀（`^SET`、`^ENVI`、`^CALC`、`^IFEX` 等）— 预先解释本命令（help.txt: \"命令前若干个^表示预先解释本命令几次\"）。循环中动态变量名必备。`^^` 预解释两次。\n8. `ENVI-ret %~1=%var%` — 将值设置到*名称*存储在 `%~1` 中的变量（引用返回）。\n9. `SET-def var=value` — 仅在变量未定义时设置（安全默认值）。\n\n### ENVI^ / ENVI @@ 运行时控制命令\n\n| 命令 | 功能 |\n|------|------|\n| `ENVI^ EnviMode=1` | 标准模式：空变量解释为空字符串，顺序解释1遍 |\n| `ENVI^ ForceLocal=1` | 强制所有变量为 PE 变量，最简多线程/并行窗口 |\n| `ENVI^ EXPORTLOCAL=1\\|0\\|&1\\|&0` | PE 变量继承：1=继承，0=隔离（默认），&1=仅本级及以下继承，&0=仅本级及以下隔离 |\n| `ENVI^ Alias name=cmd` | 命令别名：替代命令前半部（可包装 "},{"path":"README.md","content":"# PECMD Pro Max\n\n> PECMD2012 脚本编程的 AI 技能文件 —— 让 AI 编码助手一次写出正确的 WinPE 工具、GUI 和启动脚本。\n\n简体中文 | [English](./README.en.md)\n\n[![Version](https://img.shields.io/badge/version-1.5.1-blue)](./SKILL.md)\n[![License](https://img.shields.io/badge/license-NonCopyRight-yellow)](./LICENSE)\n[![PECMD](https://img.shields.io/badge/PECMD-v1.88+-green)](https://pecmd.net)\n\n## 这是什么？\n\nPECMD Pro Max 是一个 **AI 编码助手技能文件**，教会 AI 如何编写正确的 PECMD2012 脚本。PECMD 是 WinPE 指挥官 —— 一种用于 Windows PE 启动脚本、轻量级 GUI 系统工具、磁盘实用程序和预安装环境自动化的脚本语言与命令解释器。其变量作用域规则、十六进制内存模型和窗口系统以复杂著称。本技能编码了十多年的 PECMD 脚本知识，让 AI 助手能够一次写出生产就绪的 `.wcs` / `.wci` / `.wce` 文件，无需反复试错。\n\n## 文件结构\n\n```\npecmd-pro-max/\n├── README.md                        ← 你正在阅读\n├── README.en.md                     ← English version\n├── SKILL.md                         ← 主技能文件 — 心智模型、变量系统、关键规则、陷阱（561行）\n└── references/\n    ├── commands-full.md             ← 110+ 条命令完整参考（1943行）\n    ├── pecmd-gui.md                 ← 完整 GUI 控件与窗口系统参考（2178行）\n    ├── pe-startup.md                ← WinPE 启动流程、环境限制、PE版本差异\n    └── how-tos/\n        ├── storage.md               ← 磁盘/分区/文件/注册表/设备 写法示例\n        ├── system.md                ← 进程/线程/系统/工具/回调 写法示例\n        ├── gui.md                   ← GUI 控件/窗口/绘制 写法示例\n        └── net.md                   ← 网络/SOCK/COM/WMI 写法示例\n```\n\n## 核心特性\n\n- **三层变量系统详解** —— 环境变量 vs PE-局部 vs PE-全局，间接引用、延迟展开、引用返回、十六进制/原始缓冲区分配、二进制比较/转换\n- **110+ 命令参考** —— 每条 PECMD 命令包含完整语法、返回值、陷阱说明（含 BROW、TREE、LAMBDA、SBAR、IPAD、BLOCK、DTIM、SLID、SPIN）\n- **按域组织的写法示例** —— 磁盘/分区、进程/线程、GUI控件/绘制、网络/COM，按主题独立文件，AI按需加载\n- **完整 GUI 参考** —— 所有 25 种控件与子窗口（`LABE`、`EDIT`、`CHEK`、`RADI`、`IMAG`、`TABL`、`LIST`、`MEMO`、`TREE`...）、ENVI @ 控件属性大全、消息系统、窗口管理\n- **WinPE 启动流程** —— 从 `winpeshl.exe` → `PECMD MAIN PECMD.INI` 直至 `EXPLORER.EXE`，包含 `WinXShell` 集成\n- **50 个内置变量全表** —— 路径/Shell变量、进程/线程变量、窗口/GUI变量、脚本/运行时变量、命令结果变量\n- **17 个 ENVI 运行时控制命令** —— EnviMode、ForceLocal、Alias、WndProc、memvar、LoadPlugin、DisX64、zero、Arg、Clipboard、EnviBroad、__arg、LoadEnvi、HelpColor、DeskTopFresh(@@)、TaskIcoMenu(@@)、EXPORTLOCAL\n- **ForceLocal + EnviMode 默认值** —— 确保每个生成的脚本都使用最安全的变量作用域\n- **代码组织规则** —— `_SUB` 声明时解析 vs 运行时调用、`SET^` Win32 回调绑定、`CALL @` 变体速查表\n- **ENVI @ 控件属性大全** —— 通用属性、EDIT/ITEM/窗口专用、TABL 30+ 操作、TREE 10+ 操作、跨进程控制\n\n## 快速上手\n\n```wcs\n#code=65001\nENVI^ EnviMode=1\nENVI^ ForceLocal=1\nSET$ &NL=0d 0a\n\n_SUB MainWin,L200T100W400H200,你好世界,-trap\n    LABE Lbl1,L20T30W350H24,欢迎使用 PECMD\n    ITEM Btn1,L150T120W80H28,关闭,CALL CloseMe\n_END\n\n_SUB CloseMe\n    KILL \\\n_END\n\nCALL @MainWin\n```\n\n## 安装\n\n将 `pecmd-pro-max/` 文件夹复制到 AI 编码助手的技能目录：\n\n- **Claude Code**: `~/.claude/skills/pecmd-pro-max/`\n- **OpenCode**: `~/.config/opencode/skills/pecmd-pro-max/`\n\n## 运行要求\n\n- [Claude Code](https://claude.ai)、[OpenCode](https://opencode.ai) 或任何支持 agent 技能的兼容 AI 编码工具\n- [PECMD2012](https://pecmd.net) v1.88+（执行生成脚本的解释器）\n\n## 协议\n\n**NonCopyRight** —— 本技能完全自由、开源、无限制。随意使用、修改、用于商业产品。无需署名。无任何限制。\n\n---\n\n源码仓库：[github.com/VirtualHotBar/PECMD-Pro-Max](https://github.com/VirtualHotBar/PECMD-Pro-Max)\n\nClawHub：[clawhub.ai/virtualhotbar/pecmd-pro-max](https://clawhub."},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn75c1axscyjtg0wtnnt4h2jjx839hs5\",\n  \"slug\": \"pecmd-pro-max\",\n  \"version\": \"1.7.1\",\n  \"publishedAt\": 1777992449285\n}"},{"path":"references/commands-full.md","content":"# PECMD 命令参考\n\n按类别组织的完整命令参考。所有命令不区分大小写。\n语法约定：`<required>` 为必填，`[optional]` 为可选，`|` 表示多选一。\n\n---\n\n## 脚本结构\n\n### _END\n结束一个 `_SUB` 函数或代码块。\n```\n_END\n```\n必须单独一行。每个 `_SUB` 需要一个对应的 `_END`。\n\n### _ENDFILE\n脚本文件结束。该行之后的代码不会被加载。\n```\n_ENDFILE[-IMPORT]\n```\n`-IMPORT`：仅在文件被 IMPORT 时生效。\n\n### _SUB — 定义函数 / 类 / 窗口\n```\n_SUB FuncName [*]                   // 函数 (* = this-call，使用调用者栈)\n_SUB FuncName,*,,destroyCmd         // 带析构命令的函数\n_SUB WinName,<shape>,[title],[closeCmd],[icon],[style],[mask] [-flag1 -flag2 ...]  // 窗口\n```\n窗口形状：`LleftTtopWwidthHheight`。省略 L/T 为居中。\n窗口标志：\n`-top`（始终置顶），`-nocap`（无标题栏），`-nosysmenu`（无系统菜单），\n`-trap`（关闭时不退出），`-size`（可调整大小），`-maxb`（启用最大化），\n`-minb`（启用最小化），`-disminb`（禁用最小化按钮），\n`-discloseb`（禁用关闭按钮），`-nfocus`（不接受键盘焦点），\n`-ntab`（无 Tab 键导航），`-disaltmv`（禁用 ALT 拖动），\n`-forcenomin`（阻止最小化），`-scalef`（XP 风格 DPI 缩放），\n`-scale[:DPI]`（Win8+ DPI 缩放），`-nxp`（无 XP 视觉样式），\n`-csize`（尺寸=客户区），`-na`（创建时不激活）\n样式：`[#][$]`数字 表示透明度，`,#` 表示隐藏窗口。\n遮罩：`[color][*][w:h]bmpname` 用于异形窗口。\n\n### CALL — 调用函数/窗口/DLL\n```\nCALL FuncName [args...]               // 调用函数\nCALL *FuncName [args...]              // this-call（使用调用者栈）\nCALL @WinName [args...]              // 创建/显示窗口（模态，会阻塞）\nCALL @*WinName [args...]             // 并行窗口\nCALL @-WinName [args...]             // 后台窗口\nCALL @~WinName [args...]             // 后台，非阻塞\nCALL @+WinName [args...]             // 抛弃式子窗口\nCALL @^WinName [args...]             // 并行，父窗口不阻塞子窗口\nCALL @--popmenu WinName [x.y[:align]] // 弹出菜单\nCALL @--WinName                      // 销毁 Win 环境\nCALL @WinName                        // 初始化 Win 环境\n\n// DLL 调用（缓冲区输出用 `*&buf` 形式传递，见下方说明；需要 PECMD2012 v1.88+ 完整版）\nCALL $[? --cd --nrcd --c --[[i]v]ret:[~@]retVar] DLL|*hDll,Func,[#]p1,[#]p2...\nCALL $--ret:retVar [--cd],[--nrcd],-LoadLibrary,[^]DLLpath     // 加载 DLL（^=自动释放）\nCALL $--ret:retVar [&&memVar],-LoadLibrary,*[file]#resID[|type] // 从内存加载\nCALL $--ret:retVar ,-GetProcAddress,*hDll,FuncName             // 获取函数地址\nCALL $[--ret:retVar] ,-FreeLibrary,*hDll                        // 释放 DLL\nCALL $--win [--qd@ --cd --nrcd --ret:retVar] DLL,Func,cmdLine   // rundll32\nCALL $--cpl CPLpath                                             // 控制面板\nCALL $--ret:var ,-LoadLibrary,^<DLLpath                         // COM DLL 加载\n```\nDLL 标志：`--cd`=切换目录，`--nrcd`=不恢复目录，`--c`=C 调用约定（默认 PASCAL/stdcall），\n`--bool`=BOOL 返回，`--ret:*`=通过指针返回，`--m`=内存中，\n`--1`=剩余全部作为一个参数，`--co`=注册 DLL（默认），`--nco`=不注册 DLL。\n`--qd`=启用类型前缀系统（qualified mode），允许用 `#`/`$`/`*` 等前缀为每个参数指定类型。\n\n**类型前缀系统（--qd）：** 每个参数的类型覆盖，使用 `--qd:类型1,类型2,...`\n| 前缀 | 类型 | 描述 |\n|--------|------|-------------|\n| `#` | integer | 按整数传递（数字的默认方式） |\n| `<` | INT64 | 64位整数 |\n| `*` | PE variable | 按 PE 变量指针传递 |\n| `$` | string | 按字符串传递（Unicode） |\n| `=` | raw | 按原始数据传递 |\n| `>` | VARIANT | 按 VARIANT 传递 |\n| `@` | narrow | ANSI 窄字符串 |\n| `~` | UTF8 | UTF-8 字符串 |\n\n附加标志：\n```\n--sret           // 返回符号数量\n--16             // 以十六进制返回\n--iret:retVar    // 以 INT 返回\n--vret:[~@]var   // 返回 VARIANT（~=剥离，@=原始）\n--arg:~.table    // 参数备选格式（~=去除引号）\n.vFun:index      // 虚函数索引\n.vFun:[?]name    // IDispa"},{"path":"references/how-tos/gui.md","content":"# GUI 控件/窗口/绘制 — 写法示例\n\n> **版本兼容性：** 部分示例使用 DLL 调用（`CALL $--qd`）。DLL 调用需要 PECMD2012 v1.88+ 完整版支持（32-bit 和 64-bit 行为一致）。\n> 如果 DLL 调用不工作，可使用 `FIND --wid*@`、`EXEC*` 等内置命令替代。\n\n## 7. GUI 模式\n\n### 完整窗口模板\n\n```wcs\n#code=65001\nENVI^ EnviMode=1\nENVI^ ForceLocal=1\nSET$ &NL=0d 0a\nSET$ &TAB=09\n\nCALL @主窗口\n\n_SUB 主窗口,W400H300,我的工具,,#1,,\n    ENVI @this.Font=12:Microsoft YaHei\n    ENVI @this.bkcolor=0xF0F0F0\n    ENVI @this.MSG=0x0010:CALL OnClose           // WM_CLOSE (window-level, no _)\n    LABE -vcenter -trans 标签1,L20T20W360H30,欢迎使用本工具,,0x000000,14\n    EDIT 编辑1,L20T60W360H120,,CALL OnEdit,,12\n    ITEM 确定,L150T200W100H35,确定,CALL OnOK\n    ITEM 取消,L260T200W100H35,取消,KILL \\\n_END\n\n_SUB OnOK\n    MESS 你点击了确定@提示#OK\n_END\n\n_SUB OnClose\n    KILL \\\n_END\n```\n\n### DPI 感知窗口与手动布局\n\n```wcs\n_SUB DPIWindow,W600H400,DPI Demo,,,,, -scalef -scale\n    TEAM SET &dpi=| REGI #HKCU\\Control Panel\\Desktop\\WindowMetrics\\AppliedDPI,&dpi|\n    FIND $%&dpi%=, SET dpi=96\n    // Check if system already auto-scaled (if actual = requested, skip manual scaling)\n    ENVI @this.POS=?::&actualW:&actualH\n    IFEX [ %&actualW%=600 & %&actualH%=400 ], SET dpi=96\n    SET &DPI=%&dpi%/96\n    // Save initial positions for resize handling\n    ENVI @this.POS=?::&InitW:&InitH\n    CALC #&x=20*%&DPI%\n    ITEM Btn,L%&x%T120W100H30,DPI Button,CALL OnClick\n    ENVI @this.MSG=0x0005::&&wp,&&lp,CALL OnResize %&wp% %&lp%\n_END\n\n_SUB OnResize\n    IFEX $%1=1, EXIT _SUB                        // SIZE_MINIMIZED, skip\n    CALC #&newW= %2 & 0xFFFF                     // LOWORD of lParam\n    CALC #&newH= %2 / 0x10000                    // HIWORD of lParam\n    IFEX [ %&newW%<600 | %&newH%<400 ],         // enforce minimum\n    {\n        ENVI @DPIWindow.POS=::%&InitW%:%&InitH%\n    }\n_END\n```\n\n### TABL 数据操作（综合）\n\n```wcs\n// Title with formatting flags\nENVI &&Title=100:名称%&TAB%=60:PID%&TAB%+80:内存%&TAB%*0:隐藏列%&TAB%*200:路径\n//   default=left, =  =right-align, +  =center, *0: =hidden column\n\nTABL Table1,L10T10W500H300,%&Title%,,0x10040\n\n// Bulk-set from variable (typical after FIND --pid*@)\nFIND --pid*@ &&processList,\nENVI @Table1.Val=1*;%&processList%\n\n// Read individual cells\nENVI @Table1.Sel=?;&sel\nENVI @Table1.Val=?%&sel%.1;&name\nENVI @Table1.Val=?%&sel%.2;&pid\n\n// Row count\nENVI @Table1.Val=?*;&count\n\n// Clear all\nENVI @Table1.Val=-*\n\n// Select/deselect\nENVI @Table1.Sel=3\nENVI @Table1.Sel=3;0\n\n// Set full row (tab-separated columns)\nENVI @Table1.Val=%&row%;%&col1%%&TAB%%&col2%%&TAB%%&col3%\n\n// Sort rows by reading and swapping values\nENVI @Table1.Val=?%&a%;&rowA\nENVI @Table1.Val=?%&b%;&rowB\nENVI @Table1.Val=%&a%;%&rowB%\nENVI @Table1.Val=%&b%;%&rowA%\n```\n\n### LIST 下拉操作\n\n```wcs\nLIST -h List1,L10T10W200H200,,CALL OnSelect,,0x100\nENVI @List1.VAL=                        // clear all\nENVI @List1.ADD=选项1                    // add item\nENVI @List1.ADD=选项2\nENVI @List1.ADDSEL=默认选项              // add and select\nENVI @List1.DEL=选项1                    // remove item\nENVI @List1.isel=2                       // select by 1-based index\nENVI @List1.QUE"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"PECMD2012 WinPE 脚本编程 — 轻量级 Windows GUI、系统工具、启动/初始化 脚本、自动化。适用于 .wcs/.wci/.wce 文件、磁盘分区、批处理转 PECMD、 系统信息收集、PE/预安装环境工具、PECMD 代码调试。 参考文件：references/commands-full.... Skill: PECMD Pro Max Owner: virtualhotbar Summary: PECMD2012 WinPE 脚本编程 — 轻量级 Windows GUI、系统工具、启动/初始化 脚本、自动化。适用于 .wcs/.wci/.wce 文件、磁盘分区、批处理转 PECMD、 系统信息收集、PE/预安装环境工具、PECMD 代码调试。 参考文件：references/commands-full.... Tags: automation:1.7.1, latest:1.7.1, pecmd:1.7.1, scripting:1.7.1, system-tools:1.7.1, windows:1.7.1, winpe:1.7.1 Version history: v1.7.1 | 2026-05-05T14:47:29.285Z | auto pecmd-pro-max 1.7.1 - Updated comma","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1422,"uniquenessScore":47,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-11T15:26:58.742Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-11T15:26:58.742Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-11T17:42:15.239Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}