Как продлить работу старых приложений в 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 сама массово использует эту временную меру и открывает часть механизма пользователям и администраторам.
Если пользоваться этим, не понимая механизма, продление эксплуатации получается хрупким: «нельзя трогать, потому что непонятно, почему работает». Если механизм понятен, можно обоснованно решить, насколько далеко можно на это опираться, что его сломает и когда программу стоит переписать.
flowchart TB
accTitle: Понимание механизма меняет качество продления эксплуатации
accDescr: Использование режима совместимости без понимания механизма даёт хрупкое продление, к которому боятся прикасаться; понимание механизма позволяет обоснованно решить, насколько можно опираться, что сломает работу и когда программу стоит переписать
unknown["Использовать, не понимая механизм"] --> fear["Хрупкое продление, к которому боятся прикасаться"]
known["Использовать, поняв механизм"] --> judge["Обоснованные решения"]
judge -.-> j1["Насколько можно опираться"]
judge -.-> j2["Что сломает работу"]
judge -.-> j3["Когда стоит переписать"]
Рис. 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»; эта статья держит шимы в центре и упоминает остальные слои только по необходимости.
flowchart TB
accTitle: Где стоит виртуализация UAC
accDescr: Виртуализация UAC — переходная мера для интерактивных 32-разрядных процессов без манифеста; она перенаправляет записи в пользовательский VirtualStore, но сама Microsoft называет её временной технологией, которую намерены убрать из будущей Windows
proc["Интерактивный 32-разрядный процесс без манифеста"] --> uacv["Применяется виртуализация UAC"]
uacv --> vs["Перенаправлено в пользовательский VirtualStore"]
uacv -.-> tmp["Временная технология, которую намерены убрать"]
Рис. 2: Виртуализация UAC — переходная мера для 32-разрядных процессов без манифеста, и на неё нельзя опираться постоянно.
Заметка о виртуализации DPI: приложение, не объявившее поддержку DPI, считается рисующим при 96 DPI (100%), и Windows растягивает растр для показа. Поэтому старые приложения выглядят «размытыми» на мониторе с высокой плотностью, а «Переопределить масштабирование при высоком DPI» на вкладке «Совместимость» — переключатель этого поведения виртуализации.11
flowchart TB
accTitle: Как работает виртуализация DPI
accDescr: Приложение, не объявившее поддержку DPI, считается рисующим при 96 DPI; Windows растягивает растр, поэтому оно выглядит размытым, а переопределение масштабирования при высоком DPI на вкладке «Совместимость» переключает это поведение виртуализации
app["Приложение, не объявляющее поддержку DPI"] --> treat["Считается рисующим при 96 DPI"]
treat --> stretch["Растр растягивается для показа"]
stretch --> blur["Выглядит размытым на мониторе с высокой плотностью"]
tab["Переопределить масштабирование при высоком DPI"] -.->|Переключает виртуализацию| treat
Рис. 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»; со стороны ОС — что «работает корректно ведущее себя приложение». Шим — переводчик между ними.
flowchart TB
accTitle: Путь, по которому шим перехватывает вызов API
accDescr: Вызов API приложения идёт через IAT; перепись записи IAT на шим при загрузке позволяет шиму перехватить вызов, подставить тот же ответ, что давала старая Windows, и затем при необходимости вызвать настоящий API
app["Приложение"] -->|Вызов API| iat["Запись IAT"]
iat -->|При загрузке переписывается на шим| shim["Шим (переводчик)"]
shim -->|Если нужно| api["Настоящий Windows API"]
shim -.-> lie["Подставляет тот же ответ, что давала старая Windows"]
gpa["Вызовы через GetProcAddress"] -.->|Обрабатываются перехватом| shim
Рис. 4: Шим встаёт между приложением и Windows API. Переписывается IAT на стороне приложения; сама ОС не меняется.
Из этой конструкции следуют три важных свойства.3
- Шим выполняется как код на стороне приложения. Он не часть ОС, поэтому подчиняется тем же ограничениям безопасности, что и приложение. Шим не обходит механизмы безопасности ОС, и ослаблять настройки безопасности ради шима не нужно.
- То, что шим может исправить, может исправить и правка кода на стороне приложения. Шим — замена для случаев «нет исходников / не можем править»; он не сильнее правки кода.
- Только пользовательский режим. Проблемы совместимости драйверов устройств в режиме ядра шим не чинит.
3.2. База шимов (.sdb) и сопоставление
Таблица соответствия «какой шим применять к какому EXE» — это база шимов, двоичный файл с расширением .sdb. Целевые исполняемые файлы регистрируются в базе по атрибутам вроде имени файла, размера, контрольной суммы и версии (атрибуты сопоставления) и сопоставляются при старте процесса. Среди средств есть Appfix (шим), который внедряет перехват API, и Apphelp, который показывает сообщение «у этого приложения проблема совместимости». Набор нескольких шимов и флагов — это слой совместимости (режим совместимости).1
Это легко упустить: сопоставление идёт не только у приложений с включённым режимом совместимости, а при каждом запуске процесса. Windows поставляет стандартную базу ОС с исправлениями для тысяч известных приложений (файлы лежат в %WINDIR%\AppPatch), и на вашем ПК сегодня почти наверняка какое-то старое приложение стартует с прикреплённым шимом незаметно. Исправления совместимости от Microsoft поставляются как часть Windows и обновляются через Windows Update.3
flowchart TB
accTitle: Сопоставление базы шимов при старте процесса
accDescr: Каждый запуск процесса сопоставляется с базой шимов; если регистрация совпадает с атрибутами сопоставления, Appfix внедряет шим или Apphelp показывает сообщение, иначе процесс стартует как есть
start["Старт процесса"] --> db["Сопоставить с базой шимов (.sdb)"]
db -.-> attr["Имя файла, размер и т. д."]
db --> hit{"Есть регистрация?"}
hit -->|Да| appfix["Appfix: внедрить шим"]
hit -->|Да| apphelp["Apphelp: сообщение"]
hit -->|Нет| plain["Стартовать как есть"]
layer["Слой совместимости (режим совместимости)"] -.->|Набор шимов и флагов| appfix
Рис. 5: Сопоставление идёт при каждом запуске процесса, не только у приложений с включённым режимом совместимости.
3.3. PCA — механизм, который применяет шимы автоматически
Другой путь, по которому шим может примениться без намерения администратора, — PCA (Program Compatibility Assistant). PCA следит за выполнением приложений и, обнаружив признаки известной проблемы совместимости, предлагает пользователю применить исправление или в некоторых случаях применяет настройку совместимости автоматически. Например, приложению, которое падает, вызывая код в освобождённой DLL, назначают PINDLL, а приложению, которое не может писать в защищённый файл Windows, — WRPMITIGATION.5
flowchart TB
accTitle: Как PCA автоматически применяет настройку совместимости
accDescr: PCA следит за выполнением приложений и, обнаружив признаки известной проблемы совместимости, предлагает пользователю применить исправление или в некоторых случаях применяет настройку совместимости автоматически
run["Выполнение приложения"] --> pca["PCA следит"]
pca --> sign{"Признаки известной проблемы?"}
sign -->|Да| resp{"Какой случай?"}
resp -->|Через предложение| suggest["Предложить применить исправление"]
resp -->|Некоторые случаи| auto["Применить настройку совместимости автоматически"]
sign -->|Нет| none["Выполнить как есть"]
auto -.-> ex["Пример: 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, которую видит приложение», решается в этих наложенных ступенях.
- Возвращается значение до ОС, объявленной в манифесте (6.2, если объявления нет)
- Если применён режим совместимости (шим семейства VersionLie), возвращается версия выбранной ОС6
flowchart TB
accTitle: Как решается версия ОС, которую видит приложение
accDescr: Значение, которое возвращает GetVersionEx, решается наличием объявления supportedOS в манифесте; без объявления возвращается эквивалент Windows 8 6.2, с объявлением — значение до самой высокой объявленной ОС, а если применён шим семейства VersionLie, оно перезаписывается версией выбранной ОС
q["Запрос GetVersionEx"] --> m{"Есть объявление supportedOS?"}
m -->|Нет| v62["Возвращается эквивалент Windows 8 (6.2)"]
m -->|Да| decl["Значение до самой высокой объявленной ОС"]
v62 --> lie{"Применён шим семейства VersionLie?"}
decl --> lie
lie -->|Да| fake["Значение ОС, выбранное в режиме совместимости"]
lie -->|Нет| asis["Значение возвращается как есть"]
Рис. 7: Версия Windows, которую видит приложение, решается наложенными ступенями манифеста и шимов.
Если внутреннее приложение «ветвится по версии ОС и, путано, считается восьмёркой, хотя это Windows 11», сначала подозревайте объявление supportedOS в манифесте. Наоборот, старое приложение, которое отказывается стартовать из-за проверки версии, с высокой вероятностью можно провести шимом VersionLie. Во многих случаях оно смотрит только на номер версии, а фактическое поведение на более новой ОС нормально.
flowchart TB
accTitle: Два симптома из-за версии и как с ними быть
accDescr: Если внутреннее приложение считается восьмёркой, хотя это Windows 11, подозревайте объявление supportedOS в манифесте; старое приложение, которое отказывается стартовать из-за проверки версии, с высокой вероятностью можно провести шимом VersionLie
sym1["Считается восьмёркой, хотя это Windows 11"] --> fix1["Подозревать объявление supportedOS"]
sym2["Старт отказан из-за проверки версии"] --> fix2["Попробовать пройти VersionLie"]
fix2 -.-> why["Фактическое поведение на более новой ОС часто нормально"]
Рис. 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 в следующей главе.
flowchart TB
accTitle: Путь от настройки вкладки «Совместимость» до действия
accDescr: Настройки вкладки «Совместимость» хранятся как путь EXE и значение в ключе AppCompatFlags Layers; при следующем старте этого EXE загрузчик читает значение и применяет соответствующий слой совместимости к процессу
tab["Задать на вкладке «Совместимость»"] --> reg["Сохранить путь EXE и значение в ключе Layers"]
reg --> boot["Следующий старт EXE"]
boot --> loader["Загрузчик читает значение"]
loader --> apply["Применить слой совместимости к процессу"]
reg -.-> hkcu["HKCU только этот пользователь"]
reg -.-> hklm["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
flowchart TB
accTitle: Два момента, которые учесть при работе с Compatibility Administrator
accDescr: Используйте 32-разрядное издание для 32-разрядных приложений и 64-разрядное для 64-разрядных и подтверждайте эффект исправления той же учётной записью и теми же правами, что у реального пользователя, а не в повышенном состоянии
app32["32-разрядное приложение"] --> tool32["Использовать 32-разрядное издание"]
app64["64-разрядное приложение"] --> tool64["Использовать 64-разрядное издание"]
elev["Тест в повышенном состоянии"] -.-> wrong["Можно ошибочно оценить исправление"]
user["Тест с правами реального пользователя"] --> ok["Подтвердить эффект"]
Рис. 10: Выбор 32- или 64-разрядного издания и проверка теми же правами, что у реального пользователя, — то, что важно учесть с самого начала.
6.2. Порядок сборки пользовательской базы совместимости
Схема такова.14
- В левой панели Compatibility Administrator создайте новую базу в «Custom Databases» и выберите «Create New» → «Application Fix»
- Введите имя приложения и имя поставщика и укажите целевой EXE
- Выберите применяемый режим совместимости (слой) — сначала попробовать набор вроде «совместимость с Windows XP» короче
- При необходимости добавьте отдельные исправления совместимости (шимы) — можно сузить до минимума вроде только VersionLie или только CorrectFilePaths
- Подтвердите условия сопоставления (размер файла, контрольная сумма, версия и так далее) и сохраните
Условия сопоставления — ключ к «применять это только к этому EXE». Базовых условий по умолчанию обычно хватает, но мы рекомендуем оставить условие, которое идентифицирует версию приложения. Это предотвращает аварию, когда старая ложь продолжает применяться к новой версии, когда поставщик позже выпустит исправленное издание.1415
flowchart TB
accTitle: Порядок сборки пользовательской базы совместимости
accDescr: Создайте Application Fix в новой базе, укажите имя приложения и целевой EXE, сначала попробуйте набор режима совместимости, затем при необходимости сузьте до отдельных шимов, подтвердите условия сопоставления и сохраните
new["Создать новую базу"] --> fix["Выбрать Application Fix"]
fix --> info["Указать имя приложения и целевой EXE"]
info --> layer["Попробовать набор режима совместимости"]
layer --> single["При необходимости сузить до отдельных шимов"]
single --> match["Подтвердить условия сопоставления и сохранить"]
match -.-> ver["Оставить условие, которое идентифицирует версию"]
Рис. 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
flowchart TB
accTitle: Путь от создания пользовательского .sdb до развёртывания
accDescr: Создайте пользовательскую базу совместимости в Compatibility Administrator, протестируйте на проверочной машине, примените на каждом ПК через sdbinst и при обновлении установите новую версию с тем же GUID, чтобы старая заменилась автоматически
make["Создать в Compatibility Administrator"] --> test["Протестировать на проверочной машине"]
test --> deploy["Применить на каждом ПК через sdbinst"]
deploy --> update["Установить новую версию с тем же GUID"]
update -.-> replace["Старая версия заменяется автоматически"]
deploy -.-> inv["Регистрируется в «Программы и компоненты»"]
Рис. 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 аномалией и перестать работать.
flowchart TB
accTitle: Случаи, когда шим не работает
accDescr: Шим выполняется внутри процесса пользовательского режима, поэтому не работает на проблемах драйверов режима ядра, 16-разрядных приложениях, прямом доступе к оборудованию и обходе механизмов безопасности
shim["Шим (выполняется в пользовательском режиме)"] -->|Не работает| drv["Драйвер ядра"]
shim -->|Не работает| b16["16-разрядное приложение"]
shim -->|Не работает| hw["Прямой доступ к оборудованию"]
shim -->|Не работает| sec["Обход механизмов безопасности"]
b16 -.-> fmt["На 64 разрядах падает уже сам старт"]
sec -.-> fake["Лишь подменяет успех, чтобы приложение продолжило"]
Рис. 13: Шим только в пользовательском режиме и не достаёт до ядра, 16-разрядных приложений, прямого доступа к оборудованию и обхода безопасности.
И существенный предел, общий для каждого шима: это временная мера. Шим — ложь, заточенная под конкретное использование конкретного API, и если реализация на стороне ОС меняется, предпосылка рушится. Шимы от Microsoft поддерживаются как часть Windows через Windows Update,3 но сопровождать ложь, которую вы применили пользовательской базой, — работа вашей организации. Заложите в бюджет, как стоимость продления эксплуатации, операцию, которая проверяет «список приложений, которых держат живыми шимы» при каждом обновлении функций.
flowchart TB
accTitle: Шимы как временная мера и кто отвечает за сопровождение
accDescr: Шим — ложь, заточенная под конкретное использование API, и предпосылка рушится, если меняется реализация на стороне ОС; шимы Microsoft поддерживаются через Windows Update, но сопровождать ложь, применённую пользовательской базой, — работа организации, а проверка при каждом обновлении функций — стоимость продления эксплуатации
shim["Шим = временная ложь"] --> break["Изменение ОС ломает"]
ms["Шимы Microsoft"] --> wu["Через Windows Update"]
own["Ложь пользовательской базы"] --> self["Организация сопровождает"]
self --> cost["Проверка каждого обновления — стоимость продления эксплуатации"]
Рис. 14: Ответственность за сопровождение лжи шима делится между набором от Microsoft и пользовательским набором вашей организации.
8. Практическая ценность RunAsInvoker — подавить только запрос повышения
Среди шимов чаще всего в повседневной ИТ-работе встречается RunAsInvoker.
Некоторые старые бизнес-приложения объявляют requireAdministrator в манифесте или ошибочно детектируются как установщик по имени или содержимому EXE и запрашивают повышение UAC при каждом старте. Многие из них, однако, просят администратора лишь по инерции эпохи XP и не используют права администратора. Применение шима RunAsInvoker перезаписывает и детекцию установщика, и манифест, и приложение стартует с токеном, унаследованным от родительского процесса (= обычные права пользователя).9
flowchart TB
accTitle: Как RunAsInvoker подавляет запрос повышения
accDescr: Объявление requireAdministrator в манифесте или ошибочная детекция как установщик вызывает запрос повышения UAC при старте, но применение RunAsInvoker перезаписывает оба и приложение стартует с токеном, унаследованным от родителя
manifest["Объявление requireAdministrator"] --> shim{"Применён RunAsInvoker?"}
detect["Ошибочно детектировано как установщик"] --> shim
shim -->|Нет| uac["Запрос повышения UAC при каждом старте"]
shim -->|Да| token["Стартует с токеном родителя"]
token -.-> limit["Работа, которой действительно нужен администратор, падает внутри приложения"]
Рис. 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. Это приём совместимости, который укрепляет защиту, в духе наименьших привилегий.
flowchart TB
accTitle: Эффект раздачи пакета RunAsInvoker
accDescr: Раздача двухстрочного пакета, который задаёт RunAsInvoker, как ярлыка значит, что можно не выдавать локальные права администратора обычным пользователям, ИТ не вызывают из-за пароля UAC, а эксплуатация следует наименьшим привилегиям
bat["Раздать двухстрочный пакет"] --> noadmin["Можно не выдавать права администратора"]
bat --> nocall["ИТ не вызывают из-за UAC"]
noadmin --> lp["Эксплуатация, которая следует наименьшим привилегиям"]
nocall --> lp
Рис. 16: Одна раздача пакета может сократить и выдачу прав администратора, и вызовы из-за UAC.
Ограничения тоже стоит назвать прямо.
- Права не увеличиваются. Работа, которой действительно нужны права администратора (запись в HKLM, обновления под Program Files и так далее), даст ошибку внутри приложения или, если условия выполнены, будет перенаправлена в VirtualStore виртуализацией UAC.10 Если сохранение настроек вдруг «перестало работать», подозревайте виртуализацию.
- Метод переменной окружения действует только на дочерние процессы. Для постоянного применения надёжны прямая настройка в ключе Layers (у RUNASINVOKER нет пункта на вкладке) или развёртывание через .sdb.
- Исправить место записи — правильный путь. Если приложение можно менять, перенесите файл настроек под
%APPDATA%и объявитеasInvokerв манифесте — это корректная форма.9
flowchart TB
accTitle: Временное и постоянное применение RunAsInvoker
accDescr: Применение через переменную окружения COMPAT_LAYER действует только на дочерние процессы, запущенные оттуда; для постоянного применения используйте прямую настройку в ключе Layers или развёртывание через .sdb
env["Задать через переменную окружения"] --> child["Действует только на дочерние процессы"]
child -.-> tmp["Временное применение"]
layers["Задать напрямую в ключе Layers"] --> always["Постоянное применение"]
sdb["Развернуть через sdb"] --> always
Рис. 17: Метод переменной окружения — временное применение, ограниченное дочерними процессами; постоянным его делают ключ Layers или .sdb.
9. Решение между продлением эксплуатации и миграцией — о чём думать после того, как заработало под шимом
Момент, когда заработало под шимом, — облегчение, но важно не останавливать мысль там. Работа под шимом значит лишь, что случайно подошёл механизм, который Windows уже подготовила. Оси решения — таблицей.
| Ось решения | Условия в пользу продления эксплуатации (шим) | Условия в пользу миграции / переписывания |
|---|---|---|
| Оставшийся срок использования | Планируется вывести вместе с бизнесом за 1–2 года | Предполагается использовать ещё 5 лет и больше |
| Исходный код | Нет (поставщик исчез или потерян) | Есть, или актив можно восстановить |
| Глубина зависимости | Только проблема совместимости API в пользовательском режиме | Зависит от драйвера, 16 бит или специализированного оборудования |
| Альтернативы | Нет коробочного продукта или новой версии | Целевой продукт и технология ясны |
| Влияние при отказе | Бизнес может идти по запасной процедуре | Ядро бизнеса бьёт напрямую |
| Возможности проверки | Можно подтверждать поведение при каждом обновлении функций | Нет ресурса на проверки, и сопровождение легко замирает |
Если решили продлевать эксплуатацию, внесите в работу следующие три пункта комплектом.
- Зафиксировать. Какой EXE, какой шим/слой и почему. Оставьте значение ключа Layers и GUID .sdb в учётном журнале. «Никто не знает, почему работает» — самый большой долг следующей смене. Это та же установка на сохранение, что в «Если вам досталась система без исходного кода и без документации — практический план, как сопровождать её, не останавливая работу».
- Проверять. Включите старт и основные операции приложений, которых держат живыми шимы, в пункты проверки обновления функций Windows. Свяжите и с планом замены ОС (Practical Options After Windows 10 End of Support).
- Поставить срок. Решите конец продления — «до следующего обновления ядра системы», «до марта 2028» — и параллельно ведите рассмотрение миграции.
flowchart TB
accTitle: Комплект эксплуатации из трёх пунктов после решения продлевать
accDescr: Зафиксируйте в учётном журнале, какой шим даёт работу, проверяйте поведение приложений, которых держат живыми шимы, при каждом обновлении функций, поставьте срок конца продления и параллельно ведите рассмотрение миграции
decide["Решить продлевать эксплуатацию"] --> rec["Зафиксировать: какой шим даёт работу, в учётный журнал"]
rec --> verify["Проверять: подтверждать поведение при каждом обновлении функций"]
verify --> deadline["Срок: решить конец продления"]
deadline --> mig["Параллельно вести рассмотрение миграции"]
Рис. 18: Продление эксплуатации ведётся комплектом из трёх пунктов — зафиксировать, проверять и срок, включая параллельное рассмотрение миграции.
На стороне миграции стандартные варианты меняются с технологией приложения. Для VB6 — тройной выбор полной переписки, автоматического преобразования и поэтапной миграции, собранный в «До каких пор будут работать приложения VB6 ── состояние поддержки среды выполнения и практичный путь миграции на .NET»; для зависимости от ActiveX/OCX — таблица решений оставить / обернуть / заменить в «Как сегодня поступать с ActiveX / OCX - таблица решений: оставить, обернуть или заменить». Здоровое место шима — покупать время, чтобы период рассмотрения и подготовки этого проекта миграции шёл безопасно.
flowchart TB
accTitle: Варианты на стороне миграции и где стоит шим
accDescr: Стандартные варианты миграции меняются с технологией приложения; для VB6 тройной выбор — переписать, автоматически преобразовать и поэтапная миграция, для зависимости ActiveX действует таблица оставить / обернуть / заменить, а шим стоит как покупка времени на рассмотрение и подготовку проекта миграции
tech{"Какая технология приложения?"} -->|VB6| vb["Переписать, автоматически преобразовать или поэтапная миграция"]
tech -->|Зависимость ActiveX| ax["Оставить, обернуть или заменить"]
shim["Продление эксплуатации через шим"] -.->|Покупает время на рассмотрение и подготовку| tech
Рис. 19: Стандартные варианты миграции решает технология приложения, а шим стоит как покупка времени на это рассмотрение.
10. Итог
- Режим совместимости — это шимы. Настройки вкладки «Совместимость» пишутся в ключ AppCompatFlags\Layers и при старте внедряются в процесс как перехват API через подмену IAT.
- Шимы — набор «лжи, которая возвращает ответ, которого ждёт старое приложение». Готовые шимы для подмены версии, перенаправления путей, подмены реестра, подмены проверок администратора и подобного предоставляются.
- Сама Windows по умолчанию использует много шимов, и PCA может применять их автоматически. Опираться на режим совместимости само по себе разумный выбор, который едет на официальном механизме ОС.
- Есть принципиальный предел только пользовательского режима и без обхода безопасности, и драйверы ядра, 16-разрядные приложения и прямой доступ к оборудованию спасти нельзя.
- Организационное развёртывание — собрать пользовательский .sdb в Compatibility Administrator (Windows ADK) и доставить через sdbinst. Выбор 32-/64-разрядного издания, тест с реальной учётной записью пользователя и ведение обновлений по GUID — практические точки.
- Приложения, которые «требуют администратора, но на самом деле не нуждаются», можно опустить до обычных прав через
__COMPAT_LAYER=RunAsInvoker. Это защитный приём, который глушит запрос повышения, а не раздаёт права. - Работа под шимом — продление эксплуатации, не решение. Зафиксировать, что даёт работу, проверять при каждом обновлении функций и поставить срок, чтобы миграция шла параллельно, — этот комплект из трёх пунктов входит в решение «опираться на режим совместимости».
В следующий раз, когда старое приложение заработает после галочки режима совместимости, спросите снова. «Благодаря какой лжи это приложение работает? Как долго эта ложь ещё будет действовать?» Если можете ответить, продление эксплуатации — вполне состоятельная стратегия.
Похожие статьи
- Registry 32-bit/64-bit Redirection and Virtualization Pitfalls — Wow6432Node and the “The Value I Wrote Isn’t There” Problem
- До каких пор будут работать приложения VB6 ── состояние поддержки среды выполнения и практичный путь миграции на .NET
- Как сегодня поступать с ActiveX / OCX - таблица решений: оставить, обернуть или заменить
- Practical Options After Windows 10 End of Support — A Decision Table for ESU, LTSC, and Replacement
- Если вам досталась система без исходного кода и без документации — практический план, как сопровождать её, не останавливая работу
- Интеграция с оболочкой Windows сегодня — контекстные меню, сопоставления файлов и что изменилось в Windows 11
Смежные области консультирования
Компания KomuraSoft LLC занимается исследованием поведения старых бизнес-приложений без исходного кода и проектированием продления их эксплуатации (выбор шимов и режима совместимости, сборка и развёртывание пользовательского .sdb), проверкой совместимости существующих приложений для миграции на Windows 11 и планированием переписывания или миграции, идущих параллельно с продлением. Консультация уже со стадии «заработало в режиме совместимости, но нормально ли так оставлять?» уместна.
- Использование и перенос существующих активов
- Разработка приложений для Windows
- Технические консультации и ревью дизайна
- Связаться с нами
Справочные ссылки
-
Microsoft Learn, Application Compatibility Database. О том, что инфраструктура совместимости ведёт проблемы и средства в базе формата .sdb, сопоставление по атрибутам исполняемого файла, Apphelp (показ сообщения) и Appfix (перехват API через шим), а также слой совместимости (режим), который связывает несколько шимов и флагов. ↩ ↩2 ↩3
-
Microsoft Learn, DXGI overview. О том, что настройки совместимости приложений хранятся в ключе реестра HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers (на примере настроек совместимости DXGI). ↩ ↩2
-
Microsoft Learn, Understanding and Using Compatibility Fixes. О том, что исправление совместимости (шим) перенаправляет вызовы API, переписывая IAT (таблицу адресов импорта), что динамическая компоновка обрабатывается перехватом GetProcAddress, что шим подчиняется тем же ограничениям безопасности, что и приложение, и не обходит механизмы безопасности ОС, что он только в пользовательском режиме и не чинит проблемы драйверов, что исправление, возможное шимом, возможно и правкой кода, сценарии вроде приложений, у которых кончилась поддержка поставщика, и что исправления совместимости от Microsoft поставляются как часть Windows и обновляются через Windows Update. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8
-
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
-
Microsoft Learn, Program Compatibility Assistant scenarios for Windows 8. О том, что PCA следит за выполнением приложений, обнаруживает признаки известной проблемы совместимости и предлагает применить рекомендованное исправление или применяет его автоматически (PINDLL, DISABLEUSERCALLBACKEXCEPTION, VIRTUALIZEDELETE, WRPMITIGATION и подобные), а также применение исправления с вкладки «Совместимость» и Program Compatibility Troubleshooter. ↩ ↩2
-
Microsoft Learn, GetVersionExW function. О том, что начиная с Windows 8.1 значение, которое возвращает GetVersionEx, зависит от манифеста, что приложению без манифеста для Windows 8.1/10 дают значение версии Windows 8 (6.2), и что при включённом режиме совместимости сообщается версия выбранной ОС. ↩ ↩2 ↩3
-
Microsoft Learn, Targeting your application for Windows. Как объявлять GUID поддерживаемых ОС элементом supportedOS в разделе compatibility манифеста приложения, поведение без объявления и то, что интерактивное 32-разрядное x86-приложение без trustInfo попадает под виртуализацию файлов UAC (перенаправление записи в VirtualStore). ↩ ↩2
-
Microsoft Learn, Running 32-bit Applications. О том, что WOW64 — слой эмуляции, который запускает 32-разрядные приложения на 64-разрядной Windows и изолирует столкновения файлов и реестра, и что 64-разрядная Windows не поддерживает выполнение 16-разрядных приложений, а старт падает с ERROR_BAD_EXE_FORMAT из-за числа значащих бит в дескрипторе. ↩ ↩2
-
Microsoft Learn, Using the RunAsInvoker Fix. О том, что исправление совместимости RunAsInvoker стартует приложение с токеном, унаследованным от родительского процесса, что оно перезаписывает и детекцию установщика, и обработку манифеста, что применяется как флаг загрузчика без перехвата API, и что когда код можно править, правильное исправление — объявить asInvoker в манифесте. ↩ ↩2 ↩3
-
Microsoft Learn, Registry Virtualization. О том, что виртуализация реестра — технология совместимости, которая прозрачно перенаправляет глобальные записи в HKLM\Software в пользовательский VirtualStore, что в охвате только интерактивные 32-разрядные процессы и она отключена для процессов, которые задают requestedExecutionLevel в манифесте, и для 64-разрядных процессов, и что её ставят как временную технологию, предназначенную к удалению из будущей Windows. ↩ ↩2
-
Microsoft Learn, High DPI Desktop Application Development on Windows. О том, что приложение без поддержки DPI считается рисующим при фиксированных 96 DPI и на дисплее с высокой плотностью Windows растягивает растр, поэтому оно выглядит размытым, а также различия режимов осведомлённости о DPI (Unaware/System/Per-Monitor). ↩ ↩2
-
Microsoft Learn, Download and install the Windows ADK. О том, что Windows ADK включает Compatibility Administrator и Standard User Analyzer, и как думать о выборе версии ADK и как скачивать и устанавливать. ↩
-
Microsoft Learn, Compatibility Administrator User’s Guide. О том, что Compatibility Administrator даёт применение исправлений совместимости, режимов совместимости и сообщений AppHelp и создание пользовательской базы, и что ставятся и 32-, и 64-разрядные издания и для 32-разрядных приложений нужно 32-разрядное издание, для 64-разрядных — 64-разрядное. ↩
-
Microsoft Learn, Creating a Custom Compatibility Fix in Compatibility Administrator. О том, что исправление совместимости (раньше называлось шимом) — маленький кусок кода, который перехватывает вызов API; порядок создания Application Fix в пользовательской базе (указать имя приложения, поставщика и целевой EXE, выбрать режим совместимости, выбрать дополнительные шимы, задать условия сопоставления); и что следует оставить условия, которые верно идентифицируют приложение, сужая сведения сопоставления. ↩ ↩2
-
Microsoft Learn, Compatibility Fix Database Management Strategies and Deployment. О том, что централизованно ведомая база рекомендуется как стратегия управления пользовательской базой совместимости, что исправление совместимости должно включать проверку версии (условие сопоставления), чтобы не применяться к новой версии, локальная установка через Sdbinst.exe (параметры -q, -u, -g), что установка новой версии с тем же GUID базы автоматически удаляет старую, и способы развёртывания через MSI или сценарий. ↩ ↩2 ↩3
Похожие статьи
Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.
Сеть работает, а Windows пишет «Нет доступа к интернету» — разбираем NCSI, DNS, прокси и VPN
Почему Windows сообщает «Нет доступа к интернету», хотя сеть работает: разбираем решение NCSI о связности. Отделяем DNS, прокси, VPN и ca...
Что на самом деле делает быстрый запуск — почему «Завершение работы» в Windows не то же самое, что перезагрузка
Завершение работы Windows по умолчанию — гибридное: ядро и драйверы сохраняются в hiberfil.sys. Почему только перезагрузка их сбрасывает ...
Time Travel Debugging — записывать и перематывать ошибки, которые не воспроизводятся в долгоживущих приложениях
Ошибка раз в месяц оставляет в дампе только результат. Записывайте и перематывайте исполнение через WinDbg Time Travel Debugging (TTD): T...
Пул потоков Win32 — параллелизм через CreateThreadpoolWork без своих потоков
Не плодите ли вы CreateThread по всему нативному коду? Разбираем API пула потоков Win32, переработанный в Vista: четыре объекта work, tim...
Именованные каналы на практике — от проектирования до безопасности IPC в Windows
Практический разбор именованных каналов — стандартного IPC в Windows. По первоисточникам: выбор байтового режима и режима сообщений, серв...
Связанные темы
Эти страницы показывают тему статьи в более широком контексте услуг и решений.
Технические темы Windows
Раздел о разработке Windows, расследовании сбоев и использовании существующих активов.
Услуги по этой теме
Статья напрямую связана со следующими услугами.
Разработка приложений для Windows
Бизнес-приложения, интеграция оборудования и средства связи — от требований до разработки.
Частые вопросы
Вопросы, которые часто возникают при консультациях по теме статьи.
- Если после включения режима совместимости приложение заработало, можно ли так и пользоваться?
- Для ближайшей непрерывности бизнеса — да. Режим совместимости — это перехват 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, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.