Как продлить работу старых приложений в Windows: режим совместимости, шимы и Compatibility Administrator

· Обновлено: · · Windows, Режим совместимости, Шимы, Совместимость приложений, Compatibility Administrator, Унаследованные активы, Разработка под Windows, Существующие системы

История изменений (1 обновлений, последнее 31 Aug 2026)

Журнал изменений этой статьи. Там, где версия до правки была заархивирована, она остаётся доступной для чтения по постоянной ссылке с DOI.

Русский текст переписан по текущему навыку технического перевода как полный перевод японского оригинала.
Первая публикация
Цитирование статьи(DOI (зарегистрированный архив): 10.5281/zenodo.22176312)

Приведённые ниже DOI относятся к ранее зарегистрированным архивным версиям, которые могут отличаться от текущего текста. Для ссылки на текущий текст используйте URL этой страницы.

Го Комура (2026). Как продлить работу старых приложений в Windows: режим совместимости, шимы и Compatibility Administrator. KomuraSoft LLC. https://comcomponent.com/ru/blog/windows-appcompat-shims-compatibility-mode/

DOI (зарегистрированный архив)
10.5281/zenodo.22176312
DOI (последняя зарегистрированная версия)
10.5281/zenodo.22176313

«Десятилетнее бизнес-приложение, исходников которого уже нет, не запускается на новом ПК с Windows 11. На вкладке «Совместимость» в свойствах файла включили режим Windows XP — и оно просто заработало. Что это на самом деле делает? Можно ли и дальше на это опираться?» Такие вопросы нам задают часто.

Когда приложение «оживает» от одной галочки, тревога как раз уместна. За кажущейся магией режима совместимости стоят шимы (shim) — небольшие фрагменты кода, которые встают между приложением и Windows API и отвечают «ложью». Чтобы держать в работе приложения многих поколений, Windows сама массово использует эту временную меру и открывает часть механизма пользователям и администраторам.

Если пользоваться этим, не понимая механизма, продление эксплуатации получается хрупким: «нельзя трогать, потому что непонятно, почему работает». Если механизм понятен, можно обоснованно решить, насколько далеко можно на это опираться, что его сломает и когда программу стоит переписать.

Понимание механизма меняет качество продления эксплуатацииИспользование режима совместимости без понимания механизма даёт хрупкое продление, к которому боятся прикасаться; понимание механизма позволяет обоснованно решить, насколько можно опираться, что сломает работу и когда программу стоит переписатьИспользовать, не понимая механизмХрупкое продление, к которому боятся прикасатьсяИспользовать, поняв механизмОбоснованные решенияНасколько можно опиратьсяЧто сломает работуКогда стоит переписать

Рис. 1: Даже при одном и том же продлении эксплуатации качество разное: тревога из-за непонимания механизма и решение на основе понимания.

Статья рассчитана на ИТ-специалистов малых и средних компаний и на разработчиков Windows-приложений, которые сопровождают старые бизнес-программы. По первичным материалам Microsoft Learn в ней собраны механизм шимов — то, чем на самом деле является режим совместимости, — возможности типичных шимов, организационное применение через Compatibility Administrator, пределы, которые шимы не закрывают, и выбор между продлением эксплуатации и миграцией.

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

  • Режим совместимости — это шимы (слой совместимости). Настройки вкладки «Совместимость» пишутся в HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers, и при запуске к процессу применяется набор шимов.12
  • Шим — это перехват API в пользовательском режиме за счёт подмены записей в таблице адресов импорта (IAT). Он встаёт на путь, по которому приложение вызывает Windows API, и возвращает те же ответы, что давала старая Windows. Саму ОС он не меняет.3
  • То, что умеет шим, совпадает с тем, что умеет правка кода в приложении. Он не обходит механизмы безопасности и не чинит проблемы режима ядра (драйверы устройств).3
  • Microsoft поставляет много готовых шимов — подмена версии, перенаправление путей к файлам, подмена реестра, подмена проверок администратора и другое. Их можно применять к отдельным EXE из Compatibility Administrator.4
  • Сама Windows по умолчанию использует шимы. Стандартная база совместимости ОС (.sdb) сопоставляется при каждом запуске, а PCA (Program Compatibility Assistant) может обнаружить проблему и автоматически применить настройку совместимости.15
  • «Отвечать так, будто это более старая Windows» теперь поведение по умолчанию. Начиная с Windows 8.1 GetVersionEx не возвращает версию ОС, которую приложение не объявило в манифесте. Режим совместимости — продолжение этого механизма.67
  • Шимы не работают с 16-разрядными приложениями, зависимостями от драйверов ядра и прямым доступом к оборудованию. В частности, 16-разрядные приложения на 64-разрядной Windows вообще не запускаются.8
  • Для приложений, которые «требуют администратора, но на самом деле не нуждаются», обычный ход — RunAsInvoker. __COMPAT_LAYER=RunAsInvoker подавляет запрос повышения и даёт приложению обычные права.9
  • Работа под шимом значит, что эксплуатацию можно продлить пока, но правильный путь — «сделать так, чтобы работало без шима». Если решили продлевать, зафиксируйте, какие шимы дают работу, и ведите это как материал для решения о переписывании.

На схеме сплошная линия обозначает отношение, которое выполняется всегда, а пунктирная — условное отношение (условия указаны в пояснении к каждому отношению на странице сведений). Полный список отношений (всего 16, с доказательствами и степенью уверенности) и определения основных понятий собраны на странице сведений карты знаний (на японском). Данные: JSON-LD / Turtle

2. Общая картина совместимости приложений — слои обратной совместимости, которые у Windows уже есть

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

Слой Что делает Типичная цель
Шимы (режим совместимости) Перехватывает вызовы API и подставляет те же ответы, что давала старая Windows Приложения, написанные в расчёте на более старую ОС, в целом
Виртуализация UAC (файлы / реестр) Перенаправляет записи без прав в HKLM\Software или Program Files в пользовательский VirtualStore 32-разрядные приложения, написанные в расчёте на права администратора
WOW64 Запускает 32-разрядные приложения как есть на 64-разрядной Windows (даёт 32-разрядные представления реестра и файловой системы) 32-разрядные приложения в целом
Виртуализация DPI Заставляет приложение без поддержки DPI рисовать при 96 DPI и показывает его, растягивая растр Старые приложения на дисплеях с высокой плотностью

