Работают ли бизнес-приложения на Windows на Arm — реальность x64-эмуляции (Prism) и нативных DLL/COM
· Го Комура · Windows on Arm, Arm64, x64-эмуляция, Нативная интеграция, P/Invoke, COM, Драйверы, C#, .NET, Разработка Windows, Техническая консультация
«Со следующего месяца переходим на новый ПК, что-то вроде Copilot+ PC — заработает ли на нём наша бизнес-система?» По мере того как корпоративное внедрение ПК на Snapdragon набирает обороты, всё больше компаний-разработчиков и ИТ-отделов сталкиваются с этим вопросом. В маркетинговых материалах написано «существующие приложения тоже работают через эмуляцию». Но собственное бизнес-приложение вызывает через P/Invoke нативную DLL от вендора за интерфейсом на C#, формирует отчёты через COM-компонент, да ещё и содержит драйвер для специализированного оборудования. Честно говоря, «заработает ли?» — вопрос, на который сходу не ответишь.
Ответ вкратце: «само приложение обычно заработает. Опасность — во всём, что к нему подвешено». Эмуляция Windows 11 довольно точно справляется с пользовательским кодом x86/x64, но при этом чётко очерчена зона «вне юрисдикции эмуляции» — драйверы, расширения оболочки, смешение архитектур внутри процесса, — и именно в этой зоне бизнес-приложения традиционно чувствовали себя как дома.
В этой статье разбираем, как устроена эмуляция Windows на Arm и где проходят её границы, фундаментальное правило о невозможности смешивать x64 и Arm64 внутри процесса, характерную для .NET-приложений проблему сочетаний, а также практический порядок проверки «заработает ли наше приложение на Arm-машине» — всё это с опорой на то, что можно перепроверить по Microsoft Learn.
1. Сначала вывод
- Чисто управляемое (.NET) приложение или обычное десктопное x86/x64-приложение почти наверняка заработает благодаря эмуляции Arm-версии Windows 11. Эмуляция встроена в ОС — изменение приложения или дополнительные компоненты не требуются.1
- Эмуляция заботится только о коде пользовательского режима. Драйверы уровня ядра не эмулируются и обязательно требуют нативной сборки под Arm64. Драйверы UMDF и принтеров тоже должны соответствовать архитектуре ОС.23
- Расширения оболочки, IME, средства специальных возможностей — любые «DLL, загружаемые в чужой процесс» — тоже нужно пересобрать под Arm64, как и саму систему. Эмуляция здесь не спасает.4
- Внутри одного процесса x64 и Arm64 сосуществовать не могут. Процесс x64/Arm64EC может загружать только бинарники x64 и Arm64EC, процесс Arm64 — только бинарники Arm64. Из x64-exe нельзя вызвать Arm64-DLL, и наоборот тоже нельзя.5
- Способы обойти это ограничение в пределах одного файла — это Arm64EC (нативный Arm64-код, способный сосуществовать с x64 в одном процессе) и Arm64X (бинарник, объединяющий Arm64- и Arm64EC-код в одном PE-файле и загружаемый в процесс любого из этих типов). Именно для этого нужен Arm64X, когда COM-сервер вне процесса или плагин вызывается из обеих архитектур.56
- .NET официально поддерживает Arm64, и нативную публикацию можно выполнить через RID
win-arm64. С другой стороны, запустите AnyCPU-приложение на Arm64-runtime — и процесс будет работать как Arm64, поэтому если приложение вызывает через P/Invoke нативную DLL, доступную только для x64, её загрузка завершится ошибкой — это стоит держать в уме как проблему сочетания.785 - Помимо физического железа (Copilot+ PC и т. п.), тестовое окружение можно развернуть на Arm64-VM в Azure или через ISO Windows 11 Arm64, пригодный для Hyper-V на Arm-машине или для Mac на Apple Silicon. Учтите, что на Hyper-V, работающем на x64-машине, Arm64-VM создать нельзя.910
2. Что такое Windows на Arm — ПК на Snapdragon и Prism
Windows на Arm — это Windows, работающая на процессоре Arm64. С 2024 года большинство «Copilot+ PC» — новой категории ПК на Windows 11 с NPU, способным выполнять более 40 триллионов операций в секунду (40+ TOPS), — используют Arm-чипы серии Snapdragon X, и разработчики уже не могут это игнорировать.1112
Совместимость с существующими приложениями обеспечивает встроенная в ОС эмуляция. Кратко о том, как она устроена.1
- Эмулятор выполняет JIT-компиляцию блоков инструкций x86/x64 в инструкции Arm64, кэшируя результат преобразования по модулям, чтобы ускорить последующие запуски.
- Windows 11 умеет эмулировать и x86, и x64. Windows 10 на Arm эмулирует только x86, поэтому любой разговор о x64-бизнес-приложениях по сути подразумевает Windows 11.
- В Windows 11 24H2 появился новый эмулятор Prism, который повысил производительность по сравнению с предыдущим и снизил нагрузку на CPU. Prism оптимизирован под чипы Qualcomm Snapdragon.
- 32-битные (x86) приложения работают поверх того же слоя WOW64, что и в x64-версии Windows, и получают перенаправление файловой системы и реестра. У x64-приложений слоя WOW64 нет — поскольку системные бинарники скомпилированы в формате Arm64X (о нём ниже), x64-приложения обращаются ко всей ОС (и к файловой системе, и к реестру) без перенаправления.1
Информация о процессоре, видимая приложению под эмуляцией, — это информация об «эмулируемом виртуальном процессоре». Ради совместимости даже GetNativeSystemInfo возвращает эмулированное значение, поэтому чтобы узнать, действительно ли хост — Arm64, используйте IsWow64Process2 или GetMachineTypeAttributes.13
Отметим также, что для приложений, у которых возникают проблемы под эмуляцией, в Windows предусмотрен способ изменить настройки эмуляции (пресеты «по умолчанию/безопасный/строгий/очень строгий» и отдельные детальные параметры) через правый клик по exe-файлу → «Свойства» → вкладка «Совместимость». Это компромисс, снижающий производительность ради совместимости, но стоит держать его в уме как запасной вариант для случаев «раньше на старой Windows на Arm это работало».14
3. Что работает под эмуляцией, а что нет
Ответ на вопрос «заработает ли?» определяется не самим приложением, а типом зависимости. Сведём это в таблицу решений.
| Категория | Поведение на Arm-версии Windows 11 | Основание / примечание |
|---|---|---|
| Пользовательское x86/x64-приложение (exe + полный набор DLL той же архитектуры) | Работает через эмуляцию | Без изменений, без дополнительной установки1 |
| .NET-приложение (управляемое) | Работает (возможен и нативный запуск под Arm64) | См. раздел 58 |
| Драйвер уровня ядра | Не работает. Обязательно нужна нативная сборка под Arm64 | В ядре эмуляции нет23 |
| Драйвер UMDF / драйвер принтера | Обязательно нужен Arm64, совпадающий с ОС | Даже если само приложение работает через эмуляцию, функции, зависящие от драйвера, использовать нельзя3 |
| Расширение оболочки / IME / средство специальных возможностей (DLL, загружаемая в чужой процесс) | Требуется пересборка под Arm64 | Контекстное меню Explorer, отображение значков облачных хранилищ и т. п.4 |
| x86-приложения, запрещающие динамическую генерацию кода | Под эмуляцией не работают | Эмулятор генерирует инструкции Arm64 во время выполнения, поэтому нужно ослабить ProcessDynamicCodePolicy4 |
| Игры, зависящие от устаревшего OpenGL или античит-драйверов | Могут не работать | Препятствиями становятся OpenGL старше 3.3 или античит без поддержки Arm15 |
| Периферия (принтеры, сканеры, специализированные устройства) | Определяется наличием Arm64-драйвера | Нужен Arm64-драйвер — либо встроенный в ОС, либо от производителя15 |
| Антивирусы и ПО, «меняющее поведение Windows» | Требуется проверка по каждому продукту отдельно | Поддержка Arm заметно продвинулась, но проверка по каждому продукту всё же рекомендуется15 |
Переводя на язык бизнес-приложений, тревожные сигналы выглядят так:
- VPN-клиенты, агенты управления активами, средства защиты — по сути, набор драйверов уровня ядра. Нужно уточнить у вендора наличие версии с поддержкой Arm64.
- Авторизация через USB-донглы, специализированное оборудование (измерительные приборы, платёжные терминалы и т. п.) — наличие Arm64-драйвера устройства становится решающим фактором.
- Инструменты «добавляют функцию в Explorer» — расширения оболочки загружаются в Arm64-версию Explorer, поэтому пока они остаются x64, они просто не будут работать.
- Даже если само приложение не подпадает под эти категории, случай, когда установщик содержит драйвер (например, вывод в PDF через драйвер виртуального принтера), сталкивается с той же проблемой.
4. Смешение архитектур внутри процесса невозможно — реальность P/Invoke и COM
Ещё с 32-битной эпохи существовало железное правило: «64-битный процесс не может загрузить 32-битную DLL».16 В Windows на Arm действует структурно то же правило. Официально совместимость загрузки сведена в такую таблицу.5
| Архитектура процесса | DLL x64 | DLL Arm64EC | DLL Arm64 | DLL Arm64X |
|---|---|---|---|---|
| Процесс x64 / Arm64EC | Можно загрузить | Можно загрузить | Нельзя | Можно загрузить |
| Процесс Arm64 | Нельзя | Нельзя | Можно загрузить | Можно загрузить |
Здесь появляются два механизма, ключевых для проектирования готовности к Arm.
- Arm64EC (Emulation Compatible) — это ABI нативного Arm64-кода, следующее соглашению о вызовах, использованию стека и раскладке данных x64, благодаря чему такой код может сосуществовать в одном процессе с x64-кодом, работающим под эмуляцией. Когда x64-приложение работает в Windows 11 на Arm, бо́льшая часть кода ОС, загружаемого в этот процесс, уже скомпилирована как Arm64EC и выполняется с нативной скоростью незаметно для приложения. Это позволяет вести поэтапную миграцию: постепенно переводить в Arm64EC собственный код, повышая производительность, оставляя зависимые DLL по-прежнему в x64.5
- Arm64X — это формат бинарника, объединяющий традиционный Arm64-код и Arm64EC-код в одном PE-файле. В зависимости от того, x64 или Arm64 загружающий процесс, он ведёт себя как x64-DLL или как Arm64-DLL соответственно, что делает его удобным для DLL, которую потенциально могут вызывать процессы обеих архитектур. Официальная документация называет ситуации, требующие Arm64X: «64-битный COM-сервер, вызываемый как из x64-, так и из Arm64-приложений», «плагин, загружаемый и в x64-, и в Arm64-приложения», «единый бинарник, инжектируемый в процессы x64/Arm64».6
Конкретизируем реальные последствия для бизнес-приложений.
Случай 1: x64-exe + нативная x64-DLL (P/Invoke). Если весь процесс целиком остаётся x64, он полностью работает внутри эмуляции. Нельзя «ускорить только часть», подмешав туда Arm64-DLL — это попросту невозможно (как показано в таблице выше).
Случай 2: COM-сервер внутри процесса. COM-сервер in-proc — это просто DLL, поэтому таблица выше применяется напрямую. x64-клиент может использовать только x64- (или Arm64EC/Arm64X-) COM-DLL, и в момент, когда приложение станет нативным под Arm64, x64-COM-DLL перестанет загружаться. Если нужна поддержка обоих вариантов, либо делайте DLL в формате Arm64X, либо применяйте проверенный ещё с эпохи 32/64 бит приём — разделение на отдельные процессы с COM/IPC вне процесса (разнести на разные процессы и связать межпроцессным взаимодействием). Пересечение границы архитектур на границе процессов — исторически базовый подход.166
Случай 3: вы сами хостите плагин или являетесь плагином. Надстройки Excel, плагины бизнес-пакетов, промежуточное ПО для печати и любая другая форма, где «ваша DLL загружается в чужой процесс», должны соответствовать архитектуре хост-процесса. И наоборот, если ваше приложение само хостит плагины, нужно продумать зону влияния: перевод собственного приложения на нативный Arm64 «выкосит» все сторонние x64-плагины.
Кстати, узнать, к какой архитектуре относится конкретный бинарник, можно из командной строки разработчика.5
link /dump /headers MyLibrary.dll | findstr machine
# 8664 machine (x64) → x64
# 8664 machine (x64) (ARM64X) → включает Arm64EC
# AA64 machine (ARM64) → Arm64
# AA64 machine (ARM64) (ARM64X) → Arm64X
5. Случай .NET-приложений — ловушка AnyCPU и определение архитектуры
.NET (семейство Core) официально поддерживает Windows Arm64, и Arm64-версии Windows 11/10 прямо указаны как поддерживаемые ОС для .NET 8/9/10. Для публикации достаточно указать win-arm64 в качестве RID.177
<!-- csproj: публикация для нативного Arm64 -->
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers>
</PropertyGroup>
dotnet publish -r win-arm64 -c Release
Для приложения, состоящего только из управляемого кода, на этом перевод на нативный Arm64 практически завершён. JIT просто генерирует код Arm64, и правки исходников, как правило, не требуются. Для приложений на .NET Framework нативную поддержку Arm64 добавила версия 4.8.1 (для Arm64-машин под Windows 11; runtime 4.8.1 не поддерживает нативные Arm64-приложения на Arm-машинах с Windows 10). Приложение на Framework, оставшееся в сборке x64, считается работающим через эмуляцию.1819
Проблема — в сочетании, возникающем при вызове нативной DLL через P/Invoke. На Arm-машине давнее ощущение «это .NET-приложение, значит AnyCPU запустится где угодно» подводит.
- При запуске под Arm64-версией SDK/runtime .NET приложение по умолчанию работает как Arm64-процесс.8
- Процесс Arm64 не может загрузить x64-DLL (см. таблицу в разделе 4). То есть собственный AnyCPU-код остаётся нетронутым, но загрузка нативной x64-DLL, подключённой через
DllImport, завершается ошибкой.5 - И наоборот, приложение, опубликованное как
win-x64, работает целиком как x64-процесс и функционирует внутри эмуляции (вместе с нативной x64-DLL). В этом случае вы не получаете производительность нативного Arm64, но зато это конфигурация с максимальной совместимостью.12
То, что выглядит как «то работает, то не работает», обычно оказывается несовпадением архитектуры процесса и архитектуры его нативных зависимостей. Первым шагом при разборе такой ситуации сильно помогает код, который умеет сообщать, под какой архитектурой реально работает текущий процесс.
using System.Runtime.InteropServices;
// Архитектура самого процесса (X64, если работает под x64-эмуляцией)
Console.WriteLine($"Process: {RuntimeInformation.ProcessArchitecture}");
// Реальная архитектура ОС (Arm64 на Arm-машине)
Console.WriteLine($"OS: {RuntimeInformation.OSArchitecture}");
Стоит учесть: OSArchitecture начал возвращать «реальную архитектуру ОС, снимая эмуляцию» только начиная с .NET 7. До этого он возвращал X64 даже под эмуляцией, поэтому код на .NET 6 и старше, определяющий по этому API «это Arm-машина?», будет работать не так, как ожидается.2021
Сведём воедино контрольные точки, специфичные для .NET.
- Нативные ресурсы в NuGet-пакетах: пакет, содержащий только
runtimes/win-x64/native, при публикации подwin-arm64не даёт ничего взамен. Проверяйте содержимое пакета (или его репозиторий) на наличие ресурсов дляwin-arm64. Механизм RID как раз и существует для этой «маршрутизации платформо-специфичных ресурсов».7 - Состав SDK на машине разработки: на Arm-машине версия .NET для Arm64 обычно устанавливается в
C:\Program Files\dotnet\, а SDK для x64 — вC:\Program Files\dotnet\x64\, и они могут сосуществовать. То, под какой архитектурой реально выполняетсяdotnet run, зависит от того, куда указывают PATH или DOTNET_ROOT, — учитывайте это при тестировании.17 - Как читать исключение: несовпадение архитектуры в управляемой сборке проявляется как
BadImageFormatException(в официальном справочнике прямо указано, что условием возникновения служит «загрузка компонента, предназначенного для другой платформы»).22
6. Чек-лист готовности собственного приложения к Arm
На практике эффективно проверять в три этапа.
| Этап | Что сделать | Вывод |
|---|---|---|
| 1. Инвентаризация зависимостей | Составить список нативных DLL, вызываемых через P/Invoke, COM-компонентов, встроенных драйверов, расширений оболочки и NuGet-пакетов с нативными ресурсами | Если драйверов и расширений оболочки ноль, перспективы хорошие. Если есть — проверить поддержку Arm64 у каждого вендора34 |
| 2. Проверка на реальном устройстве под эмуляцией | Установить приложение как есть (в сборке x64) на Arm-машину (или Arm64-VM) и пройти основные бизнес-сценарии | Если работает, «оставить как x64» становится рабочим вариантом. Там, где не работает, подозревать несовпадение архитектуры в зависимости1 |
| 3. Рассмотреть нативную сборку под Arm64 | Для .NET — публикация под win-arm64, для C++ — добавить конфигурацию Arm64 и проверить, проходит ли сборка |
Типичная причина неудачи сборки — отсутствие Arm64-версии зависимой библиотеки. Рассмотреть обновление, замену или переход на Arm64EC23 |
Для этапов 2 и 3 есть следующие варианты тестового окружения.
- Реальное устройство: машина на Snapdragon вроде Copilot+ PC. Наличие хотя бы одного такого устройства даёт наибольшую уверенность, включая расследование проблем.12
- VM в Azure: в портале Azure можно отфильтровать образы по Arm64 и создать Arm64-VM с Windows 11 (рекомендуемый размер, например D2ps_v5, на базе Ampere Altra). Преимущество в том, что тестирование можно начать, не имея под рукой ни одной Arm-машины.9
- Локальная VM: официально распространяется ISO Windows 11 Arm64, и VM можно создать на Hyper-V на Arm-машине или на Mac с Arm-based Apple Silicon. Учтите, что на Hyper-V, работающем на x64-машине, создать Arm64-VM нельзя.10
Состояние поддержки сторонних продуктов можно проверить на сайте статуса, который публикует Microsoft (Works on Windows on Arm), а по проблемам совместимости бизнес-приложений (LOB) для корпоративных тарифов без дополнительной платы предоставляет поддержку программа App Assure. Наличие официального канала помощи до того, как всё упрётся в тупик «не работает», — полезный аргумент и при объяснении ситуации ИТ-отделу.1215
7. Практичное решение на сегодня — выбор между тремя вариантами
Готовность к Arm — это не только «полностью перевести на нативный код». Для многих бизнес-приложений практичнее поэтапный, ситуативный подход.
| Вариант | Когда подходит | На что обратить внимание |
|---|---|---|
| (а) Оставить x64 и работать под эмуляцией | Нет зависимости от драйверов и расширений оболочки, а производительности достаточно на практике | Prism (24H2+) уже улучшил производительность. Держите весь процесс единообразно в x64, не подмешивайте Arm64-бинарники15 |
| (б) Уточнить у вендора поддержку Arm64 или подождать | Нативная DLL/драйвер — сторонний продукт | Уточнить «планируется ли версия Arm64 (или Arm64X)». Для драйверов обходного пути, кроме ожидания, нет323 |
| (в) Нативная сборка под Arm64 | Чисто .NET-приложение или случай, когда Arm64-версии всех зависимостей уже доступны. Когда требования включают производительность или время автономной работы | Условие — публикация под win-arm64 плюс перевод на Arm64 всех нативных зависимостей. Если хостите плагины, учитывайте зону влияния75 |
Если объём кода на C++ велик, между (а) и (в) есть промежуточный вариант — Arm64EC. Он позволяет постепенно переводить в нативный код только собственный код, оставляя зависимые x64-DLL как есть, и служит официальным маршрутом для случаев «огромное x64-приложение нельзя перевести одним махом».523
Со стороны инструментов разработки существует нативная под Arm64 версия Visual Studio, а на Arm-машине доступен набор компилятора, способный собирать под Arm64, x64 и x86 одновременно. CI-сборки тоже можно получать кросс-компиляцией на существующей x64-машине сборки, что упрощает конфигурацию, где «только запуск тестов» переносится на реальное Arm-устройство или VM.2423
8. Итог
- Arm-версия Windows 11 умеет запускать x86/x64-приложения через встроенную в ОС эмуляцию, и начиная с 24H2 производительность дополнительно улучшена благодаря Prism. x64-эмуляция появилась начиная с Windows 11, а Windows 10 на Arm поддерживает только x86.
- Юрисдикция эмуляции — только пользовательский режим. Драйверы уровня ядра/UMDF/принтеров, а также «DLL, загружаемые в чужой процесс», вроде расширений оболочки, IME и средств специальных возможностей, обязательно требуют нативной сборки под Arm64. Работоспособность бизнес-приложения определяется не самим приложением, а этими окружающими зависимостями.
- Внутри процесса x64 и Arm64 сосуществовать не могут. Процесс x64/Arm64EC может загружать x64 и Arm64EC, процесс Arm64 — только Arm64. И COM-серверы внутри процесса, и плагины подчиняются этому же правилу: Arm64X — стандартный ответ для двойной поддержки, а COM/IPC вне процесса — стандартный ответ для пересечения границы процесса.
- .NET умеет публиковать нативно под
win-arm64, но AnyCPU-приложение, работающее на Arm64-runtime, выполняется как процесс Arm64, поэтому оно завершится ошибкой, если вызывает через P/Invoke только x64-версию нативной DLL. Для диагностики используйтеRuntimeInformation.ProcessArchitecture/OSArchitecture(последнее — начиная с .NET 7). - Порядок проверки — три этапа: «инвентаризация зависимостей → проверка на реальном устройстве в исходном виде под эмуляцией → при необходимости перевод на нативный Arm64». Тестовое окружение можно развернуть через Arm64-VM в Azure или ISO Arm64, а корпоративным клиентам доступна поддержка App Assure.
- На сегодня практичное решение — ситуативное сочетание: «если работает под эмуляцией — оставить как есть», «уточнить у вендоров драйверов и DLL статус поддержки», «перевести на нативный Arm64, если того требуют условия (для C++ возможна и поэтапная миграция через Arm64EC)».
Похожие статьи
- Вызов нативной DLL из C#: обёртка C++/CLI против P/Invoke
- Безопасный вызов Win32 API из C# — практическое руководство по P/Invoke (DllImport / LibraryImport / CsWin32)
- Как вызвать C# Native AOT DLL из C/C++
- Распространение Windows-приложения одним файлом — единый бинарник и пределы зависимости от ОС
- Практический пример COM-моста: вызов 64-битной DLL из 32-битного приложения
Смежные области консультаций
В Komura Software LLC мы занимаемся исследованием готовности существующих бизнес-приложений к Windows на Arm, проектированием миграции архитектуры приложений с нативными DLL и COM-интеграцией, а также анализом первопричин сбоев, возникающих только на Arm-машинах.
- Разработка приложений для Windows
- Техническая консультация и ревью архитектуры
- Расследование сбоев и анализ первопричин
- Контакты
Справочные материалы
-
Microsoft Learn, How emulation works on Arm. О том, что эмуляция встроена в ОС и способна запускать приложения без изменений, что Windows 11 поддерживает и x86, и x64, тогда как Windows 10 на Arm — только x86, о механизме JIT-преобразования и кэширования блоков инструкций x86, о Prism и его оптимизации под Snapdragon в Windows 11 24H2, а также о том, что x86-приложения получают перенаправление через WOW64, а x64-приложения обходятся без слоя WOW64 и используют системные бинарники в формате Arm64X. ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
Microsoft Learn, How emulation works on Arm. О том, что эмуляция поддерживает только код пользовательского режима, но не драйверы, и что компоненты уровня ядра необходимо компилировать под Arm64. ↩ ↩2
-
Microsoft Learn, Troubleshooting x86 desktop apps. О том, что все драйверы уровня ядра, драйверы UMDF и принтеров должны соответствовать архитектуре ОС, и что функции, зависящие от драйвера, остаются недоступны, даже если само приложение работает через эмуляцию. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Troubleshooting x86 desktop apps. О том, что приложения, загружающие собственную DLL в процесс Windows (расширения оболочки, IME, средства специальных возможностей), нужно пересобирать под архитектуру системы (Arm64), и что x86-приложения, запрещающие динамическую генерацию кода, не могут выполняться под эмуляцией. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Arm64EC - Build and port apps for native performance on Arm. О таблице совместимости, показывающей, что процессы x64/Arm64EC могут загружать бинарники x64 и Arm64EC, а процессы Arm64 — только бинарники Arm64, о том, что Arm64EC следует программным соглашениям x64 и может сосуществовать с x64-кодом в одном процессе, что бо́льшая часть кода ОС, загружаемого в процесс x64-приложения, — это Arm64EC, а также о способе проверки типа бинарника через link /dump /headers. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10
-
Microsoft Learn, Arm64X PE files. О том, что Arm64X объединяет код Arm64 и Arm64EC в одном PE-файле и может загружаться и в x64-, и в Arm64-процесс, а также о том, что 64-битные COM-серверы, плагины и инжектируемые DLL, вызываемые из приложений обеих архитектур, называются ситуациями, требующими Arm64X. ↩ ↩2 ↩3
-
Microsoft Learn, .NET RID Catalog. О том, что win-arm64 определён как RID для Windows, и что RID используется для маршрутизации платформо-специфичных ресурсов в NuGet-пакетах. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Windows on Arm. О том, что запуск под Arm64-версией SDK .NET по умолчанию выполняется как Arm64, что .NET 8 и новее поддерживают нативное выполнение под Arm64, и что существующие x64-приложения .NET работают через x64-эмуляцию ОС. ↩ ↩2 ↩3
-
Microsoft Learn, Quickstart: Create a Windows on Arm virtual machine in the Azure portal. О возможности отфильтровать образ Arm64 в портале Azure и создать Arm64-VM с Windows 11 (рекомендуемый размер, например D2ps_v5, на базе Ampere Altra). ↩ ↩2
-
Microsoft Learn, Windows 11 Arm ISO files overview. О том, что распространяется ISO Windows 11 Arm64, что VM можно создать на Hyper-V на Arm-машине или на Mac с Apple Silicon, и что Hyper-V на x64-оборудовании не поддерживает Arm64-VM. ↩ ↩2
-
Microsoft Learn, Develop AI applications for Copilot+ PCs. О том, что Copilot+ PC — новая категория оборудования на Windows 11 с NPU, способным выполнять более 40 триллионов операций в секунду (40+ TOPS). ↩
-
Microsoft Learn, Windows on Arm. О том, что Windows 10 поддерживала x86, а Windows 11 добавила выполнение x64 без изменений, что большинство Copilot+ PC используют серию Snapdragon X, а также о существовании сайта статуса поддержки Arm (Works on Windows on Arm) и сервиса App Assure Arm Advisory Service. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, How emulation works on Arm - Detecting emulation. О том, что приложению под эмуляцией видна информация об эмулируемом виртуальном процессоре, что GetNativeSystemInfo тоже ради совместимости возвращает эмулированное значение, и об использовании IsWow64Process2 или GetMachineTypeAttributes для определения Arm64-хоста. ↩
-
Microsoft Learn, Adjust emulation settings on Arm. О возможности изменить настройки эмуляции Prism (пресеты «по умолчанию/безопасный/строгий/очень строгий» и отдельные параметры) через вкладку «Совместимость» свойств exe-файла. ↩
-
Microsoft Learn, Arm-based Surface devices FAQ. Об ограничениях Arm-устройств (драйверы должны быть спроектированы под Arm, работоспособность периферии зависит от Arm64-драйверов, игры с OpenGL старше 3.3 или неподдерживаемым античитом, приложения-кастомизаторы вроде IME, необходимость проверки антивирусного ПО по каждому продукту), а также о поддержке совместимости через App Assure, включая LOB-приложения. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Process Interoperability. О том, что 64-битный процесс не может загрузить 32-битную DLL (и наоборот), и о стандартном приёме связи через границу архитектур с помощью COM-сервера вне процесса и RPC. ↩ ↩2
-
Microsoft Learn, Install .NET on Windows. О том, что Arm64-версии Windows 11/10 поддерживаются .NET 8/9/10, что на Arm-машине версия .NET для Arm64 устанавливается в C:\Program Files\dotnet\, а SDK для x64 — в C:\Program Files\dotnet\x64\, и что может потребоваться настройка PATH или DOTNET_ROOT. ↩ ↩2
-
Microsoft Learn, What’s new in .NET Framework. О том, что .NET Framework 4.8.1 добавила нативную поддержку Arm64 с преимуществом в производительности по сравнению с x64-кодом, работающим под эмуляцией на Arm64. ↩
-
Microsoft Learn, Develop Apps for Windows IoT Enterprise. О том, что нативная поддержка Arm64 в .NET Framework 4.8.1 предназначена для Windows 11, и что runtime 4.8.1 не поддерживает нативные Arm64-приложения на устройствах с Windows 10. ↩
-
Microsoft Learn, RuntimeInformation.OSArchitecture under emulation. О том, что начиная с .NET 7 OSArchitecture стал возвращать Arm64 даже для процесса под эмуляцией на Windows Arm64 (ранее возвращалось X64), и что для архитектуры самого процесса следует использовать ProcessArchitecture. ↩
-
Microsoft Learn, RuntimeInformation.ProcessArchitecture Property / RuntimeInformation.OSArchitecture Property. Об API для получения архитектуры выполняемого процесса и реальной архитектуры ОС. ↩
-
Microsoft Learn, BadImageFormatException Class. О том, что BadImageFormatException возникает, когда компонент приложения предназначен для другой платформы (загрузка сборки несовпадающей архитектуры). ↩
-
Microsoft Learn, Add Arm support to your Windows app. О типичных препятствиях для сборки под Arm64 (неподдерживаемые зависимые библиотеки, архитектурно-специфичный код, драйверы уровня ядра) и способах их устранения, о варианте пересборки через Arm64EC с сохранением зависимостей от x64, о способах получить Arm-устройство или VM для тестирования, а также о сочетании кросс-компилированных сборок с тестированием в среде Arm. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Visual Studio on Arm-powered devices. О том, что нативная под Arm64 версия Visual Studio поддерживает разработку на .NET/C++, и что набор инструментов MSVC, доступный на Arm64-хосте, может собирать под Arm64, x64 и x86. ↩
Похожие статьи
Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.
Безопасный вызов Win32 API из C# — практическое руководство по P/Invoke (DllImport / LibraryImport / CsWin32)
Разбираем практические аспекты вызова Win32 API из C# через P/Invoke: разницу между DllImport и LibraryImport, автогенерацию сигнатур чер...
Если ваше Windows-приложение приняли за вирус — как реагировать на ложные срабатывания Microsoft Defender и жить с влиянием на производительность
Разбираем правильный порядок действий, если Microsoft Defender ложно определяет ваше Windows-приложение как вредоносное: как устроена сов...
Спящий режим, гибернация, Modern Standby и долго работающие приложения — как проектированием предотвратить «остановилось ночью»
Разбираем, почему долго работающее Windows-приложение оказывается «остановленным к утру», начиная с различий между спящим режимом S3, гиб...
MAX_PATH и подводные камни путей/имён файлов в Windows — лимит 260 символов, зарезервированные имена, конечная точка, регистр
Разбираем ограничения путей и имён файлов, которые часто стоят за классической ошибкой «файл не найден». Рассматриваем состав лимита MAX_...
Подводные камни сетевых дисков и UNC-путей ── как бизнес-приложения работают с файловым сервером (общей папкой)
Разбираем типичные проблемы, возникающие при выводе данных и мониторинге общей папки из бизнес-приложения: почему буква диска (Z:) не вид...
Связанные темы
Эти страницы показывают тему статьи в более широком контексте услуг и решений.
Технические темы Windows
Раздел о разработке Windows, расследовании сбоев и использовании существующих активов.
Миграция ActiveX
Решения о сохранении, обёртке или замене компонентов COM / ActiveX / OCX.
Услуги по этой теме
Статья напрямую связана со следующими услугами.
Разработка приложений для Windows
Бизнес-приложения, интеграция оборудования и средства связи — от требований до разработки.
Использование и перенос существующих активов
Помогаем использовать и переносить активы COM / ActiveX / OCX и зависимости 32/64 бит.
Частые вопросы
Вопросы, которые часто возникают при консультациях по теме статьи.
- Заработает ли обычное x64-бизнес-приложение на Windows на Arm?
- В большинстве случаев да. В Windows 11 на Arm встроена эмуляция, запускающая x86/x64-приложения без изменений, а начиная с Windows 11 24H2 новый эмулятор Prism дополнительно улучшил производительность. Однако эмуляция покрывает только пользовательский режим — драйверы уровня ядра, а также расширения оболочки и IME, которые загружаются в другие процессы вроде Explorer, обязательно требуют нативной сборки под Arm64. Стоит думать об этом не как о вопросе к самому приложению, а как о вопросе к тому, что к нему подвешено.
- Может ли x64-exe вызвать Arm64-DLL?
- Нет. Смешивать x64- и Arm64-бинарники в пределах одного процесса нельзя: процесс x64 (или Arm64EC) может загружать только бинарники x64 и Arm64EC, а процесс Arm64 — только бинарники Arm64. Обратное направление (Arm64-exe вызывает x64-DLL) точно так же невозможно. Если действительно нужна одна-единственная DLL, поддерживающая оба варианта, вариантами остаются Arm64X — формат, позволяющий Arm64- и Arm64EC-коду сосуществовать в одном файле, — либо разделение на отдельные процессы, связанные через IPC.
- Что нужно, чтобы подготовить .NET-приложение к Arm64?
- .NET 6 и новее официально поддерживают Windows Arm64, и нативный исполняемый файл под Arm64 можно получить, просто опубликовав приложение с RID (идентификатором среды выполнения) win-arm64. Для чисто управляемого кода на этом работа практически заканчивается, но если приложение вызывает нативную DLL через P/Invoke или использует NuGet-пакет с нативными ресурсами, нужно проверить наличие Arm64-версии для каждого из них. Для приложений на .NET Framework нативное выполнение на Arm64 в Windows 11 поддерживает версия 4.8.1.
- Какое ПО не работает на Windows на Arm?
- На первом месте — ПО с драйверами уровня ядра. Драйверы не эмулируются, поэтому VPN-клиенты, средства защиты, виртуальные устройства и авторизация через USB-донглы не заработают без Arm64-драйвера. Далее идут расширения оболочки, IME и средства специальных возможностей, загружающие DLL в процессы самой ОС, приложения, запрещающие динамическую генерацию кода, а также игры, зависящие от устаревшего OpenGL или античит-драйверов. Работоспособность периферии тоже определяется наличием Arm64-драйвера.
Об авторе
Страница с профилем автора статьи.
Го Комура
Представитель KomuraSoft LLC
Специализируется на разработке программного обеспечения для Windows, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.
Публичные ссылки