Странная любовь разработчика, или Как я перестал беспокоиться и полюбил Windows

· · Windows, Разработка Windows, Обратная совместимость, COM, ActiveX, QA, Философия

1. Сначала — вывод

Когда разрабатываешь приложения для Windows, поводов для беспокойства много.

Запустится ли это на данном ПК? Будет ли работать в окружении без прав администратора? Не сломается ли из-за разницы между 32-битной и 64-битной архитектурой? Пути на японском языке, длинные пути, сетевые диски, старые DLL, COM-компоненты, ActiveX, принтеры, последовательная связь, антивирусы, Windows Update.

Стоит только начать об этом думать, и беспокойству не будет конца.

Но в какой-то момент я начал смотреть на это иначе.

Возможно, это не недостаток, а свидетельство того, что Windows несла на себе реальный бизнес.

Windows — не безупречная утопия. Но она вобрала в себя программы, оборудование, рабочие процессы и человеческие привычки, которые десятилетиями работают на местах.

Именно этот хаос и делает Windows интересной — и именно поэтому, как разработчику, с ней стоит иметь дело.

2. Разработка приложений для Windows приносит много поводов для беспокойства

В разработке приложений для Windows недостаточно того, чтобы «код был правильным».

Он работает в локальном окружении. Он работает на компьютере разработчика. Он работает даже на тестовой виртуальной машине.

И всё же нет никакой гарантии, что он заработает на компьютере заказчика.

Например, случается следующее:

  • Не удаётся найти DLL
  • Не установлена среда выполнения Visual C++
  • Не совпадает версия .NET Framework
  • Не удаётся загрузить 32-битную DLL из 64-битного процесса
  • Повреждена регистрация COM
  • Путают 32-битную и 64-битную версии regsvr32.exe
  • Код, рассчитанный на фиксированный текущий каталог, ломается под управлением Планировщика заданий
  • Попытка записи в Program Files вызывает ошибку прав доступа
  • AppData\Roaming и AppData\Local используются не по назначению
  • Приложение падает при японских именах пользователей или японских именах папок
  • Не удаётся открыть файл из-за слишком длинного пути
  • Работает на подключённом сетевом диске, но не работает через UNC-путь
  • Интерфейс ломается в средах с высоким DPI
  • На нескольких мониторах смещаются расчёты координат
  • Результат печати меняется в зависимости от драйвера принтера
  • USB-устройства, камеры, измерительные приборы и последовательная связь не распознаются в зависимости от окружения
  • Антивирус блокирует часть обработки
  • После обновления Windows поведение меняется

Если перечислить всё это подряд, немного кружится голова.

Проблемы, которые в веб-приложении остаются заперты между браузером и сервером, в приложении для Windows расползаются по всему компьютеру. Файловая система, реестр, профили пользователей, принтеры, устройства, сеть, политики безопасности, установщики, среды выполнения.

Приложение не просто «работает поверх ОС» — оно оказывается помещённым внутрь реальной рабочей среды.

Именно поэтому разработка приложений для Windows сложна. Но списывать всё это на «Windows просто плохая» — значит, на мой взгляд, упускать суть.

На всё это опирается сложность реального мира.

3. Windows — ОС для реального дела

Windows — не операционная система, существующая только ради новейших технологий.

Заводы, больницы, госучреждения, школы, лаборатории, вещательные компании, поверочное оборудование, терминалы приёма посетителей, терминалы печати документов, склады, магазины, бухгалтерия, расчёт зарплаты, управление запасами. В подобных местах и сегодня работает бесчисленное множество компьютеров с Windows.

И там есть не только новейшие веб-сервисы.

Есть макросы Excel. Есть Access. Есть старые приложения на VB. Есть бизнес-приложения на .NET Framework. Есть резидентные приложения, написанные на C++. Есть COM-компоненты. Есть ActiveX. Есть подключения ODBC. Есть драйверы принтеров. Есть сканеры штрихкодов. Есть измерительные приборы с последовательной связью. Есть SDK от производителей оборудования.

Более того, ничто из этого не существует само по себе.

Люди работают с этим, печатают документы, меняют USB-устройства, кладут CSV-файлы в общие папки; ночью выполняются пакетные задания, а на следующее утро работа начинается заново. Всё это функционирует в рамках единого непрерывного процесса.

Windows — не просто основа для запуска приложений. Это платформа, которая вбирает в себя повседневную работу на местах, существующие активы, периферийные устройства и даже человеческие привычки.

Поэтому она иногда выглядит устаревшей. Иногда — сложной. Иногда возникает вопрос, зачем то или иное вообще до сих пор существует.

Но это также означает, что старое здесь никогда не выбрасывали небрежно.

4. Обратная совместимость как форма любви