Виртуализация UAC — переходная мера для интерактивных 32-разрядных процессов без манифеста, и сама Microsoft называет её «временной технологией, которую мы намерены убрать из будущей версии Windows».10 Реальный вред перенаправления Wow6432Node и VirtualStore и как с ним жить подробно разобраны в «Registry 32-bit/64-bit Redirection and Virtualization Pitfalls»; эта статья держит шимы в центре и упоминает остальные слои только по необходимости.

Где стоит виртуализация UACВиртуализация UAC — переходная мера для интерактивных 32-разрядных процессов без манифеста; она перенаправляет записи в пользовательский VirtualStore, но сама Microsoft называет её временной технологией, которую намерены убрать из будущей WindowsИнтерактивный 32-разрядный процесс без манифестаПрименяется виртуализация UACПеренаправлено в пользовательский VirtualStoreВременная технология, которую намерены убрать

Рис. 2: Виртуализация UAC — переходная мера для 32-разрядных процессов без манифеста, и на неё нельзя опираться постоянно.

Заметка о виртуализации DPI: приложение, не объявившее поддержку DPI, считается рисующим при 96 DPI (100%), и Windows растягивает растр для показа. Поэтому старые приложения выглядят «размытыми» на мониторе с высокой плотностью, а «Переопределить масштабирование при высоком DPI» на вкладке «Совместимость» — переключатель этого поведения виртуализации.11

Как работает виртуализация DPIПриложение, не объявившее поддержку DPI, считается рисующим при 96 DPI; Windows растягивает растр, поэтому оно выглядит размытым, а переопределение масштабирования при высоком DPI на вкладке «Совместимость» переключает это поведение виртуализацииПереключает виртуализациюПриложение, не объявляющее поддержку DPIСчитается рисующим при 96 DPIРастр растягивается для показаВыглядит размытым на мониторе с высокой плотностьюПереопределить масштабирование при высоком DPI

Рис. 3: Приложение без поддержки DPI считается 96 DPI и растягивается; переопределение на вкладке «Совместимость» — переключатель этой виртуализации.

3. Чем шим является на самом деле — перехват между API через подмену IAT

3.1. «Переводчик», который стоит между приложением и ОС

Исполняемый файл Windows (формат PE) вызывает API во внешних DLL через таблицу адресов импорта (IAT). Когда приложение вызывает GetVersionEx, оно лишь прыгает по адресу, записанному в IAT. Механизм шимов этим пользуется. При загрузке он переписывает запись IAT целевого API на адрес кода шима и встаёт между приложением и Windows. API, полученные динамически через GetProcAddress, обрабатываются перехватом самого GetProcAddress.3

Перехватив вызов, шим может вернуть старый номер версии на вопрос «какая сейчас версия ОС?» или перенаправить доступ к файлу в незаписываемое место куда-то ещё, а затем при необходимости вызвать настоящий API. Со стороны приложения кажется, что оно «работает на старой Windows»; со стороны ОС — что «работает корректно ведущее себя приложение». Шим — переводчик между ними.

Путь, по которому шим перехватывает вызов APIВызов API приложения идёт через IAT; перепись записи IAT на шим при загрузке позволяет шиму перехватить вызов, подставить тот же ответ, что давала старая Windows, и затем при необходимости вызвать настоящий APIВызов APIПри загрузке переписывается на шимЕсли нужноОбрабатываются перехватомПриложениеЗапись IATШим (переводчик)Настоящий Windows APIПодставляет тот же ответ, что давала старая WindowsВызовы через GetProcAddress

Рис. 4: Шим встаёт между приложением и Windows API. Переписывается IAT на стороне приложения; сама ОС не меняется.

Из этой конструкции следуют три важных свойства.3

  1. Шим выполняется как код на стороне приложения. Он не часть ОС, поэтому подчиняется тем же ограничениям безопасности, что и приложение. Шим не обходит механизмы безопасности ОС, и ослаблять настройки безопасности ради шима не нужно.
  2. То, что шим может исправить, может исправить и правка кода на стороне приложения. Шим — замена для случаев «нет исходников / не можем править»; он не сильнее правки кода.
  3. Только пользовательский режим. Проблемы совместимости драйверов устройств в режиме ядра шим не чинит.

3.2. База шимов (.sdb) и сопоставление

Таблица соответствия «какой шим применять к какому EXE» — это база шимов, двоичный файл с расширением .sdb. Целевые исполняемые файлы регистрируются в базе по атрибутам вроде имени файла, размера, контрольной суммы и версии (атрибуты сопоставления) и сопоставляются при старте процесса. Среди средств есть Appfix (шим), который внедряет перехват API, и Apphelp, который показывает сообщение «у этого приложения проблема совместимости». Набор нескольких шимов и флагов — это слой совместимости (режим совместимости).1

Это легко упустить: сопоставление идёт не только у приложений с включённым режимом совместимости, а при каждом запуске процесса. Windows поставляет стандартную базу ОС с исправлениями для тысяч известных приложений (файлы лежат в %WINDIR%\AppPatch), и на вашем ПК сегодня почти наверняка какое-то старое приложение стартует с прикреплённым шимом незаметно. Исправления совместимости от Microsoft поставляются как часть Windows и обновляются через Windows Update.3

Сопоставление базы шимов при старте процессаКаждый запуск процесса сопоставляется с базой шимов; если регистрация совпадает с атрибутами сопоставления, Appfix внедряет шим или Apphelp показывает сообщение, иначе процесс стартует как естьДаДаНетНабор шимов и флаговСтарт процессаСопоставить с базой шимов (.sdb)Имя файла, размер и т. д.Есть регистрация?Appfix: внедрить шимApphelp: сообщениеСтартовать как естьСлой совместимости (режим совместимости)

