Skip to content

Latest commit

 

History

History
121 lines (93 loc) · 12.8 KB

File metadata and controls

121 lines (93 loc) · 12.8 KB

Архитектура W-Fix

Границы компонентов

  • W-Fix.App — WPF-интерфейс, выбор цели и сценария, отображение прогресса.
  • W-Fix.Core.Models — данные принтеров, журнал и типизированные результаты операций.
  • W-Fix.Core.Services — обнаружение принтеров, Active Directory и выполнение PowerShell.
  • W-Fix.Core.Fixers — прикладные сценарии диагностики и исправления.
  • W-Fix.Core.Abstractions — стабильные контракты транспорта, инвентаризации, диагностики, ремонта и отчётов.
  • W-Fix.Core.Remote — WinRM/WSMan-сессии, capability preflight и снимок печатной подсистемы.
  • W-Fix.Core.Diagnostics — правила, формирующие находки только из наблюдаемых фактов.
  • W-Fix.Core.Repair — планирование, адаптер двенадцати v2-фиксеров и ограниченное пакетное выполнение.
  • W-Fix.Core.Catalog — встроенный и подписанный онлайн-каталог известных проблем Windows.
  • W-Fix.Core.Pairing — TLS-транспорт, подписанный offline-обмен, парная диагностика и двухузловая saga.

UI не должен самостоятельно определять успешность системной команды. Источником истины является PowerShellExecutionResult, а итог многошагового фиксера вычисляется из результатов всех выполненных шагов.

Выполнение PowerShell

PowerShellEngine поддерживает два режима:

  1. Встроенный runspace PowerShell SDK — в том числе для Invoke-Command на удалённой машине.
  2. Внешний Windows PowerShell 5.1 — для Windows-модулей, несовместимых со встроенным Core-runspace.

Оба режима имеют общий десятиминутный таймаут по умолчанию. Пользовательская отмена пробрасывается как OperationCanceledException; таймаут возвращается как неуспешный PowerShellExecutionResult с TimedOut = true. Внешний процесс при этом завершается вместе с дочерними процессами.

Скрипты используют префиксы [OK], [INFO], [WARN] и [ERROR]. Даже если PowerShell-скрипт перехватил исключение, строка [ERROR] делает результат неуспешным. Служебный progress-CLIXML Windows PowerShell 5.1 в stderr не считается ошибкой.

Правила для фиксеров

  • Не сообщать Success, если обязательный шаг завершился неуспешно.
  • Не скрывать ошибку обязательного шага за успешным перезапуском Spooler.
  • Ограничивать удаление файлов только ресурсами подсистемы печати.
  • Каждый фиксер, изменяющий реестр, реализует ISystemStateChangingFixer и точно объявляет затрагиваемые значения, разделы и ACL. Новое изменение реестра без дополнения плана снимка считается дефектом.
  • Любой новый сценарий должен иметь тестируемую логику определения результата.

Снимок и откат системного состояния

Перед запуском изменяющего реестр фиксера SystemStateBackupService сохраняет только затрагиваемое состояние, а не экспортирует реестр целиком. Снимок содержит state.clixml, manifest.json, при необходимости .reg-файлы и автономный restore.ps1. Каталог создаётся на целевой машине в %ProgramData%\W-Fix\Backups\<время>_<фиксер>_<id>.

Ошибка снимка выводится как заметное предупреждение, но не превращает W-Fix в режим «только диагностики»: пользовательский ремонт продолжается. После успешного снимка команда «Откат» восстанавливает значения, удаляет значения, которых до исправления не существовало, возвращает ACL и импортирует сохранённые разделы. После восстановления перезапускается Print Spooler.

UI сохраняет выбранные фиксер, принтер и компьютер в начале операции. Поэтому смена выбора во время исполнения не может направить часть одного сценария на другую цель. Повторные загрузки принтеров, очередей и компьютеров отменяют устаревшие запросы, чтобы поздний ответ не перезаписывал более актуальное состояние.

Удалённый пользовательский контекст