Если бы целью было лишь сделать ОС красивой, было бы проще просто отрезать старые механизмы.

Удалить старые API. Удалить старые среды выполнения. Удалить старые экраны настроек. Считать, что старые приложения попросту больше не работают.

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

Но за этим стоят бизнес-приложения, которые перестанут работать. Оборудование, которое остановится. Предприятия, которые окажутся в затруднении.

Обратная совместимость Windows технически действительно доставляет хлопоты. Есть WOW64 — для запуска 32-битных приложений на 64-битной Windows. Реестр и DLL могут выглядеть по-разному для 32-битного и 64-битного кода. Есть структура, которая на первый взгляд сбивает с толку: C:\Windows\System32 — это 64-битная сторона, а C:\Windows\SysWOW64 — 32-битная.

COM тоже доставляет хлопоты. Просто разместить DLL недостаточно — иногда требуется регистрация. Регистрация выполняется на уровне пользователя или на уровне машины? Это 32-битный или 64-битный COM? Нужны ли права администратора?

С .NET Framework то же самое. Сегодня есть возможность использовать современный .NET, например .NET 8 или .NET 9. Но на местах до сих пор работают приложения на .NET Framework 4.x. Это не просто «устарело» — это значит, что данная версия много лет поддерживала реальный бизнес.

Обратная совместимость — не просто красивое понятие. Скорее, это тяжёлая ответственность.

Поддерживать работу старого — значит нести технический долг. Но в то же время это и своего рода честность: не останавливать работу тех, кто пользуется системой.

Я думаю, именно в этом и заключается то, за что Windows можно любить.

5. Windows — ОС, устроенная как геологические слои

В Windows технологии каждой эпохи наслаивались друг на друга, как геологические пласты.

Win32. COM. ActiveX. Windows Forms. WPF. .NET Framework. UWP. WinUI. Windows App SDK. MSIX. PowerShell. Windows Terminal. WSL.

У каждой была своя эпоха появления, свои сильные стороны и места, где её использовали.

Если смотреть только на новое, старое может показаться помехой. Но в разработке приложений для Windows часто встречаются ситуации, когда старые слои игнорировать нельзя.

Например, даже разрабатывая приложение на WPF, при печати можно столкнуться с проблемами GDI и драйверов принтеров. Даже написав код на C#, если SDK поставщика представляет собой нативную DLL, приходится иметь дело с P/Invoke и вопросами разрядности. Даже создавая новые экраны, порой приходится сохранять существующие COM-компоненты или интеграцию с Excel.

Windows — это не идеально выстроенный сад. Она скорее похожа на огромный город, который снова и снова достраивали и перестраивали.

В нём есть широкие проспекты. Есть подземные переходы. Есть старые переулки. Есть новые небоскрёбы.

В нём легко заблудиться. Но в глубине этих переулков и сегодня выполняется важная работа.

Разработчику нужно не суждение «старое — значит ненужное». Нужно умение понять, какой технологический слой поддерживает какую именно работу.

6. Превратить хлопоты в архитектуру

В заголовке сказано «перестать беспокоиться».

Но перестать беспокоиться — не значит стать небрежным. И не значит делать вид, что проблем не существует.

Перестать беспокоиться — значит превратить беспокойство в архитектуру.

Например, если тревожит вопрос запуска, проверку запуска превращают в дымовой тест (smoke test).

Start-Process .\MyApp.exe

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

Если тревожат DLL, проверяют зависимости. Если требуется среда выполнения Visual C++, решают, включать ли её в установщик или явно указать как обязательное условие. Если используются нативные DLL, не оставляют неопределённым соотношение x86, x64 и AnyCPU.

Если тревожит COM, оформляют порядок регистрации в виде инструкции и воспроизводят его с нуля на тестовом компьютере.

# Пример: регистрация 64-битной COM DLL
C:\Windows\System32\regsvr32.exe .\SomeComponent64.dll

# Пример: регистрация 32-битной COM DLL
C:\Windows\SysWOW64\regsvr32.exe .\SomeComponent32.dll

Если тревожат права доступа, избегают архитектур, работающих только с правами администратора. Пользовательские настройки размещают в AppData, а общесистемные — в ProgramData. Избегают решений, которые пишут логи в Program Files.

Если тревожат пути, включают в тесты японские символы, пробелы, длинные имена папок и UNC-пути.

New-Item -ItemType Directory -Path "C:\テスト 用\とても長いフォルダー名\さらに深いフォルダー" -Force

Если тревожит DPI, проверяют при 100%, 125%, 150% и 200%. На нескольких мониторах проверяют, не ломается ли всё при переходе между экранами с разным масштабом. Поскольку WinForms, WPF и WinUI по-разному подходят к поддержке DPI, проверку проводят отдельно для каждой технологии интерфейса.

