本文件维护技术所有权、数据含义和开发方式。产品范围归 Product,本轮结果见 V0.57 收口归档,测试要求归 Quality。当前代码为 V0.57。统一数据、模拟编辑及十段硬件报告已完成;硬件采集与报告边界见实施核对。已知限制见 CHANGELOG。
C#、WinUI 3、.NET 10、Windows App SDK 2.4;SDK 以 global.json 为准。Windows 项目当前 TFM 为 net10.0-windows10.0.26100.0,SDK BuildTools 为 28000 系列。最低操作系统以 Product 为准。
| 模块 | 所有权 |
|---|---|
| Domain | 稳定标识、单位和无副作用的存储规则、容量计算 |
| Application | 存储事实模型、用例契约、编辑意图、操作规划和表现投影 |
| Execution | 类型化计划/步骤、执行策略、风险和前置条件、结果与回放;真实修改默认拒绝 |
| Inventory / Monitoring | 采集与监控契约、适配接口及各自数据模型 |
| Infrastructure.Windows | 固定只读 Windows 采集、Windows 适配、现有模拟协调与系统仓储适配 |
| Infrastructure.Sqlite | 事务、仓储、数据格式实现 |
| Ipc / Agent.Client | 封闭的 App–Agent 类型化传输、连接和结果传播 |
| App | WinUI 页面、输入、呈现和交互;不自行实现存储规则或写 SQLite |
| Agent | 每用户可见托盘进程、采集/监控协调、SQLite 写租约和进程生命周期 |
依赖保持表现与适配层 → Application → Domain 的现有方向,Execution 与 Inventory 等边界按现有项目引用验证。优先在现有项目内拆分职责,不新增通用引擎项目、DSL、插件体系或公开 SDK。
TopologyLayoutEngine 的布局决策归整数单位计划,像素/DPI 只负责最后映射;不把容量业务规则放入布局算法。修改布局算法时按需读踩坑记录中的布局案例。硬件页按来源对象展示,不以旧 13 类、154 项为数量契约。旧报告工厂和原始快照解释器已退出构建,有效 CIM/WMI 与原生补充读取保留。
共用一套存储对象含义,区分采集事实、编辑草稿和操作结果;不复制三套完整模型。
| 含义 | 约定 |
|---|---|
| 身份 | 内部稳定 ID、系统 ID 和提供程序定位信息分工明确;盘符、名称、列表顺序、DiskNumber 不能单独作为持久身份。名称变化不得改变身份、关系或目标定位;缺少可靠 ID 时不以名称猜测跨采集关联。保留稳定性/未知标记 |
| 实体 | PhysicalDisk、StoragePool、StorageTier、VirtualDisk、OS Disk、Partition、Volume 各有明确身份;分区描述几何和分区类型,卷描述文件系统与挂载。无卷的分区也是合法事实 |
| 关系 | 来源事实中的对象关联是唯一事实源;通用关系图、导航和显示是其派生投影,不各自维护另一套可修改关系 |
| 显示对象 | 模拟层、模拟池是统一层派生对象,沿用真实层/池的适用属性结构,但没有来源字段和容量;不得进入来源事实、持久化或真实命令目标。详细产品语义见 UnifiedModel |
| 未知 | 未采集、读取失败、不支持、否、零、空集合分别按含义表达;不得把缺失状态静默补成健康、可写或无系统角色 |
| 草稿 | 记录用户意图和基线修订。临时输入不完整不等于允许生成非法模拟文档 |
| 操作 | 一次生成类型化操作序列,预览、校验和提交共用它;模拟命令文本只作解释,不再由文本反推执行 |
| 结果 | 区分成功、明确失败、结果未知和修订冲突;传输失败不能证明存储未改变。以 Agent 的持久化记录对账 |
读取遇到超出编辑范围的 Windows 结构时保留原貌及只读原因,不自动“修复”。新增或更改结构必须通过本次操作适用的规则;对无关未知对象不得仅因其存在而阻断其他独立对象的只读展示。
规则统一入口,内部按对象/操作分组。合法性规则输出允许、拒绝或信息不足,并携带稳定原因、受影响对象和依据/适用条件。App 用同一规则和模拟操作服务完成表单反馈、动作预检查及内存候选文档;UI 禁用不是校验边界。模拟提交到 Agent 时系统校验明确标记为 SkippedForSimulation,Agent 不重跑整套业务规则,只执行封闭请求、格式/哈希、修订、CommitId 对账、事务和单写入方等提交保护。未来真实执行必须由 Agent 重新检查实际 Windows 状态。
规则依赖必要的 OS/SKU、提供程序、布局、介质、用途、扇区及能力信息;只定义当前操作需要的字段。不把本机能力偷偷套用到导入系统。未知组合不默认放行,不为通过旧样例而放宽规则。
容量至少明确原始物理容量、逻辑容量、已分配/物理占用、可用范围和估算来源,不能用同一个值替代。计算使用整数 bytes 和溢出检查;单位转换只在输入/显示边界进行。
- 保留适用的采集值及来源;改名等无容量影响的操作不重新估算。
- 成员、布局或分配相关参数改变后,使受影响的容量/能力证据失效,重新估算并标记,保留未受影响事实。
- 模拟 Simple、Mirror、Parity 分别按布局、数据副本、列数和校验列折算理想逻辑上界,排除热备与退役盘。MAX 与默认创建值向下对齐到 4 GiB,不再扣旧 1% 余量,也不以 Interleave 代替容量粒度;这不是 Windows 通用保证。混合介质逐层计算,物理占用与逻辑容量分别保存。
- 理论估算、保守规划值和真实采集值区分。模拟应用后仍是估算;未来真实创建结束后才由重新采集结果更新。
- 200G 成员合计、UseMax 实得约 199.86G、规划预留至约 198G 是用户提供的示例,不是 Windows 的固定扣减公式。当前估算策略见本节,行为验证按 Quality 执行;调整策略时在对应任务或阶段计划中明确范围。
- 容量余量不能替代合法性,也不保证真实操作成功。无法建立保守估算的组合返回尚不支持,不制造精确数字。
新增字段按一条链路完成:采集来源 → 原始数据 → 规范化模型 → 规则/模拟 → 持久化与 IPC → 界面/导出 → 往返和缺失值测试。字段的来源、单位、缺失含义和失效条件跟定义就近维护,不再分别维护大型字段副本。
修复缺陷时,将失败场景补成回归测试,检查实际入口的最终结果(按需覆盖连续操作、重载和失败恢复)。后续修改相关功能时重跑;预期以当前需求为准,不把旧样例固化为产品边界。
采集通知使用同一套状态文案。Agent 的 Started、Updated、Failed 事件带自动来源标记;自动阶段由 LocalInventoryObserver 转交通知,成功仅在文档验证并应用后呈现。手动请求仍由请求/响应路径通知,包含连接或传输失败;事件不再重复通知手动采集。自动存储、自动完整硬件及手动刷新使用独立进度键;失败、断流或重连清理未完成的自动进度。采集事件与监控诊断共用严格版本握手;当前 IPC 为 11,App 与 Agent 须成套重启。
WinPoolFacts 保存带来源、时间、类型、读取状态的原始对象及关联;WinPoolSystem 与 StorageSnapshot 是只读派生结果。跨来源选值由 WinPoolSourceDetails 维护,只有明确等价的字段参与备用或冲突判断。缺少安全字段、关联冲突和数值超范围不能变成允许;所有采集字段保持原值,不设置脱敏状态或按隐私开关裁剪。
显示用假池、假层由 SyntheticStorageProjection 从当前快照派生,使用独立的 SyntheticStorageObject,不为它们构造 WinPoolSourceObject。WinPoolSystem.SyntheticStorageObjects 与有来源的 Objects 分开;管理列表、拓扑、属性及导航共享同一派生规则。快照经 with 修改成员或用途后重新派生,不能携带旧的缓存分组。假对象使用 LogicalGroup 操作身份,并在命令和模拟编辑入口拒绝作为存储修改目标;原始字段区域单独显示“无原始来源”。既有编辑器用途操作仍针对成员磁盘,不针对假层。
真实层容量呈现统一使用 TierCapacityText,根据来源字段读取状态区分缺失与零,不以成员合计回填。只有新建草稿的规划默认值可以按既有规则计算;该默认值不属于统一显示用模拟层的容量。
存储与完整硬件使用独立刷新用途,Agent 串行协调;较旧结果忽略。来源失败保留上次事实及关联时间,成功空集合才移除对象。层成员没有可靠关联时显示归属未知,不按介质相同猜测。
App 启动经 ReadOnlyLocalInventoryReader 以只读 SQLite 连接读取已提交的本机事实,不初始化数据库、不取得写租约;校验现有 schema、文档格式和哈希后先呈现历史。Agent 就绪后自动顺序执行 Storage、Hardware 两次采集,沿用同一串行采集/合并/持久化入口,成功落库后发送类型化库存事件,失败发送失败事件且仍尝试下一阶段。App 的 LocalInventoryObserver 在工作区初始化前订阅,初始化后接收阶段结果;晚连接与重连补读 Agent 缓存。UI 线程统一应用新结果,拒绝旧/重复回报,保留模拟选择;两页手动刷新仍触发各自用途的采集。退出、提权交接与切换数据根前取消并等待启动采集,避免继续写旧数据根。IPC 为 11,核心 SQLite schema 仍为 17。
窗口恢复上次系统另走 ReadOnlyWorkspaceStartupReader:在同一个只读 SQLite 快照内核对 schema、工作区选择及其指向的唯一活动文档;模拟文档核对元数据与 SHA-256,本机文档核对缓存格式。首个异步偏好等待前隐藏系统内容,页面偏好加载后只对验证成功的文档做临时预显,标题栏显示系统名但暂不接受操作;损坏、缺失或旧 schema 则显示居中加载态。预显不写数据库,也不放开工作区状态持久化。Agent 连接后仍由现有仓储完整恢复目录与选择;只有确认后的编辑文档签名变化才重建已显示编辑页,最后放开页面和系统选择器。读取本次运行消息历史不阻塞首屏。此路径只优化可见启动顺序,不把预显当成真实存储状态或 Agent 的提交权威。
完整硬件刷新在既有 CIM/WMI 事实后追加 WindowsGraphicsFactCollector 和 WindowsNetworkFactCollector:前者以 DXGI LUID 保存适配器和输出,并用 D3D12 读取功能级别;同一 LUID 通过 D3DKMT 保存适配器类型标志、显示侧描述和渲染侧描述。IndirectDisplayDevice 为真时统一对象使用显示侧名称,保留 DXGI 原始描述,并禁止按相同 VEN/DEV 借用物理 GPU 的驱动和 PCI 位置。Win32_VideoController、Win32_DesktopMonitor 与 WmiMonitorID 在统一事实中属于字段补充,不形成第二组 GPU 或 Monitor 设备,驱动、型号和厂商仍可按可靠硬件标识补入 DXGI 对象。软件或间接显示 DXGI 适配器均不按标志或名称过滤。网络保持 WinPool.NetworkAdapter 统一来源键不变,内部以 MSFT_NetAdapter 的 ConnectorPresent -or InterfaceType -ne 0 作为对象集合边界,按接口索引关联全部 IP 地址与默认路由,并替换同次脚本采集产生的原始 MSFT_NetAdapter 观察。同一来源的成功刷新直接整组替换旧网络对象,不引入跨来源迁移规则。WinPoolSystem 是不持久化的运行时投影;入库的是来源事实,启动从来源事实重新生成统一模型,完整硬件在 Agent 启动第二阶段自动刷新,也可手动刷新。Monitor 不在报告投影中筛除,存储摘要不增加硬件页专用条件。
HardwareReportProjector 按统一对象类型完整投影 CPU、内存、页面文件、GPU、Monitor 和 Network;报告可以选择字段行,但不能按来源类名选择或丢弃某个对象。字段备用来源只用于补值,不改变对象列集合。ManageSystemSummaryProjector 为管理页与硬件页提供同一存储摘要。App 通过 PropertyTableVisuals 小范围复用管理页与硬件页的项名上限、项值上限、列间距、行高和单元格样式:两页项名列使用 Auto 宽度及 220 DIP 上限,项值列使用 Auto 宽度及 250 DIP 上限;硬件项名网格位于分段横向 ScrollViewer 外,标签行高跟随值行。外层纵向 ScrollViewer 包含左对齐操作、即时反馈和整份报告,不呈现采集完成时间。设备列选择、悬停、选中后居中和所选列文本复制沿用管理页语义,硬件页不再打开字段详情对话框。标题栏的 ActiveSystemSelector 复用现有系统切换入口;下拉选择先暂存,待 DropDownClosed 后再切换工作区和重建列表,避免在 WinUI 弹出层仍打开时使控件集合失效。不建立第二套事实模型或通用表格框架。所有字段保持原值;内部格式为核心 SQLite 17 / 监控 SQLite 1 / IPC 11 / StorageSystemDocument 3 / 来源事实 1。
MainWindow 的自绘标题栏行高 48 DIP,先启用 ExtendsContentIntoTitleBar,再设置 AppWindow.TitleBar.PreferredHeightOption=Tall。导航列表、真实编辑控件和可见的系统选择器容器是 Passthrough 交互区,剩余标题行由系统处理拖动;这些交互区加载或尺寸变化后排队重算物理像素矩形,避免语言和窗口布局变化后命中区域仍是旧坐标。系统选择器宽 260 DIP,容器及下拉项上限 280 DIP。App 自建按钮按角色使用两套尺寸:图标文字普通按钮以 WinPoolButtonBaseStyle 统一 4 DIP 圆角、32 DIP 最小高和内边距;行内单图标按钮以 WinPoolInlineIconButtonStyle 统一 32×32 DIP。按钮处在管理命令区或编辑操作区不改变其角色,也不派生第三套按钮高度。输入和下拉最小高 32 DIP,属性字段行采用 Auto 高度及 40 DIP 下限,文字换行时可增高;布局槽高度不是按钮高度。
内置模拟继续以 StorageSnapshot 作为编辑模型,但持久化前由 WinPoolSimulationFacts 生成 Windows 形态的来源事实。来源仍明确标记为 FactOrigin.Simulation,命名空间、类名、字段名、CIM 数字枚举、数组类型和 bytes 单位分别对齐 Win32_ComputerSystem、Win32_OperatingSystem、Registry.CurrentVersion、MSFT_*、Win32_LogicalDisk、Win32_DiskDrive 与磁盘角色补充来源。Partition、Volume 和 LogicalDisk 按真实来源拆分并用关系组合;模拟模型无法提供的 Windows 属性不伪造。系统版本号与 DisplayVersion 分开,系统卷使用 4096 bytes 分配单元,存储空间数据卷继续使用当前测试布局的 65536 bytes。
编辑状态由 SimulationEditingSession 集中管理。结构、即时分区和改名共用 SimulationEditRequest、规则与类型化步骤;目标分组、用途、分区表类型分别使用 DestinationGroupId、DiskUsage、PartitionStyle,不得塞入 Name。命令只解释步骤,未绑定 CIM 目标和无命令操作均明确说明,没有执行入口。
模拟格式化方式由 SimulationEditRequest.QuickFormat 携带,默认沿用快速方式;分区页两个互斥开关只决定此意图。计划与解释性命令预览保留完整方式的差异,当前模拟卷结果仍按现有 StorageSnapshot 字段生成,不增加介质扫描或真实 Windows 命令执行。系统导出保持现有 StorageSystemDocument JSON 结构,以 .json 扩展名写出;旧 .winpool 文件只作为导入兼容入口。当前编辑资格与几何边界见模拟规则表;旧叙述稿已归档。
模拟新建分区以 EditWorkspace.GetPartitionCreateGeometry 计算可用范围:把起点向上吸附到 1 MiB 网格,可用长度向下取整到整 MiB;不足一个整 MiB 返回明确不可创建原因。分区页与结构页自动创建读取该几何,草稿规划先按同一粒度整理容量,规则校验及模拟提交再以共享几何核对,不能由界面独自夹紧超界容量。空盘勾选 MSR 时创建于 1–17 MiB;已有导入结构保持原始偏移及容量,不自动重排。
存储结构与磁盘分区编辑页右侧属性栏均从 320 DIP 宽开始,使用 8 DIP 可拖拽分隔槽调整左右比例;属性栏紧贴分隔槽,不再叠加 8 DIP 左边距。两页属性表单使用受栏宽约束的弹性标签/值列,不再强制 412 DIP 内容宽或横向滚动。分区属性行最小高 40 DIP、行距 4 DIP;容量输入与换算组成的复合行按内容增高。左下操作区的按钮槽最小高 44 DIP,实际高度随同行内容增长;窄窗可双向滚动且最高 220 DIP,结构页待处理列表内容最高 96 DIP,以保留拓扑视口。起点与终点各占一条单行数值行,MiB 数字和括号内自适应数字各在独立的列中右对齐;无法计算偏移时隐藏数值及单位,只显示横线。容量输入下方的只读自动单位值使用普通正文文字样式。管理、监控和开发页的实际区域分隔槽同样为 8 DIP 且可拖;普通卡片之间的间距不创建分隔槽。
模拟分区扩缩的容量能力与提交共用 StorageEditRules 的建模计划。目标是总容量并按 1 MiB 对齐,依据保存的磁盘范围、下一分区边界和卷已用容量检查;分区与关联卷以同一增量更新,保留合法容量差,不将文件系统容量强制等同分区范围。扩缩入口由分区页的“扩展分区/压缩分区”按钮打开同窗口串行对话框,输入整数 MiB,对话框只接受落在能力范围内的目标并在确认前逐次校验;页面容量框对已有分区只显示四舍五入后的当前容量,不作为目标输入,因此两位显示舍入不会再被当成隐式修改,也不会让按钮永久灰置。上述范围不是 Windows Get-PartitionSupportedSize 实测,也不允许真实写入;当前验收状态见活动 Plan。
模拟分区删除资格只由所选分区自身的 Boot/System 标记决定,页面、管理页投影和服务端共用 StorageEditRules.CanDeleteSimulatedPartition:同盘的系统身份、分区类型(含 EFI、MSR、恢复)和所属系统盘都不再单独禁止删除,但仍不得删除标记为 Boot 或 System 的分区。格式化保持更窄的范围,只允许普通 Primary/BasicData 且非 Boot/System,不随删除资格一起放宽。
系统 JSON 导入在转换及保存前验证来源投影:分别拒绝已知负偏移、非正容量,以及可证明的加法溢出、超出所属磁盘范围和重叠;缺失或冲突的字段不作为已知值参与几何运算。按显式磁盘身份分组,不按磁盘编号猜测关联,也不把编辑器的新建限制套在合法导入结构上。容量估算溢出统一转为参数拒绝,保留原始来源事实。
内置模拟与导入模拟均可删除。BuiltInSimulationCatalogPolicy 只在首次成功初始化或显式恢复默认时补齐样例;UserPreferences.BuiltInSimulationCatalogSeeded 在持久化成功后设置,正常重载不重建已删除样例。目录可以没有模拟系统,此时使用本机选择。单项导入、转换及删除先完成仓储操作再更新内存目录;批量恢复默认逐项同步成功结果,避免失败重试使用旧修订。
自动创建虚拟磁盘、分区保存在 App 的 UserPreferences,结构页开关保留原位置;选择对象不修改偏好,偏好变更不反向增删已有结构。新建操作读取偏好,相关保存串行取最新偏好以避免快速连切丢失字段。前台文件选择器采用带窗口身份的 Microsoft.Windows.Storage.Pickers,不再用提升模式不支持的旧 picker;不因此新增管理员写入存储的权限。
V0.55 沿用 Application 的通知契约与 GlobalNotificationService,Presenter 负责本地化,App 负责布局和交互。人工反馈修复采用最多三张即时卡片,超出时移出最旧卡但保留会话 History,不提供合并或溢出入口;独立重复消息分开记录。普通卡 8 秒自动消失,错误卡 20 秒,普通卡点击消失,错误卡点击显示消息对话框。清空历史不删除活动消息。消息只保存有界文本与标识,不持有控件、异常对象或完整采集文档,不写数据库或新日志文件。进度显式不进入历史,持续异常按真实状态变化发出,不因轮询重复发布;消息消失只改变呈现。验证范围见 Quality。
即时卡的宽度由 NotificationCard 固定,高度随有界内容变化;退出动画在 App 的展示层向右移动,动画结束后才释放可见项;服务的历史与生命周期不依赖动画。主窗口以展示项实例身份处理完成回调,避免旧卡回调移走同 ID 的新项。触发时机、图标、悬停和样式分别见设计核对表。
开发页“消息列表”只消费现有消息服务,不显示 Diagnostics 路径或读取故障日志文件。消息缓存不依赖开发页生命周期或 DeveloperMode;退出 App 自然清空,不补采后台历史。开发者模式关闭仍隐藏开发页,错误卡固定提示到开发页消息列表查看详情,不另加开启模式判断。现有 CommandLog 不接入此页,不复制成第二套历史。原生 ToolTip 与开发页详情分别承担短说明和可复制长信息;禁用控件仍应支持鼠标悬停帮助。其它需要确认的同窗口 ContentDialog 继续使用小型串行协调,不增加通用任务平台。
开发页左上消息列表直接投影 History 的时间、级别、来源和 Title,不读取 Diagnostics 文件;第四列不拼接 Message 正文。列表不显示表头,单行条目按四列紧凑排列并垂直居中。条目双击后在页面中央显示背景变暗的详情层;唯一可操作内容是只读可复制文本框,背后由 WinPoolOpaqueSurfaceBrush 实色底板承托,点外关闭。右下通知的单层 InfoBar 本体也使用该不透明主题画刷,避免背景透出。三个子区域可拖拽调整;右上和下方保留空区域,下方只给小号 AI 入口开发中提示;窄窗时消息列表横跨上方。此页不显示区域标题、说明、路径和操作按钮;“消息列表”仅用于控件自动化名称及文档称呼。
标准数据根是 %LocalAppData%/WinPool,便携模式使用程序旁可写 Data;启动指针为根目录之外的 %LocalAppData%/WinPool.storage-location.json,避免替换标准数据根时把活动指针一起移走。兼容读取标准根内旧指针;首次切换在目录改名前先固化当前指向。切换前验证目标,现有租约、单实例和生命周期机制继续保留。迁移核对表结构、主键与完整行摘要,核心库 checkpoint 在写入方静止后执行;若暂存副本缺少已提交 WAL 内容,拒绝切换并保留源,提示重启后重试。未确认的回滚树保留,不按名称自动清除。
| 持久化来源 | 唯一写入者与用途 |
|---|---|
app-settings.json |
App;语言、主题、当前页面等前台偏好,Agent 只读所需项 |
agent-settings.json |
Agent;持续监控、采样率、自启及可选的 7z 绝对路径覆盖;App 经类型化请求修改 |
winpool.db |
Agent;系统和采集快照、模拟文档、工作区、存储健康事件、执行与 Agent 会话记录;旧监控表和记录保留 |
monitoring.db |
Agent;新监控会话、设备与原始样本,独立格式版本,不迁移旧核心库监控记录 |
MonitoringArchives |
Agent;封存库、临时压缩包、完成归档及恢复记录;不是历史查询数据库 |
偏好按变化原子保存;已存在文件不可读时禁止用默认值覆盖。App 的读取、局部变更和整体替换共用串行门,局部变更在取得门后读取最新偏好,保存成功再发布状态,避免旧快照覆盖其它设置。Agent 偏好的 SavedAtUtc 只比较是否变化,不按大小排序;通知、重连和文件观察汇入串行重载。Agent 自己维护指向自身可执行文件的 HKCU Run 项。执行模式和真实操作同意不持久化。
监控拆库与归档已完成,证据见阶段归档。核心库保持 schema 17 和旧监控结构;监控库独立 schema 1。固定活动路径为 monitoring.db,主文件与 WAL 达到 1 GiB 时触发轮换:采样继续进入有界内存,旧写入排空、TRUNCATE checkpoint 成功并关闭连接后,仅将自包含主库改名封存,再创建固定名称新库。CSV 读租约与切换互斥。切换允许短暂推迟落盘,不承诺进程崩溃时内存不丢失。
CSV 仅导出当前活动监控库中的可用记录,不跨归档补齐会话。持久化诊断区分正常待写数量、最老待写年龄和确知未保存数量;正常 250 ms 攒批不是丢样,最老待写达到 2 秒时报告延迟。故障写入器的未提交数量按写入器身份只累计一次,恢复后的写入器失败另计;队列拒绝与已接受但未保存的样本分别计数,无法确认的异常结束缺口不编造条数。会话时长使用单调计时,归档诊断在停止采样后仍可刷新;通信成功不代替采样或落库成功。
停止监控及后续空快照保留 App 本次运行观察到的最近会话 ID,允许导出活动库中该会话的已保存记录;新会话取代旧会话。零行返回无数据且不覆盖已有目标文件。CSV 接受用户选择的普通绝对路径(含 UNC),拒绝设备命名空间、备用数据流、保留设备名及异常路径组件。该限制不改变自选导出目录。
归档在 MonitoringArchives/sealed 与 MonitoringArchives/packages 管理,恢复记录 archive-ledger.json 持久化归档根内相对路径,迁移数据根后按新根解析,不访问旧根。已完成归档不自动淘汰,不提供历史读取或解压缓存。后台串行压缩采用临时包,完整性、流式数据库 SHA-256 和清单内容核验通过后发布,才可释放本功能封存的原库;失败保留有效数据。故障恢复、缓冲计数与阶段验证状态见上述归档。
ControlledProcessRunner 与 SevenZipArchiveAdapter 是现有 SQLite 基础设施内的两个小型职责,不恢复旧工具管理项目。7z 默认相对运行目录解析为 Tools/7zip/7za.exe,随附资源来自 assets/ThirdParty/7zip/26.03,许可证和来源说明一并打包。自定义覆盖只检查绝对路径和文件存在,失败不回退,不执行能力或版本预检;压缩及校验固定使用本次任务开始时取得的路径。产品不提供工具安装、更新或搜索。
当前实施代码为核心 SQLite schema 17、监控 SQLite schema 1、IPC 11、StorageSystemDocument 3、来源事实 1、StorageSnapshot 3;均是内部格式编号,不是产品版本。新文档只持久化来源事实和应用状态,Snapshot 是无 setter 的只读重建投影,旧硬件报告模型及独立报告生产路径已退出。缓存仍校验哈希,旧格式明确拒绝,不提供迁移或兼容回退。监控样本逐项保存全部 MonitorMetricKind,未提供的指标写为 NULL,真实零保持为零;CSV 使用空单元格表达缺失。模拟文档 IPC 先分页读取有界元数据,再按 ID 单独读取正文,不扩大 4 MiB 帧上限。模拟提交的 CommitId 同时绑定文档、前后哈希、修订、OperationId 和 PlanHash,查询返回提交时的不可变文档回执。控制管道握手有独立 5 秒期限,连接级异常记录稳定代码并释放连接,监听任务终止会进入 Failed 并由托盘呈现。实际产品版本以 Directory.Build.props 为准,V0.52 验证状态见归档及实施核对。
控制管道在握手、事件连接和请求执行前核对实际客户端令牌完整性;较低完整性或无法核实的客户端不能控制 Agent。握手后每次请求读取与响应写出分别有 30 秒传输期限,不把此期限用于业务操作。连接超时释放监听器,后续合法客户端可重连。模拟提交分别保留输入拒绝、修订冲突、持久化失败和取消的状态及诊断代码。
App 使用更短的 25 秒控制连接复用期限,在发送任何请求字节前主动更新空闲连接;计时从上次传输开始,保持保守。已发出的请求不因断连自动重试,继续返回结果未知并走原有对账流程。
V0.53 在 UserPreferences 中保存默认关闭的 DeveloperMode,旧格式缺少字段时按关闭处理,不升级偏好格式。主窗口从偏好重建可用导航;Hardware、Test、Development 同受该门控制,隐藏状态下启动目标、快捷键和记忆页面均回到 Manage。开发者导航顺序以 Hardware 在 Manage 之前开始。
数据重建只能针对明确的 WinPool 开发数据,不静默擦除未知根。首次打开旧格式应明确提示版本不支持/需重建;自动测试按夹具使用临时数据,普通开发与原生界面核对直接使用已核实的 WinPool 开发数据。必要的旧开发数据处置遵守 AGENTS 的移动规则。允许丢弃开发数据不取消单写入方、事务、冲突检测和故障恢复要求。
普通启动采用 Windows App SDK 单实例机制;重复启动激活已有窗口。提权交接是整套 App + Agent 重启:新管理员 bootstrap 以 SID 绑定的 ready/continuation 事件进入等待,期间不初始化 WinUI、不取得实例键、也不连接或复用旧 Agent。旧 App 保存工作区并获得旧 Agent 的后台有序关闭确认后才允许 bootstrap 继续;后者必须按 PID、启动时间和路径核验旧 App、旧 Agent 均已退出,才进入普通启动并创建新的管理员 Agent。取消、事件失败、身份不符或超时均不得接管实例、复用旧 endpoint 或强杀旧进程。等待失败诊断写入数据根 Diagnostics/elevation-handoff.jsonl;IPC 正常断开不等同于 Agent 故障。SQLite 不是实时 Windows 状态的权威,未来真实操作执行前必须重新核对对象及前置条件。
在仓库根执行常规构建:
dotnet restore WinPool.slnx
dotnet build WinPool.slnx -c Release --no-restore -m:1生成文件集中在 artifacts:trees/<Configuration>/App 与 Agent 是独立树,<Configuration> 是并集运行树,obj 和 build 是中间文件与类库/测试输出。src 和 tests 只存源码。
build/Merge-RuntimeTrees.ps1 按相对路径和 SHA-256 合并:同路径同内容存一份,内容不同则失败。WinPool.App.exe 与 WinPool.Agent.exe 位于同一根目录,共享自包含 runtime;保持 PublishTrimmed=false。
.\artifacts\Release\WinPool.App.exe开发阶段默认关闭占用标准运行树的 WinPool App / Agent,然后直接构建到 artifacts/Release;可按开发需要修改或重建已核实的 WinPool 开发数据,无需逐次请示。不要在进程仍占用目录时部分覆盖。仅在用户明确要求并行保留版本,或标准目录确实不可用时,才考虑其他输出位置。正式分发保持完整目录;不包含脚本、PDB、源图、数据库、日志、测试结果或重复子程序。构建输出可保留 PDB,产物不提交。
旧的自定义隔离输出路径有生成目标传播缺陷:App/Agent 的 .deps.json、.runtimeconfig.json 及 App .pri 可能留在默认 artifacts/trees/Release,导致隔离运行树缺文件。这不是开发阶段的默认构建路线;不要为规避关闭进程或重建开发数据而重新尝试隔离构建。若未来确有明确的并行产物需求,应先修复并核对运行树文件完整性。
build/Merge-RuntimeTrees.ps1 先在相邻暂存树完成碰撞检查,并复制现有便携 Data;确认进程未占用后,将旧运行树移至项目根 Rubbish/YYYYMMDD_winpool-build,再发布新树。发布失败尝试恢复旧树,失败暂存树也保留。路径必须位于当前 checkout 内且不能含重解析点。
build/Rebuild-WinPool.ps1 先仅移走中间输出,保留旧运行树直到新构建合并成功,然后写入快捷方式;运行前须关闭占用标准树的 WinPool 进程。build/Clean-WinPool.ps1 -WhatIf 可预览,默认只移动明确生成物,保留运行树的 Data、测试证据及其它未知 artifacts。两者均不直接删除旧文件,也不按进程名结束未知路径的进程。它们不是纯文档任务或普通检查的默认入口。
未来正式 staging 使用仓库外未占用的新路径,复现同一并集和碰撞检查;不顺便部署、签名或发布。测试命令归 Quality。
内部开发文档只维护中文无语言后缀版本。根目录 README.md(英文)和 README.zh-CN.md(中文)保持用户信息一致;其他目录中的索引 README 不因此需要双语。历史双语原件不追溯翻译。代码/API 标识和微软原名保持英文。
Product 管产品,UnifiedModel 是其统一对象与派生属性专项设计;Development 管技术、Quality 管验证、Plan 管当前阶段(若有)、CHANGELOG 管重要结果;AGENTS 管操作规则。Design 保存未排期方案,Reference 保存方法,Archive 保存被替代/结束的历史。一个事实一个维护位置,其余用短摘要和链接。
设计只需状态、基线/条件、未决问题三个说明,不引入复杂审批体系。讨论中的设计不等于当前规范;方向已认可也不代表细节冻结。纳入版本时重新核对代码,明确采纳部分并写入唯一活动 Plan,长期决定归各自所有者。无须为每份设计新建一个 Plan。
有活动阶段时,Plan 记录范围、固定决策、任务依赖和验收;执行时及时更新实际状态。阶段被替代时如实归档,不写成验收完成;阶段结束时记重要结果、归档 Plan,没有新阶段就不保留活动 Plan。CHANGELOG 按重要结果记录,长历史可按明确时间点归档,Git 保留过程。
用户明确要求留待以后执行的计划可以保留在 docs/Plan.md 中,标记“未激活”并与当前任务分节;不提前归档,也不视为执行授权。此前界面与人工反馈阶段的 Plan 已归档;当前 Plan 仅固定本机真实存储编辑阶段的范围和边界,尚未实施。其他未激活 Design 不因此获得执行授权。
唯一产品版本源为 Directory.Build.props:Va.b 表示产品线,Va.bc 的 c 为 1–9 的迭代;迭代为 0 时显示补零,因此产品线 0.5 显示为 V0.50,框架数字版本为 0.5.0。框架必需数字版本由该文件机械生成。
项目不能通过相对路径、复制运行文件、子模块或运行时导入依赖其他仓库。软件资源使用受版本控制的 assets,不让代码依赖忽略目录。
WinPoolSystem 将唯一的 partition-volume / same-volume 关联组合为 WinPoolPartition,Resolve 接受所有成员来源 ID。StorageSnapshot.PartitionUnions 是管理与业务导出的单层表面,PartitionSourceIds 负责旧来源选择恢复。PartitionInfo / VolumeInfo / NetworkDiskInfo 仍作为采集、持久化和现有编辑命令的内部适配记录;不得再次据此建立独立卷属性分类。文件系统属性由同一个 ManagePartitionProjector 输出。
磁盘补充事实通过 disk-supplement 关联匹配唯一 Disk.Number。OS 磁盘的 Number、PartitionStyle 等仍读取自己的来源,不能被物理磁盘主来源覆盖。单例 Computer/OperatingSystem 身份按系统和类名确定。按来源刷新只替换本次成功的来源;保留仍被事实字段引用的历史来源及每类最新状态,避免重复失败状态增长。模拟提交保留仍有效的补充关系,删除联合体时同时去掉其附属逻辑来源,真正孤立来源继续保留。
固定采集脚本始终内嵌,经标准输入执行,不输出独立 inventory 脚本。分区联合体修复的历史验证见 CHANGELOG 中 2026-09-15 对应记录。