PowerShell Remoting выполняет команды в сервисном контексте учётной записи администратора. Поэтому обычный HKCU: и вызовы WScript.Network из WinRM не относятся к рабочему столу пользователя, вошедшего на целевой ПК. Фиксеры принтера по умолчанию используют отдельный InteractiveUserPowerShellService:

  1. Через WinRM определяется интерактивный пользователь и его SID.
  2. Администратор сохраняет HKCU этого пользователя через Registry::HKEY_USERS\<SID>; restore-скрипт хранит уже разрешённый путь, поэтому откат возвращается в тот же профиль.
  3. На целевом ПК создаётся временная задача W-Fix-Interactive-<id> с типом входа Interactive и уровнем Limited. Пароль пользователя не запрашивается и не сохраняется; используется существующий токен сеанса.
  4. Пользовательская часть выполняет WScript.Network/PrintUI, пишет UTF-8 журнал и подтверждает фактически назначенный принтер. Код задачи и маркеры [ERROR] проверяются независимо.
  5. Административные действия — исправление ACL и перезапуск Spooler — остаются в WinRM-контексте.
  6. Временная задача и файлы удаляются в finally; при отмене выполняется дополнительная best-effort очистка. ExecutionTimeLimit ограничивает процесс даже при обрыве управляющего соединения.

Удалённый пользовательский фикс требует включённых WinRM и Task Scheduler, административного доступа и уже вошедшего пользователя. Если интерактивного сеанса нет, операция завершается явной ошибкой — W-Fix не сообщает ложный успех для HKCU администратора.

Конвейер Remote Center v3

App.xaml.cs является composition root. ViewModel больше не создают системные сервисы самостоятельно. Пользовательский поток имеет фиксированные границы:

  1. TargetDescriptor создаётся из ручного списка либо объекта Active Directory.
  2. IRemotePreflightService проверяет DNS, WinRM, административный токен, CIM, Spooler, Task Scheduler, интерактивного пользователя, pending reboot и место на системном диске. Ping остаётся справочным сигналом.
  3. IPrinterInventoryService собирает ОС/build/UBR, KB, очереди, задания, порты, драйверы, политики, Protected Print Mode и свежие ошибки PrintService.
  4. IDiagnosticRule создаёт DiagnosticFinding с доказательствами, уверенностью и локальными action ID.
  5. IRepairPlanner исключает действия, для которых цель не имеет требуемых capabilities.
  6. IRepairExecutor ограничивает параллелизм, создаёт снимок до мутации, выполняет шаг, повторно диагностирует цель и при неуспехе откатывает её независимо от остальных машин.
  7. IRunReportService сохраняет JSON/HTML в %ProgramData%\W-Fix\Runs\<RunId>.

Каталог известных проблем декларативен и не содержит скриптов. Даже корректно подписанная запись может выбрать только действие, уже скомпилированное и зарегистрированное в W-Fix.

Конвейер Pair Repair v3.1

IPairSessionTransport создаёт одноразовую TLS-сессию с временным ECDSA P-256 сертификатом. Клиент проверяет pin публичного ключа из .wfixpair, оба окна показывают вычисленный шестизначный код, а прикладные сообщения разрешаются только после двух подтверждений. Протокол принимает только версионированные DTO и встроенные идентификаторы pair.*; строки PowerShell и пароли через него не передаются.

IPairInventoryService проверяет только явно названного соседа. IPairRepairExecutor выполняет общий план как двухузловую saga: remote host-side шаги проходят через PairAgentCommandLoop, local client-side шаги выполняются локальным dispatcher. До каждого изменения создаётся checkpoint. Ошибка, отмена, timeout или потеря соединения вызывают обратный rollback и явный abort; commit отправляется только после повторной проверки всех шагов.

На хосте действует временное Firewall-правило для текущего EXE, точного порта, LocalSubnet и Private/Domain. В offline-режиме ECDSA-подписанный снимок защищён от изменения, но обе стороны ремонтируются раздельно, поэтому общий автоматический rollback недоступен. Пароль HOST\\User сохраняется напрямую в Windows Credential Manager.

Риски и подтверждения

  • Reversible — обычное подтверждение плана и обязательный снимок.
  • Disruptive — заметная маркировка (например, временная остановка Spooler).
  • Irreversible — дополнительный диалог; сюда относятся удаление заданий или пакетов драйверов.
  • Protected Print Mode не переключается автоматически: режим может удалить несовместимые очереди и драйверы.
  • Удаление Windows Update не является обычным действием; допускается только отдельным экспертным сценарием.