Рис. 5: Сопоставление идёт при каждом запуске процесса, не только у приложений с включённым режимом совместимости.

3.3. PCA — механизм, который применяет шимы автоматически

Другой путь, по которому шим может примениться без намерения администратора, — PCA (Program Compatibility Assistant). PCA следит за выполнением приложений и, обнаружив признаки известной проблемы совместимости, предлагает пользователю применить исправление или в некоторых случаях применяет настройку совместимости автоматически. Например, приложению, которое падает, вызывая код в освобождённой DLL, назначают PINDLL, а приложению, которое не может писать в защищённый файл Windows, — WRPMITIGATION.5

Как PCA автоматически применяет настройку совместимостиPCA следит за выполнением приложений и, обнаружив признаки известной проблемы совместимости, предлагает пользователю применить исправление или в некоторых случаях применяет настройку совместимости автоматическиДаЧерез предложениеНекоторые случаиНетВыполнение приложенияPCA следитПризнаки известной проблемы?Какой случай?Предложить применить исправлениеПрименить настройку совместимости автоматическиВыполнить как естьПример: PINDLL или WRPMITIGATION

Рис. 6: PCA следит за выполнением и, обнаружив признаки известной проблемы, предлагает исправление или применяет его автоматически.

Сущность ситуации «я ничего не настраивал, но в какой-то момент флажок режима совместимости оказался включён» во многих случаях именно это. Это не сбой и не промах; Windows ведёт себя как задумано.

4. Что умеют типичные шимы

Из готовых шимов, которые публикует Microsoft, выборка того, что реально часто встречается при продлении эксплуатации бизнес-приложения.4

Шим Что умеет (кратко)
WinXPSP3VersionLie и другие шимы семейства VersionLie Возвращать указанную более старую версию на запросы версии ОС (подмена версии)
CorrectFilePaths Перенаправлять доступ к незаписываемому или несуществующему пути файла в другое место
VirtualRegistry Перенаправлять или подменять чтение и запись реестра (включая подмену версии и имитацию несуществующих ключей)
ForceAdminAccess Временно возвращать True на проверку «вы член группы Administrators?»
RunAsAdmin / RunAsHighest / RunAsInvoker Снаружи дать уровень выполнения, равный requireAdministrator / highestAvailable / asInvoker в манифесте
WRPMitigation Подменять успех записи в защищённые файлы ОС и ключи реестра, чтобы приложение могло продолжить
EmulateGetDiskFreeSpace Сообщать свободное место на диске максимум 2 ГБ (для приложений, которые переполняются на больших дисках)
GlobalMemoryStatusLie Подменять сообщаемые значения состояния памяти (для приложений, которые не проходят проверку памяти при старте)
LoadLibraryRedirect Загружать текущую DLL Windows вместо старой системной DLL, которую приложение несёт с собой

Глядя на список, большинство шимов — это «ложь, которая возвращает ответ, которого ждёт старое приложение». Диск не больше 2 ГБ, ОС — XP, вы администратор: они воссоздают, только внутри этого процесса, картину мира эпохи, в которой приложение родилось.

Подмена версии стала «официальным поведением по умолчанию»

Подмена версии — не особый хак. Начиная с Windows 8.1 значение, которое возвращает GetVersionEx, зависит от манифеста приложения. Приложению без объявления <supportedOS> в разделе <compatibility> манифеста всегда дают эквивалент Windows 8 (6.2), какая бы ни была фактическая ОС. Если объявление есть, возвращается значение до самой высокой ОС среди объявленных (например, если объявлено до GUID Windows 8.1, вы получаете 6.3 даже на Windows 11).67

Итак, «версия Windows, которую видит приложение», решается в этих наложенных ступенях.

  1. Возвращается значение до ОС, объявленной в манифесте (6.2, если объявления нет)
  2. Если применён режим совместимости (шим семейства VersionLie), возвращается версия выбранной ОС6
Как решается версия ОС, которую видит приложениеЗначение, которое возвращает GetVersionEx, решается наличием объявления supportedOS в манифесте; без объявления возвращается эквивалент Windows 8 6.2, с объявлением — значение до самой высокой объявленной ОС, а если применён шим семейства VersionLie, оно перезаписывается версией выбранной ОСНетДаДаНетЗапрос GetVersionExЕсть объявление supportedOS?Возвращается эквивалент Windows 8 (6.2)Значение до самой высокой объявленной ОСПрименён шим семейства VersionLie?Значение ОС, выбранное в режиме совместимостиЗначение возвращается как есть

Рис. 7: Версия Windows, которую видит приложение, решается наложенными ступенями манифеста и шимов.

Если внутреннее приложение «ветвится по версии ОС и, путано, считается восьмёркой, хотя это Windows 11», сначала подозревайте объявление supportedOS в манифесте. Наоборот, старое приложение, которое отказывается стартовать из-за проверки версии, с высокой вероятностью можно провести шимом VersionLie. Во многих случаях оно смотрит только на номер версии, а фактическое поведение на более новой ОС нормально.

Два симптома из-за версии и как с ними бытьЕсли внутреннее приложение считается восьмёркой, хотя это Windows 11, подозревайте объявление supportedOS в манифесте; старое приложение, которое отказывается стартовать из-за проверки версии, с высокой вероятностью можно провести шимом VersionLieСчитается восьмёркой, хотя это Windows 11Подозревать объявление supportedOSСтарт отказан из-за проверки версииПопробовать пройти VersionLieФактическое поведение на более новой ОС часто нормально

Рис. 8: Если суждение устарело — подозревайте манифест; если старт отказан — подозревайте VersionLie.

5. Что делает флажок режима совместимости

Настройки «Свойства → вкладка “Совместимость”» хранятся в ключе реестра AppCompatFlags\Layers. Настройки совместимости приложений DXGI и подобные используют тот же ключ как место указания слоя совместимости.2 Посмотрим на деле.

reg query "HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"

Для EXE, на котором на вкладке «Совместимость» заданы «Windows XP (Service Pack 3)», «Запускать эту программу от имени администратора» и «Переопределить масштабирование при высоком DPI», вы увидите значение вроде следующего.

HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers
    C:\LegacyApp\Gyomu.exe    REG_SZ    ~ WINXPSP3 RUNASADMIN HIGHDPIAWARE

Типичные соответствия пунктов флажка и значений (проверено на Windows 11; имена пунктов и значения могут меняться по версии ОС).

Пункт вкладки «Совместимость» Записанное значение (пример) Что это на самом деле
Режим совместимости: Windows XP (Service Pack 3) WINXPSP3 Слой совместимости, который связывает подмену версии и несколько других шимов
Пониженный цветовой режим (8 бит / 256 цветов) 256COLOR Ослабление для старого цветового режима
Запускать в разрешении экрана 640 × 480 640X480 Запускать в низком разрешении
Отключить оптимизации полноэкранного режима DISABLEDXMAXIMIZEDWINDOWEDMODE Отключить оптимизации рисования в полноэкранном режиме
Переопределить масштабирование при высоком DPI (Приложение) HIGHDPIAWARE Остановить виртуализацию DPI (растяжение растра)11
Запускать эту программу от имени администратора RUNASADMIN Запрашивать повышение при старте

Три пункта стоит запомнить.

  • «Запускать эту программу от имени администратора» пишется в то же место. Режим совместимости и флаг повышения живут вместе в одном ключе Layers, и отсюда путаница «я включил режим совместимости, и повышение пришло / пропало». Прямой взгляд на значение разделяет их.
  • То, что записано в HKCU, — «настройка этого пользователя». Если задать через «Изменить параметры для всех пользователей» вкладки, пишется в одноимённый ключ на стороне HKLM и действует на всех пользователей. При подготовке образов для тиражирования сознавайте, на какую сторону пишете.
  • Флажок — только вход в готовые слои. Вкладка даёт выбрать лишь типичные слои; отдельные шимы выбрать и скомбинировать нельзя. Это делает Compatibility Administrator в следующей главе.
Путь от настройки вкладки «Совместимость» до действияНастройки вкладки «Совместимость» хранятся как путь EXE и значение в ключе AppCompatFlags Layers; при следующем старте этого EXE загрузчик читает значение и применяет соответствующий слой совместимости к процессуЗадать на вкладке «Совместимость»Сохранить путь EXE и значение в ключе LayersСледующий старт EXEЗагрузчик читает значениеПрименить слой совместимости к процессуHKCU только этот пользовательHKLM действует на всех пользователей

Рис. 9: Флажок на деле — запись в ключ Layers, а применение происходит при следующем старте.

6. Compatibility Administrator на практике — собрать и развернуть пользовательский .sdb

6.1. Как получить и что учесть

Compatibility Administrator — инструмент из Windows ADK (Windows Assessment and Deployment Kit).12 После установки есть и 32-, и 64-разрядные издания, и для 32-разрядных приложений нужно 32-разрядное издание, для 64-разрядных — 64-разрядное.13

Есть ещё важный момент. Если запускать Compatibility Administrator с повышением (от имени администратора) и тестировать, виртуализация UAC и перенаправление ведут себя не как у реального пользователя, и можно ошибочно решить, что «исправлено». Всегда подтверждайте эффект исправления той же учётной записью и теми же правами, что у реального пользователя.4

Два момента, которые учесть при работе с Compatibility AdministratorИспользуйте 32-разрядное издание для 32-разрядных приложений и 64-разрядное для 64-разрядных и подтверждайте эффект исправления той же учётной записью и теми же правами, что у реального пользователя, а не в повышенном состоянии32-разрядное приложениеИспользовать 32-разрядное издание64-разрядное приложениеИспользовать 64-разрядное изданиеТест в повышенном состоянииМожно ошибочно оценить исправлениеТест с правами реального пользователяПодтвердить эффект

Рис. 10: Выбор 32- или 64-разрядного издания и проверка теми же правами, что у реального пользователя, — то, что важно учесть с самого начала.

6.2. Порядок сборки пользовательской базы совместимости

Схема такова.14

  1. В левой панели Compatibility Administrator создайте новую базу в «Custom Databases» и выберите «Create New» → «Application Fix»
  2. Введите имя приложения и имя поставщика и укажите целевой EXE
  3. Выберите применяемый режим совместимости (слой) — сначала попробовать набор вроде «совместимость с Windows XP» короче
  4. При необходимости добавьте отдельные исправления совместимости (шимы) — можно сузить до минимума вроде только VersionLie или только CorrectFilePaths
  5. Подтвердите условия сопоставления (размер файла, контрольная сумма, версия и так далее) и сохраните

Условия сопоставления — ключ к «применять это только к этому EXE». Базовых условий по умолчанию обычно хватает, но мы рекомендуем оставить условие, которое идентифицирует версию приложения. Это предотвращает аварию, когда старая ложь продолжает применяться к новой версии, когда поставщик позже выпустит исправленное издание.1415

Порядок сборки пользовательской базы совместимостиСоздайте Application Fix в новой базе, укажите имя приложения и целевой EXE, сначала попробуйте набор режима совместимости, затем при необходимости сузьте до отдельных шимов, подтвердите условия сопоставления и сохранитеСоздать новую базуВыбрать Application FixУказать имя приложения и целевой EXEПопробовать набор режима совместимостиПри необходимости сузить до отдельных шимовПодтвердить условия сопоставления и сохранитьОставить условие, которое идентифицирует версию

Рис. 11: Для Application Fix сначала пробуйте набор режима совместимости, сужайте до минимума и ограничивайте цель условиями сопоставления.

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

6.3. Развёртывание через sdbinst

Команда, которая применяет пользовательский .sdb на каждом ПК, — sdbinst.exe (нужны права администратора).15

:: Установка (-q — тихий режим без подтверждения)
sdbinst -q "C:\Deploy\MyCorpFixes.sdb"

:: Удаление (по файлу)
sdbinst -q -u "C:\Deploy\MyCorpFixes.sdb"

:: Удаление (по GUID базы)
sdbinst -q -u -g {GUID базы данных}

