# Анализ исходного кода HardwareFullReport

## Итоговая оценка

Присланный `HFR_new_avito.ps1` пригоден как рабочий прототип, но перед
публичной публикацией его стоило оптимизировать. Основная проблема была не
в скорости выполнения, а в достоверности результата, обработке ошибок,
безопасности HTML и удобстве пользователя.

## Существенные недостатки исходной редакции

### 1. Жёстко заданные диапазоны цены

Для всех процессоров использовался один диапазон, для всех видеокарт —
другой и так далее. Модель, возраст, состояние и регион на диапазон не
влияли. Такие значения могли создать ложное впечатление автоматической
рыночной оценки.

В оптимизированной версии статические диапазоны удалены. Программа прямо
сообщает, что цену нужно определять по актуальным объявлениям.

### 2. Регион фактически не использовался

Выбранный регион отображался в заголовке отчёта, но все ссылки вели на
`/all`. Теперь регион участвует в формировании URL поиска.

### 3. Ошибки скрывались

Глобальный `SilentlyContinue` мог приводить к пустым таблицам без понятного
объяснения. Теперь каждый класс CIM запрашивается отдельно, а ошибки
появляются в журнале.

### 4. Значения WMI вставлялись в HTML без экранирования

Название модели или драйвера добавлялось непосредственно в HTML. Теперь
динамические значения проходят HTML-кодирование.

### 5. Не проверялась папка сохранения

Теперь программа проверяет путь и возможность записи до начала длительной
операции.

### 6. Глобальное состояние и неиспользуемые переменные

Исходник использовал `$global:Inventory` и `$global:lastFolder`, причём
`lastFolder` не применялся. В новой редакции состояние ограничено областью
скрипта и используется для кнопок открытия отчёта.

### 7. Слишком широкое открытие вкладок

Раньше все вкладки открывались без подтверждения. Теперь показывается их
количество и запрашивается согласие.

### 8. Слабая фильтрация устройств

Добавлена фильтрация базовых и виртуальных видеоадаптеров, обработка пустых
названий и OEM-заглушек.

### 9. Фиксированное и плохо масштабируемое окно

Добавлены DPI-масштабирование, минимальный размер, изменение размера окна,
якоря элементов и таблица найденных компонентов.

### 10. Зависимость от System.Web

Для URL-кодирования больше не требуется загружать `System.Web`.
Используется встроенный `Uri.EscapeDataString`.

## Что оптимизировано

- функции разделены по ответственности;
- добавлен строгий режим PowerShell;
- добавлены локальные `try/catch`;
- исключены серийные номера;
- добавлен HTML-safe вывод;
- добавлены CSV с разделителем `;` и JSON;
- добавлено подтверждение открытия вкладок;
- добавлены ссылки по отдельным строкам;
- добавлена проверка прав администратора;
- добавлены журнал и статус;
- добавлены версия приложения и документация;
- сохранена совместимость с Windows PowerShell 5.1;
- отсутствуют внешние модули и сетевые API.

## Что остаётся ограничением

- сведения WMI зависят от BIOS, драйверов и производителя;
- `AdapterRAM` у некоторых видеокарт может быть неполным;
- тип памяти DDR не всегда доступен однозначно;
- программа не анализирует состояние накопителей SMART;
- программа не собирает цены и завершённые продажи автоматически;
- структура URL Авито может измениться;
- сбор CIM выполняется в UI-потоке, поэтому на проблемном WMI окно может
  временно отвечать медленнее.

## Дальнейшие улучшения

В следующих редакциях можно рассмотреть:

- фоновый поток с отменой сканирования;
- SMART и состояние накопителей;
- определение поколения DDR;
- ручное редактирование поискового запроса;
- сохранение пользовательских заметок и желаемой цены;
- экспорт обезличенного диагностического пакета;
- цифровую подпись PowerShell-скрипта.

## Исправление 1.1.1

Строка `"https://www.avito.ru/$regionPath?q=$encoded"` заставляла
PowerShell искать переменную `$regionPath?q`. При `Set-StrictMode` это
останавливало программу.

Исправленная реализация:

```powershell
return ('https://www.avito.ru/{0}?q={1}' -f $regionPath, $encoded)
```

Для защиты от повторения ошибки добавлен `-SelfTest`.


## Исправление 1.1.2

PowerShell разворачивает результат функции в pipeline. Когда CIM возвращал один `Win32_ComputerSystem`, переменная получала одиночный объект, а не массив. Под `Set-StrictMode` обращение к `.Count` завершалось ошибкой.

Исправление:

```powershell
$computerSystems = @(Get-CimDataSafe ...)
```

Такая нормализация применена ко всем шести CIM-запросам.


## Изменения 1.1.3

Слишком точная строка OEM-модели приводила к пустой выдаче Авито. Добавлена категория поиска `bytovaya_elektronika` и функция `Get-SimplifiedSearchQuery`. Непрозрачный параметр `context` не сохраняется в исходнике, поскольку он может быть связан с текущим состоянием сайта.

Для Яндекс Маркета используется адрес:

```text
https://market.yandex.ru/search?text=<запрос>
```


## Исправление интерфейса 1.1.4

Корневая форма имеет белый `ForeColor`. `DataGridView` наследовал его, но оставлял белый фон ячеек, поэтому текст был виден только при выделении. В 1.1.4 все цвета таблицы задаются явно.