Если тревожат память и хендлы, используют Application Verifier, WinDbg, ProcDump, Process Explorer и подобные инструменты. Если тревожат сбои, сохраняют журналы событий, дампы и логи приложения.

Get-EventLog -LogName Application -Newest 20

Либо, в более новых окружениях, журнал событий проверяют так:

Get-WinEvent -LogName Application -MaxEvents 20

Если тревожат дефекты, которые не воспроизводятся на месте, повышают детализацию логирования. «Произошла ошибка» — этого недостаточно. Какой файл пытались открыть? Какое устройство искали? От имени какого пользователя выполнялось действие? В какой путь пытались записать? Какую DLL не удалось загрузить?

Превратить беспокойство в нечто наблюдаемое.

В разработке приложений для Windows это чрезвычайно важно.

7. «Работает на компьютере заказчика» — конечная цель

То, что всё работает в среде разработки, важно. То, что тесты проходят в CI, важно. То, что всё работает на чистой виртуальной машине, важно.

Но для приложения на Windows последним препятствием всегда остаётся вопрос: «а работает ли это на компьютере заказчика?»

На этом компьютере уже что-то установлено. Возможно, там стоит старый драйвер принтера. Возможно, установлено собственное защитное ПО компании. Возможно, подключены сетевые диски. Возможно, у пользователя нет прав администратора. Возможно, есть причины, по которым Windows Update нельзя применить немедленно. Возможно, это среда без доступа в интернет.

Поэтому важен и способ распространения.

Достаточно ли просто передать exe-файл? Нужен ли MSI? ClickOnce? MSIX? Можно ли распространять через winget? Пойдёт ли это через внутреннюю систему распространения? Нужен ли автономный установщик? Требуется ли подпись кода? Не заблокирует ли приложение SmartScreen или антивирус?

Только когда, помимо самого приложения, учтены установка, обновление, удаление, сбор логов и процедуры восстановления, действительно приближаешься к состоянию «пригодно для реальной работы».

В разработке приложений для Windows программное обеспечение не заканчивается на поставке. Оно должно запускаться в среде заказчика — и сегодня, и завтра.

8. Почему я всё же люблю Windows

У Windows есть свои неудобные стороны. Это факт.

DLL. COM. Реестр. UAC. DPI. Принтеры. Среды выполнения. 32-бит / 64-бит. Сетевые диски. Длинные пути. Японоязычные среды. Защитное ПО. Windows Update.

Если перечислять неудобства, им нет конца.

Но большая часть этих хлопот происходит от того, что Windows очень долго несла на себе реальный бизнес.

Она не выбрасывает старые активы, но при этом впитывает новые технологии; у неё есть и графический интерфейс, и командная строка; она принимает и локальные приложения, и веб, и периферийные устройства, и рабочие терминалы, и личные компьютеры, и корпоративные.

Это не единая красивая философия.

Но это сила.

И для разработчика это стоит того, чтобы с этим работать.

Создавать программное обеспечение, которое надёжно работает на Windows, — это не просто вызывать API. Это значит читать ограничения реальной среды, понимать существующие активы, находить уязвимые места, тестировать, наблюдать и исправлять то, что нужно исправить.

Это неброская работа. Но она имеет ценность.

9. Заключение

В разработке приложений для Windows поводам для беспокойства нет конца.

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

Поэтому я не считаю Windows просто устаревшей операционной системой.

Это огромная, сложная, немного неуклюжая платформа, которая продолжает работать, находя компромисс с реальностью.

И создавать программное обеспечение, надёжно работающее на ней, до сих пор представляет большую ценность.

Перестать беспокоиться.

Но это не значит терять бдительность.

Превратить беспокойство в архитектуру, тестирование и наблюдение.

Так, шаг за шагом, я и полюбил Windows.

Ссылки по теме

Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.

Практическое руководство по Process Monitor (ProcMon) — как за 10 минут выяснить, почему «настройки не читаются» или возникает ACCESS DENIED

«Исправил конфигурационный файл, но изменения не применяются», «вчера всё работало, а сегодня приложение не запускается» — прежде чем лез...

Не оборачивайте HttpClient в using ── практика HTTP-взаимодействия в бизнес-приложениях на C# (паттерны создания, тайм-ауты, повторные попытки)

HttpClient в C#, создаваемый через using при каждом запросе, приводит к исчерпанию сокетов, а статический HttpClient перестаёт учитывать ...

Эти страницы показывают тему статьи в более широком контексте услуг и решений.

Статья напрямую связана со следующими услугами.

Об авторе

Страница с профилем автора статьи.

Го Комура

Представитель KomuraSoft LLC

Специализируется на разработке программного обеспечения для Windows, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.

Публичные ссылки

Вернуться в блог