Как стратегию организационного развёртывания Microsoft рекомендует свести в одну общефирменную (или ведомственную) пользовательскую базу и вести её централизованно, а не возить отдельный .sdb с установщиком каждого приложения. Чем больше исправлений, тем проще обновлять и заново распространять одну базу, чем раздавать много однострочных. У пользовательской базы свой GUID, и установка новой версии с тем же GUID автоматически заменяет старую, поэтому операции обновления тоже остаются простыми. Саму доставку положите на существующий путь, который может идти с правами администратора, например упаковку в MSI или сценарий автозагрузки.15

Путь от создания пользовательского .sdb до развёртыванияСоздайте пользовательскую базу совместимости в Compatibility Administrator, протестируйте на проверочной машине, примените на каждом ПК через sdbinst и при обновлении установите новую версию с тем же GUID, чтобы старая заменилась автоматическиСоздать в Compatibility AdministratorПротестировать на проверочной машинеПрименить на каждом ПК через sdbinstУстановить новую версию с тем же GUIDСтарая версия заменяется автоматическиРегистрируется в «Программы и компоненты»

Рис. 12: Пользовательский .sdb разворачивается через создание, проверку и доставку sdbinst, а обновления ведутся по GUID.

Установленная пользовательская база регистрируется как пункт в «Программы и компоненты (Установленные приложения)», поэтому инвентарь и удаление можно подтверждать и оттуда. Какие ПК имеют какой .sdb — сведения для учётного журнала активов.

7. Случаи, когда не работает, и пределы

Шимы — не серебряная пуля. По конструкции они не работают в следующих случаях.

  • Проблемы режима ядра. Шим выполняется внутри процесса пользовательского режима, поэтому несовместимость драйвера устройства не исправить. Если драйвер старого измерительного прибора, USB-донгла или принтера не поддерживает Windows 11, что бы вы ни применили на стороне приложения, это не решит. Код в ядре, например части антивируса, то же самое.3
  • 16-разрядные приложения. 64-разрядная Windows не поддерживает выполнение 16-разрядных приложений. У дескриптора в 64-разрядной Windows 32 значащих бита, и его нельзя усечь так, чтобы передать 16-разрядному приложению, поэтому старт падает с ERROR_BAD_EXE_FORMAT.8 Даже если само приложение 32-разрядное, у пакетов той эпохи бывает 16-разрядная заглушка установщика, и это выглядит как «приложение бы работало, но установить нельзя».
  • Прямой доступ к оборудованию. Промышленные приложения, которые предполагают прямое обращение к портам ввода-вывода или физической памяти, в современном Windows из пользовательского режима на это не имеют права, и это за пределами того, что шим может подменить.
  • Обход механизмов безопасности. Поскольку шим идёт под теми же ограничениями безопасности, что и приложение, он не делает возможным «то, чего нельзя из-за нехватки прав». ForceAdminAccess и WRPMitigation лишь подменяют успех проверки или записи, чтобы приложение могло продолжить; они не переписывают защищённый ресурс по-настоящему.34
  • Приложения, которые проверяют свою целостность. Приложения со старой защитой от копирования или обнаружением подделки могут счесть сам перехват API аномалией и перестать работать.
Случаи, когда шим не работаетШим выполняется внутри процесса пользовательского режима, поэтому не работает на проблемах драйверов режима ядра, 16-разрядных приложениях, прямом доступе к оборудованию и обходе механизмов безопасностиНе работаетНе работаетНе работаетНе работаетШим (выполняется в пользовательском режиме)Драйвер ядра16-разрядное приложениеПрямой доступ к оборудованиюОбход механизмов безопасностиНа 64 разрядах падает уже сам стартЛишь подменяет успех, чтобы приложение продолжило

Рис. 13: Шим только в пользовательском режиме и не достаёт до ядра, 16-разрядных приложений, прямого доступа к оборудованию и обхода безопасности.

И существенный предел, общий для каждого шима: это временная мера. Шим — ложь, заточенная под конкретное использование конкретного API, и если реализация на стороне ОС меняется, предпосылка рушится. Шимы от Microsoft поддерживаются как часть Windows через Windows Update,3 но сопровождать ложь, которую вы применили пользовательской базой, — работа вашей организации. Заложите в бюджет, как стоимость продления эксплуатации, операцию, которая проверяет «список приложений, которых держат живыми шимы» при каждом обновлении функций.

Шимы как временная мера и кто отвечает за сопровождениеШим — ложь, заточенная под конкретное использование API, и предпосылка рушится, если меняется реализация на стороне ОС; шимы Microsoft поддерживаются через Windows Update, но сопровождать ложь, применённую пользовательской базой, — работа организации, а проверка при каждом обновлении функций — стоимость продления эксплуатацииШим = временная ложьИзменение ОС ломаетШимы MicrosoftЧерез Windows UpdateЛожь пользовательской базыОрганизация сопровождаетПроверка каждого обновления — стоимость продления эксплуатации

Рис. 14: Ответственность за сопровождение лжи шима делится между набором от Microsoft и пользовательским набором вашей организации.

8. Практическая ценность RunAsInvoker — подавить только запрос повышения

Среди шимов чаще всего в повседневной ИТ-работе встречается RunAsInvoker.

Некоторые старые бизнес-приложения объявляют requireAdministrator в манифесте или ошибочно детектируются как установщик по имени или содержимому EXE и запрашивают повышение UAC при каждом старте. Многие из них, однако, просят администратора лишь по инерции эпохи XP и не используют права администратора. Применение шима RunAsInvoker перезаписывает и детекцию установщика, и манифест, и приложение стартует с токеном, унаследованным от родительского процесса (= обычные права пользователя).9

Как RunAsInvoker подавляет запрос повышенияОбъявление requireAdministrator в манифесте или ошибочная детекция как установщик вызывает запрос повышения UAC при старте, но применение RunAsInvoker перезаписывает оба и приложение стартует с токеном, унаследованным от родителяНетДаОбъявление requireAdministratorПрименён RunAsInvoker?Ошибочно детектировано как установщикЗапрос повышения UAC при каждом стартеСтартует с токеном родителяРабота, которой действительно нужен администратор, падает внутри приложения

Рис. 15: RunAsInvoker перезаписывает только причину запроса повышения; права не увеличиваются.

Даже не собирая .sdb в Compatibility Administrator, тот же слой можно временно применить переменной окружения __COMPAT_LAYER.

:: Применить RunAsInvoker к дочерним процессам, запущенным из этой командной строки
set __COMPAT_LAYER=RunAsInvoker
start "" "C:\LegacyApp\Gyomu.exe"
# В PowerShell
$env:__COMPAT_LAYER = 'RunAsInvoker'
Start-Process 'C:\LegacyApp\Gyomu.exe'

Если превратить эти две строки в пакетный файл и раздать как ярлык, можно не выдавать локальные права администратора обычным пользователям, и ИТ больше не вызывают каждый раз из-за пароля UAC. Это приём совместимости, который укрепляет защиту, в духе наименьших привилегий.

Эффект раздачи пакета RunAsInvokerРаздача двухстрочного пакета, который задаёт RunAsInvoker, как ярлыка значит, что можно не выдавать локальные права администратора обычным пользователям, ИТ не вызывают из-за пароля UAC, а эксплуатация следует наименьшим привилегиямРаздать двухстрочный пакетМожно не выдавать права администратораИТ не вызывают из-за UACЭксплуатация, которая следует наименьшим привилегиям

Рис. 16: Одна раздача пакета может сократить и выдачу прав администратора, и вызовы из-за UAC.

Ограничения тоже стоит назвать прямо.

  • Права не увеличиваются. Работа, которой действительно нужны права администратора (запись в HKLM, обновления под Program Files и так далее), даст ошибку внутри приложения или, если условия выполнены, будет перенаправлена в VirtualStore виртуализацией UAC.10 Если сохранение настроек вдруг «перестало работать», подозревайте виртуализацию.
  • Метод переменной окружения действует только на дочерние процессы. Для постоянного применения надёжны прямая настройка в ключе Layers (у RUNASINVOKER нет пункта на вкладке) или развёртывание через .sdb.
  • Исправить место записи — правильный путь. Если приложение можно менять, перенесите файл настроек под %APPDATA% и объявите asInvoker в манифесте — это корректная форма.9
Временное и постоянное применение RunAsInvokerПрименение через переменную окружения COMPAT_LAYER действует только на дочерние процессы, запущенные оттуда; для постоянного применения используйте прямую настройку в ключе Layers или развёртывание через .sdbЗадать через переменную окруженияДействует только на дочерние процессыВременное применениеЗадать напрямую в ключе LayersПостоянное применениеРазвернуть через sdb

Рис. 17: Метод переменной окружения — временное применение, ограниченное дочерними процессами; постоянным его делают ключ Layers или .sdb.

9. Решение между продлением эксплуатации и миграцией — о чём думать после того, как заработало под шимом

Момент, когда заработало под шимом, — облегчение, но важно не останавливать мысль там. Работа под шимом значит лишь, что случайно подошёл механизм, который Windows уже подготовила. Оси решения — таблицей.

Ось решения Условия в пользу продления эксплуатации (шим) Условия в пользу миграции / переписывания
Оставшийся срок использования Планируется вывести вместе с бизнесом за 1–2 года Предполагается использовать ещё 5 лет и больше
Исходный код Нет (поставщик исчез или потерян) Есть, или актив можно восстановить
Глубина зависимости Только проблема совместимости API в пользовательском режиме Зависит от драйвера, 16 бит или специализированного оборудования
Альтернативы Нет коробочного продукта или новой версии Целевой продукт и технология ясны
Влияние при отказе Бизнес может идти по запасной процедуре Ядро бизнеса бьёт напрямую
Возможности проверки Можно подтверждать поведение при каждом обновлении функций Нет ресурса на проверки, и сопровождение легко замирает

Если решили продлевать эксплуатацию, внесите в работу следующие три пункта комплектом.

  1. Зафиксировать. Какой EXE, какой шим/слой и почему. Оставьте значение ключа Layers и GUID .sdb в учётном журнале. «Никто не знает, почему работает» — самый большой долг следующей смене. Это та же установка на сохранение, что в «Если вам досталась система без исходного кода и без документации — практический план, как сопровождать её, не останавливая работу».
  2. Проверять. Включите старт и основные операции приложений, которых держат живыми шимы, в пункты проверки обновления функций Windows. Свяжите и с планом замены ОС (Practical Options After Windows 10 End of Support).
  3. Поставить срок. Решите конец продления — «до следующего обновления ядра системы», «до марта 2028» — и параллельно ведите рассмотрение миграции.
Комплект эксплуатации из трёх пунктов после решения продлеватьЗафиксируйте в учётном журнале, какой шим даёт работу, проверяйте поведение приложений, которых держат живыми шимы, при каждом обновлении функций, поставьте срок конца продления и параллельно ведите рассмотрение миграцииРешить продлевать эксплуатациюЗафиксировать: какой шим даёт работу, в учётный журналПроверять: подтверждать поведение при каждом обновлении функцийСрок: решить конец продленияПараллельно вести рассмотрение миграции

Рис. 18: Продление эксплуатации ведётся комплектом из трёх пунктов — зафиксировать, проверять и срок, включая параллельное рассмотрение миграции.

На стороне миграции стандартные варианты меняются с технологией приложения. Для VB6 — тройной выбор полной переписки, автоматического преобразования и поэтапной миграции, собранный в «До каких пор будут работать приложения VB6 ── состояние поддержки среды выполнения и практичный путь миграции на .NET»; для зависимости от ActiveX/OCX — таблица решений оставить / обернуть / заменить в «Как сегодня поступать с ActiveX / OCX - таблица решений: оставить, обернуть или заменить». Здоровое место шима — покупать время, чтобы период рассмотрения и подготовки этого проекта миграции шёл безопасно.

Варианты на стороне миграции и где стоит шимСтандартные варианты миграции меняются с технологией приложения; для VB6 тройной выбор — переписать, автоматически преобразовать и поэтапная миграция, для зависимости ActiveX действует таблица оставить / обернуть / заменить, а шим стоит как покупка времени на рассмотрение и подготовку проекта миграцииVB6Зависимость ActiveXПокупает время на рассмотрение и подготовкуКакая технология приложения?Переписать, автоматически преобразовать или поэтапная миграцияОставить, обернуть или заменитьПродление эксплуатации через шим

Рис. 19: Стандартные варианты миграции решает технология приложения, а шим стоит как покупка времени на это рассмотрение.

10. Итог

  • Режим совместимости — это шимы. Настройки вкладки «Совместимость» пишутся в ключ AppCompatFlags\Layers и при старте внедряются в процесс как перехват API через подмену IAT.
  • Шимы — набор «лжи, которая возвращает ответ, которого ждёт старое приложение». Готовые шимы для подмены версии, перенаправления путей, подмены реестра, подмены проверок администратора и подобного предоставляются.
  • Сама Windows по умолчанию использует много шимов, и PCA может применять их автоматически. Опираться на режим совместимости само по себе разумный выбор, который едет на официальном механизме ОС.
  • Есть принципиальный предел только пользовательского режима и без обхода безопасности, и драйверы ядра, 16-разрядные приложения и прямой доступ к оборудованию спасти нельзя.
  • Организационное развёртывание — собрать пользовательский .sdb в Compatibility Administrator (Windows ADK) и доставить через sdbinst. Выбор 32-/64-разрядного издания, тест с реальной учётной записью пользователя и ведение обновлений по GUID — практические точки.
  • Приложения, которые «требуют администратора, но на самом деле не нуждаются», можно опустить до обычных прав через __COMPAT_LAYER=RunAsInvoker. Это защитный приём, который глушит запрос повышения, а не раздаёт права.
  • Работа под шимом — продление эксплуатации, не решение. Зафиксировать, что даёт работу, проверять при каждом обновлении функций и поставить срок, чтобы миграция шла параллельно, — этот комплект из трёх пунктов входит в решение «опираться на режим совместимости».

В следующий раз, когда старое приложение заработает после галочки режима совместимости, спросите снова. «Благодаря какой лжи это приложение работает? Как долго эта ложь ещё будет действовать?» Если можете ответить, продление эксплуатации — вполне состоятельная стратегия.

Похожие статьи

Смежные области консультирования

Компания KomuraSoft LLC занимается исследованием поведения старых бизнес-приложений без исходного кода и проектированием продления их эксплуатации (выбор шимов и режима совместимости, сборка и развёртывание пользовательского .sdb), проверкой совместимости существующих приложений для миграции на Windows 11 и планированием переписывания или миграции, идущих параллельно с продлением. Консультация уже со стадии «заработало в режиме совместимости, но нормально ли так оставлять?» уместна.

Справочные ссылки

  1. Microsoft Learn, Application Compatibility Database. О том, что инфраструктура совместимости ведёт проблемы и средства в базе формата .sdb, сопоставление по атрибутам исполняемого файла, Apphelp (показ сообщения) и Appfix (перехват API через шим), а также слой совместимости (режим), который связывает несколько шимов и флагов. ↩ ↩2 ↩3

  2. Microsoft Learn, DXGI overview. О том, что настройки совместимости приложений хранятся в ключе реестра HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers (на примере настроек совместимости DXGI). ↩ ↩2

  3. Microsoft Learn, Understanding and Using Compatibility Fixes. О том, что исправление совместимости (шим) перенаправляет вызовы API, переписывая IAT (таблицу адресов импорта), что динамическая компоновка обрабатывается перехватом GetProcAddress, что шим подчиняется тем же ограничениям безопасности, что и приложение, и не обходит механизмы безопасности ОС, что он только в пользовательском режиме и не чинит проблемы драйверов, что исправление, возможное шимом, возможно и правкой кода, сценарии вроде приложений, у которых кончилась поддержка поставщика, и что исправления совместимости от Microsoft поставляются как часть Windows и обновляются через Windows Update. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8

  4. Microsoft Learn, Compatibility Fixes for Windows 10, Windows 8, Windows 7, and Windows Vista. Список и описание известных исправлений совместимости, включая CorrectFilePaths, VirtualRegistry, ForceAdminAccess, RunAsAdmin/RunAsHighest/RunAsInvoker, WRPMitigation, EmulateGetDiskFreeSpace, GlobalMemoryStatusLie, LoadLibraryRedirect и семейство VersionLie; выбор 32-/64-разрядного издания Compatibility Administrator; и что тест в повышенном состоянии значит, что виртуализация и перенаправление ведут себя не как ожидается, поэтому проверять нужно реальной учётной записью пользователя. ↩ ↩2 ↩3 ↩4

  5. Microsoft Learn, Program Compatibility Assistant scenarios for Windows 8. О том, что PCA следит за выполнением приложений, обнаруживает признаки известной проблемы совместимости и предлагает применить рекомендованное исправление или применяет его автоматически (PINDLL, DISABLEUSERCALLBACKEXCEPTION, VIRTUALIZEDELETE, WRPMITIGATION и подобные), а также применение исправления с вкладки «Совместимость» и Program Compatibility Troubleshooter. ↩ ↩2

  6. Microsoft Learn, GetVersionExW function. О том, что начиная с Windows 8.1 значение, которое возвращает GetVersionEx, зависит от манифеста, что приложению без манифеста для Windows 8.1/10 дают значение версии Windows 8 (6.2), и что при включённом режиме совместимости сообщается версия выбранной ОС. ↩ ↩2 ↩3

  7. Microsoft Learn, Targeting your application for Windows. Как объявлять GUID поддерживаемых ОС элементом supportedOS в разделе compatibility манифеста приложения, поведение без объявления и то, что интерактивное 32-разрядное x86-приложение без trustInfo попадает под виртуализацию файлов UAC (перенаправление записи в VirtualStore). ↩ ↩2

  8. Microsoft Learn, Running 32-bit Applications. О том, что WOW64 — слой эмуляции, который запускает 32-разрядные приложения на 64-разрядной Windows и изолирует столкновения файлов и реестра, и что 64-разрядная Windows не поддерживает выполнение 16-разрядных приложений, а старт падает с ERROR_BAD_EXE_FORMAT из-за числа значащих бит в дескрипторе. ↩ ↩2

  9. Microsoft Learn, Using the RunAsInvoker Fix. О том, что исправление совместимости RunAsInvoker стартует приложение с токеном, унаследованным от родительского процесса, что оно перезаписывает и детекцию установщика, и обработку манифеста, что применяется как флаг загрузчика без перехвата API, и что когда код можно править, правильное исправление — объявить asInvoker в манифесте. ↩ ↩2 ↩3

  10. Microsoft Learn, Registry Virtualization. О том, что виртуализация реестра — технология совместимости, которая прозрачно перенаправляет глобальные записи в HKLM\Software в пользовательский VirtualStore, что в охвате только интерактивные 32-разрядные процессы и она отключена для процессов, которые задают requestedExecutionLevel в манифесте, и для 64-разрядных процессов, и что её ставят как временную технологию, предназначенную к удалению из будущей Windows. ↩ ↩2

  11. Microsoft Learn, High DPI Desktop Application Development on Windows. О том, что приложение без поддержки DPI считается рисующим при фиксированных 96 DPI и на дисплее с высокой плотностью Windows растягивает растр, поэтому оно выглядит размытым, а также различия режимов осведомлённости о DPI (Unaware/System/Per-Monitor). ↩ ↩2

  12. Microsoft Learn, Download and install the Windows ADK. О том, что Windows ADK включает Compatibility Administrator и Standard User Analyzer, и как думать о выборе версии ADK и как скачивать и устанавливать. ↩

  13. Microsoft Learn, Compatibility Administrator User’s Guide. О том, что Compatibility Administrator даёт применение исправлений совместимости, режимов совместимости и сообщений AppHelp и создание пользовательской базы, и что ставятся и 32-, и 64-разрядные издания и для 32-разрядных приложений нужно 32-разрядное издание, для 64-разрядных — 64-разрядное. ↩

  14. Microsoft Learn, Creating a Custom Compatibility Fix in Compatibility Administrator. О том, что исправление совместимости (раньше называлось шимом) — маленький кусок кода, который перехватывает вызов API; порядок создания Application Fix в пользовательской базе (указать имя приложения, поставщика и целевой EXE, выбрать режим совместимости, выбрать дополнительные шимы, задать условия сопоставления); и что следует оставить условия, которые верно идентифицируют приложение, сужая сведения сопоставления. ↩ ↩2

  15. Microsoft Learn, Compatibility Fix Database Management Strategies and Deployment. О том, что централизованно ведомая база рекомендуется как стратегия управления пользовательской базой совместимости, что исправление совместимости должно включать проверку версии (условие сопоставления), чтобы не применяться к новой версии, локальная установка через Sdbinst.exe (параметры -q, -u, -g), что установка новой версии с тем же GUID базы автоматически удаляет старую, и способы развёртывания через MSI или сценарий. ↩ ↩2 ↩3

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

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

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

Частые вопросы

Вопросы, которые часто возникают при консультациях по теме статьи.

Если после включения режима совместимости приложение заработало, можно ли так и пользоваться?
Для ближайшей непрерывности бизнеса — да. Режим совместимости — это перехват API в пользовательском режиме, который называют шимом; механизм официально предусмотрен в ОС. Шим всё же временная мера: приложение работает без исправления кода, и другое обновление ОС может сменить предпосылки и снова его сломать. Зафиксируйте в учётном журнале, что программа идёт в режиме совместимости, и ведите эту запись вместе с решением: переписывать приложение или продлевать эксплуатацию планомерно.
Что на самом деле делает флажок режима совместимости?
Когда вы сохраняете настройки на вкладке «Совместимость» в свойствах файла, Windows записывает путь целевого EXE и значение вроде "WINXPSP3" или "HIGHDPIAWARE" в ключ HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers. При следующем запуске этого EXE загрузчик Windows читает значение и применяет к процессу соответствующий слой совместимости (набор шимов). Режим Windows XP, например, подменяет версию ОС: API запроса версии возвращает старое значение. Сама ОС не меняется; только этому процессу показывают «старую Windows».
Можно ли запускать приложения эпохи 16 бит в режиме совместимости на 64-разрядной Windows?
Нет. 64-разрядная Windows запускает 32-разрядные приложения через WOW64, но не поддерживает выполнение 16-разрядных; попытка старта завершается ERROR_BAD_EXE_FORMAT. Это архитектурное ограничение, которое шим не обойдёт. Старые пакеты, у которых заглушка установщика 16-разрядная, падают по той же причине. Если они действительно нужны, смотрите средства вне режима совместимости — например виртуальную машину с 32-разрядной Windows.
Можно ли запустить приложение, которое «не стартует без прав администратора», под учётной записью обычного пользователя?
Имеет смысл попробовать RunAsInvoker. Если выполнить set __COMPAT_LAYER=RunAsInvoker в командной строке и затем запустить приложение, запросы повышения из манифеста requireAdministrator или из детекции установщика подавляются, и приложение стартует с теми же (обычными) правами, что и вызывающий процесс. Для приложения, которое только запрашивает права администратора и не использует их, этого достаточно, чтобы убрать повышение из повседневной работы. Права не увеличиваются, поэтому операции, которым администратор действительно нужен, упадут внутри приложения. Принимайте только после проверки поведения.
Где взять Compatibility Administrator?
Он входит в Windows ADK (Windows Assessment and Deployment Kit). Скачайте ADK с сайта Microsoft и при установке выберите функции Application Compatibility Tools. Ставятся и 32-, и 64-разрядные издания; для 32-разрядных приложений нужно 32-разрядное издание, для 64-разрядных — 64-разрядное. Пользовательскую базу совместимости (.sdb) применяют командой sdbinst на каждом ПК.

Об авторе

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

Го Комура

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

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

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

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