「下个月要换的新电脑,是所谓的 Copilot+ PC,我们公司的业务系统能在上面运行吗?」── 随着搭载 Snapdragon 芯片的 PC 在企业中的普及,越来越多的开发公司和信息系统部门开始被问到这个问题。产品目录上写着「现有应用也可以通过仿真运行」。但自家的业务应用,在 C# 界面背后 P/Invoke 了供应商提供的原生 DLL,报表通过 COM 组件生成,甚至还装有专用设备的驱动程序。老实说,面对「能运行吗?」这个问题,恐怕很难当场给出答案。
先说结论:「应用本体大多能运行,危险的是应用周边的那些家伙」。Windows 11 的仿真能以相当高的精度照顾好 x86/x64 的用户模式代码,但驱动程序、Shell 扩展、进程内架构混用这些「仿真管辖范围之外」的领域是明确存在的。而这个管辖范围之外的领域,恰恰正是业务应用长期以来喜欢使用的领域。
本文将围绕 Windows on Arm 仿真的原理与局限、「进程内不能混用 x64 与 Arm64」这一基本原则、.NET 应用特有的组合问题,以及用于确认「自家应用能否在 Arm 机器上运行」的实务步骤,在可以通过 Microsoft Learn 核实的范围内进行梳理。
1. 先说结论
- 纯托管(.NET)应用,或普通的 x86/x64 桌面应用,在 Arm 版 Windows 11 的仿真下基本都能运行。仿真是操作系统内置的功能,无需修改应用,也无需附加组件。1
- 仿真只能照顾用户模式代码。内核模式驱动程序不会被仿真,必须是 Arm64 原生版本。UMDF 驱动程序和打印机驱动程序也需要与操作系统的架构一致。23
- Shell 扩展、输入法(IME)、辅助技术等”会被加载到其他进程(如 Explorer)中的 DLL”,同样需要重新编译为与系统一致的 Arm64 版本。仿真无法拯救这类组件。4
- 同一个进程内无法混用 x64 与 Arm64。x64/Arm64EC 进程只能加载 x64 和 Arm64EC 的二进制文件,Arm64 进程只能加载 Arm64 的二进制文件。x64 的 exe 无法调用 Arm64 的 DLL,反过来也不行。5
- 用于在单个文件内跨越这一限制的机制,就是 Arm64EC(能与 x64 在同一进程内共存的原生 Arm64 代码)与 Arm64X(让 Arm64 与 Arm64EC 代码共存于一个 PE 文件中、可被两种进程加载的二进制格式)。会被两种架构调用的 COM 进程内服务器或插件,正是 Arm64X 大显身手的场景。56
- .NET 正式支持 Arm64,可以用 RID
win-arm64进行原生发布。另一方面,如果让 AnyCPU 应用在 Arm64 的 .NET 运行时上运行,进程会以 Arm64 方式运行,因此会出现”P/Invoke 了仅有 x64 版本的原生 DLL 就会加载失败”这样的组合问题。785 - 测试环境除了实体机(Copilot+ PC 等)之外,还可以用 Azure 上的 Windows 11 Arm64 VM,以及可在 Arm 机器上的 Hyper-V 或 Apple Silicon Mac 上使用的 Windows 11 Arm64 ISO 来搭建。※ x64 机器上的 Hyper-V 无法创建 Arm64 VM。910
2. 什么是 Arm 版 Windows ── 搭载 Snapdragon 的 PC 与 Prism
Arm 版 Windows 是运行在 Arm64 处理器上的 Windows。自 2024 年以来,「Copilot+ PC」── 搭载每秒可执行超过 40 万亿次运算(40+ TOPS)的 NPU 的 Windows 11 PC 新品类 ── 中的大多数机型都采用了基于 Arm 的 Snapdragon X 系列芯片,这使得开发者不得不正视这一存在。1112
支撑与现有应用兼容性的,是操作系统内置的仿真功能。其原理要点如下。1
- 仿真器会将 x86/x64 指令块 JIT 编译 为 Arm64 指令,并按模块缓存转换结果,从而加快第二次及以后的启动速度。
- Windows 11 可以同时仿真 x86 和 x64。Windows 10 on Arm 只能仿真 x86,因此讨论 x64 业务应用的场景实际上是以 Windows 11 为前提的。
- Windows 11 24H2 引入了新的仿真器 Prism,相比以往性能有所提升,CPU 占用也有所下降。Prism 针对 Qualcomm Snapdragon 进行了优化。
- 32 位(x86)应用运行在与 x64 版 Windows 相同的 WOW64 层之上,会受到文件系统・注册表重定向的影响。而 x64 应用没有 WOW64 层——由于系统二进制文件是以后文将介绍的 Arm64X 格式编译的,x64 应用可以在不经过重定向的情况下访问整个操作系统(文件系统和注册表均如此)。1
在仿真下运行的应用所看到的 CPU 信息,是「被仿真的虚拟处理器」的信息。出于兼容性考虑,即使是 GetNativeSystemInfo 也会返回被仿真后的值,因此如果想知道主机是否真的是 Arm64,需要使用 IsWow64Process2 或 GetMachineTypeAttributes。13
另外,针对在仿真下出现问题的应用,Windows 也提供了通过右键点击 exe → 属性 → 兼容性选项卡来更改 仿真设置(默认/安全/严格/非常严格等预设,以及各项细节设置)的机制。这是一种以牺牲性能来换取兼容性的调整方式,但作为”以前在旧版 Windows on Arm 上明明能运行”这类情况的退路,值得记住。14
3. 仿真下能运行与不能运行的内容
对”能运行吗?”这一问题的回答,取决于依赖物的种类,而不是应用本体。整理成判断表如下。
| 分类 | 在 Arm 版 Windows 11 上的表现 | 依据・备注 |
|---|---|---|
| x86/x64 用户模式应用(exe + 同架构的完整 DLL 集) | 通过仿真运行 | 无需修改・无需额外安装1 |
| .NET(托管)应用 | 可运行(也可进行 Arm64 原生执行) | 参见第 5 章8 |
| 内核模式驱动程序 | 无法运行。必须是 Arm64 原生版本 | 内核中不存在仿真23 |
| UMDF 驱动程序・打印机驱动程序 | 必须与操作系统一致,为 Arm64 | 即使应用本体能通过仿真运行,依赖驱动程序的功能也无法使用3 |
| Shell 扩展・IME・辅助技术(被加载到其他进程中的 DLL) | 需要重新编译为 Arm64 | Explorer 右键菜单、云存储图标显示等4 |
| 禁止动态代码生成的 x86 应用 | 无法在仿真下运行 | 仿真器会在运行时生成 Arm64 指令,因此需要放宽 ProcessDynamicCodePolicy4 |
| 依赖老旧 OpenGL・反作弊驱动程序的游戏 | 有时无法运行 | 超出 OpenGL 3.3 的版本,或不支持 Arm 的反作弊系统会成为障碍15 |
| 外围设备(打印机、扫描仪、专用设备) | 取决于是否存在 Arm64 驱动程序 | 需要操作系统自带或厂商提供的 Arm64 驱动程序15 |
| 杀毒软件与”改变 Windows 使用体验”类软件 | 需要逐一确认 | Arm 支持已有很大进展,但仍建议按产品逐一确认15 |
换成业务应用的语境来说,危险信号大致如下。
- VPN 客户端、资产管理代理、安全产品 ── 这些本质上是内核驱动程序的集合体。需要向厂商确认是否存在 Arm64 支持版本。
- USB 加密狗认证、专用设备(测量仪器・支付终端等) ── 设备驱动程序是否提供 Arm64 版本,是决定生死的关键。
- “给 Explorer 添加功能”类工具 ── 由于 Shell 扩展会被加载到 Arm64 版本的 Explorer 中,如果仍是 x64 版本就无法生效。
- 即使应用本体不属于上述情况,安装程序中捆绑了驱动程序 的情形(例如采用虚拟打印机驱动程序方式实现的 PDF 输出)也会遇到同样的问题。
4. 进程内无法混用架构 ── P/Invoke 与 COM 的现实
早在 32 位时代就有一条铁律:「64 位进程无法加载 32 位 DLL」16。Arm 版 Windows 同样存在结构相同的铁律。官方文档将加载规则整理如下。5
| 进程架构 | x64 DLL | Arm64EC DLL | Arm64 DLL | Arm64X DLL |
|---|---|---|---|---|
| x64 / Arm64EC 进程 | 可加载 | 可加载 | 不可 | 可加载 |
| Arm64 进程 | 不可 | 不可 | 可加载 | 可加载 |
这里出现的两种机制,正是思考 Arm 适配设计时的关键。
- Arm64EC(Emulation Compatible)是一种通过遵循 x64 的调用约定、栈使用方式和数据布局,从而 能与同一进程内以仿真方式运行的 x64 代码共存 的原生 Arm64 代码 ABI。当 x64 应用在 Windows 11 on Arm 上运行时,加载到该进程中的操作系统代码大多已经是用 Arm64EC 编译的,会在应用毫不知情的情况下以原生速度运行。即使依赖的 DLL 仍是 x64,也可以先从自己的代码开始逐步 Arm64EC 化以提升性能,实现分阶段迁移。5
- Arm64X 是一种让传统 Arm64 代码与 Arm64EC 代码 共存于同一个 PE 文件 中的二进制格式。根据加载它的进程是 x64 还是 Arm64,它会分别表现为 x64 的 DLL 或 Arm64 的 DLL,因此适用于 可能被两种架构的进程调用的 DLL。官方文档列举了需要 Arm64X 的场景,包括”同时被 x64 和 Arm64 应用调用的 64 位 COM 服务器”“可被 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,Windows 11/10 的 Arm64 已被明确列为 .NET 8/9/10 的受支持操作系统。发布时只需将 RID 指定为 win-arm64 即可。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 应用,.NET Framework 4.8.1 增加了 Arm64 原生支持(面向 Windows 11 的 Arm64 机器;4.8.1 运行时在 Windows 10 的 Arm 机器上不支持原生 Arm64 应用)。仍以 x64 方式构建的 Framework 应用,会被当作通过仿真运行。1819
问题在于 P/Invoke 原生 DLL 时出现的组合问题。在 Arm 机器上,”反正是 .NET 应用,AnyCPU 到哪都能跑”这种多年来的经验会被打破。
- 在 Arm64 的 .NET SDK/运行时下执行时,应用 默认会以 Arm64 进程的方式运行。8
- Arm64 进程无法加载 x64 的 DLL(见第 4 章的表格)。也就是说,即使 自家 AnyCPU 代码本身完好无损,
DllImport引用的 x64 原生 DLL 也会加载失败。5 - 反过来,以
win-x64方式发布的应用,整个进程都会是 x64,会在仿真环境中运行(连同 x64 原生 DLL 一起)。这种配置无法获得 Arm64 原生性能,但兼容性是最高的。12
看起来”时而能运行、时而不能运行”的真相,多半是 进程的架构与原生依赖物的架构不一致。作为排查的第一步,如果能通过代码确认正在运行的进程究竟是以什么架构在跑,调查工作会轻松很多。
using System.Runtime.InteropServices;
// プロセス自身のアーキテクチャ(x64エミュレーション下なら X64)
Console.WriteLine($"Process: {RuntimeInformation.ProcessArchitecture}");
// OS本来のアーキテクチャ(Arm機なら Arm64)
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 机器上,Arm64 版 .NET 通常安装在
C:\Program Files\dotnet\下,而 x64 版 SDK 安装在C:\Program Files\dotnet\x64\下,两者可以共存。dotnet run实际以哪种架构执行,取决于 PATH 或 DOTNET_ROOT 指向哪一个,测试时请留意这一点。17 - 异常的解读方式:托管程序集的架构不一致会以
BadImageFormatException的形式出现(官方参考文档中也明确将”加载面向不同平台的组件”列为触发条件之一)。22
6. 自家应用的 Arm 适配自查清单
在实务中,按以下三个阶段来确认会比较高效。
| 阶段 | 要做的事 | 判断 |
|---|---|---|
| ① 依赖清单梳理 | 列出所有 P/Invoke 的原生 DLL、COM 组件、随附的驱动程序、Shell 扩展,以及包含原生资源的 NuGet 包 | 如果驱动程序、Shell 扩展 为零,则前景乐观。如果存在,需确认各厂商的 Arm64 支持情况34 |
| ② 在仿真下进行实机验证 | 保持 x64 构建不变,安装到 Arm 机器(或 Arm64 VM)上,走一遍主要业务场景 | 如果能运行,”保持 x64 方式运营”就成为一个选项。无法运行的部分,应怀疑是依赖物与架构不一致所致1 |
| ③ 考虑 Arm64 原生构建 | .NET 应用发布为 win-arm64,C++ 应用则添加 Arm64 配置,确认能否构建通过 |
构建失败的典型原因是依赖库没有 Arm64 版本。可考虑更新、替换,或利用 Arm64EC23 |
用于②③阶段的测试环境,有以下几种选择。
- 实体机:Copilot+ PC 等搭载 Snapdragon 的机型。手头有一台,连排障调查在内都是最可靠的方式。12
- Azure VM:在 Azure 门户中按 Arm64 筛选镜像,即可创建 Windows 11 的 Arm64 VM(推荐规格如基于 Ampere Altra 的 D2ps_v5 等)。其优点是即使手头一台 Arm 机器都没有,也能开始测试。9
- 本地 VM:Windows 11 Arm64 的 ISO 已官方发布,可以在 Arm 机器上的 Hyper-V,或基于 Arm 的 Apple Silicon Mac 上创建 VM。请注意,x64 机器上的 Hyper-V 无法创建 Arm64 VM。10
第三方产品的支持情况,可以在 Microsoft 提供的状态查询网站(Works on Windows on Arm)上确认;此外,针对业务应用(LOB)的兼容性问题,符合条件的企业方案还可以免费获得 App Assure 项目的支持。在陷入”因为无法运行而束手无策”之前,还有官方渠道可用──这一点作为向信息系统部门说明情况的材料也很有说服力。1215
7. 当前阶段的现实解法 ── 三种选择的搭配使用
Arm 适配并不是”全部原生化”这一唯一选项。相反,对许多业务应用而言,分阶段搭配使用才是现实的解法。
| 选择 | 适合的情形 | 注意事项 |
|---|---|---|
| (a) 保持 x64,在仿真下运营 | 不依赖驱动程序・Shell 扩展,且性能已经足够实用的情况 | Prism(24H2 及以后)已经改善了性能。整个进程要统一为 x64,不要混入 Arm64 二进制文件15 |
| (b) 确认厂商的 Arm64 支持情况・等待 | 原生 DLL・驱动程序是第三方产品的情况 | 需要确认”是否计划提供 Arm64 版(或 Arm64X 版)DLL”。驱动程序除了等待没有别的绕过办法323 |
| (c) Arm64 原生构建 | 纯 .NET 应用,或依赖项的 Arm64 版本已经齐全的情况。对性能・续航有要求的情况 | 需要以 win-arm64 发布,并将全部原生依赖 Arm64 化。如果托管插件,需注意影响范围75 |
如果 C++ 资产规模较大,还有介于 (a) 和 (c) 之间的 Arm64EC。它可以在保留 x64 依赖 DLL 不变的情况下,只对自己的代码分阶段进行原生化,是”无法一次性迁移庞大的 x64 应用”这类情况的官方路线。523
在开发环境方面,Visual Studio 提供了 Arm64 原生版本,并配备了可在 Arm 机器上以 Arm64/x64/x86 为目标的完整编译器工具集。CI 用的构建也可以在现有的 x64 构建机器上通过交叉编译完成,因此很容易搭建出”只把测试执行放到 Arm 实体机/VM 上”的配置。2423
8. 总结
- Arm 版 Windows 11 可以通过操作系统内置的仿真运行 x86/x64 应用,24H2 及以后版本还通过 Prism 进一步改善了性能。x64 仿真是从 Windows 11 才开始支持的,Windows 10 on Arm 只支持 x86。
- 仿真的管辖范围仅限于用户模式。内核模式/UMDF/打印机的各类驱动程序,以及 Shell 扩展・IME・辅助技术这类”会被加载到其他进程中的 DLL”,都必须是 Arm64 原生版本。业务应用能否运行,并非取决于应用本体,而是取决于这些周边依赖。
- 进程内无法混用 x64 与 Arm64。x64/Arm64EC 进程可以加载 x64 加 Arm64EC,Arm64 进程只能加载 Arm64。COM 进程内服务器与插件都遵循同样的规则──需要同时支持两种架构时,Arm64X 是标准做法;需要跨越进程边界时,进程外 COM/IPC 是标准做法。
- .NET 可以用
win-arm64进行原生发布,但运行在 Arm64 运行时上的 AnyCPU 应用会以 Arm64 进程方式运行,因此如果 P/Invoke 了仅有 x64 版本的原生 DLL 就会失败。可以用RuntimeInformation.ProcessArchitecture/OSArchitecture(.NET 7 及以后版本)进行排查。 - 确认步骤分为三个阶段:”依赖清单梳理 → 保持 x64 在仿真下进行实机确认 → 视需要进行 Arm64 原生化”。测试环境可以用 Azure 的 Arm64 VM 或 Arm64 ISO 搭建,企业还可以获得 App Assure 的支持。
- 当前阶段的现实解法是灵活搭配使用:”如果在仿真下能运行就保持不变”“确认驱动程序・DLL 厂商的支持情况”“视需求进行 Arm64 原生化(C++ 也可以采用 Arm64EC 分阶段迁移)”。
相关文章
- 从 C# 调用原生 DLL:C++/CLI 包装 vs P/Invoke
- 从 C# 安全调用 Win32 API ── P/Invoke 实务指南(DllImport / LibraryImport / CsWin32)
- 从 C/C++ 调用 C# Native AOT DLL 的方法
- Windows 应用的单文件分发 - 单一二进制文件与操作系统依赖的局限
- 从 32bit 应用调用 64bit DLL 的 COM 桥接实例
相关咨询领域
合同会社小村软件(KomuraSoft LLC)承接调查现有业务应用是否能适配 Arm 版 Windows、设计包含原生 DLL・COM 交互在内的应用架构迁移方案,以及排查”仅在 Arm 机器上无法运行”类故障的原因分析。
参考链接
-
Microsoft Learn, How emulation works on Arm。关于仿真是操作系统内置功能、可以运行未修改的应用,Windows 11 同时支持 x86/x64 而 Windows 10 on Arm 仅支持 x86,x86 指令块的 JIT 转换与缓存机制,Windows 11 24H2 中 Prism 针对 Snapdragon 的优化,以及 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 进程中的应用(Shell 扩展・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 被定义为 Windows 的 RID,以及 RID 被用于分发 NuGet 包中平台专属资源。 ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Windows on Arm。关于在 Arm64 版 .NET SDK 下执行时默认以 Arm64 方式运行,.NET 8 及以后版本支持原生 Arm64 执行,以及现有的 x64 .NET 应用会通过操作系统的 x64 仿真运行。 ↩ ↩2 ↩3
-
Microsoft Learn, Quickstart: Create a Windows on Arm virtual machine in the Azure portal。关于可以在 Azure 门户中筛选 Arm64 镜像来创建 Windows 11 的 Arm64 VM(推荐规格如基于 Ampere Altra 的 D2ps_v5)。 ↩ ↩2
-
Microsoft Learn, Windows 11 Arm ISO files overview。关于 Windows 11 Arm64 的 ISO 已经发布,可以在 Arm 机器上的 Hyper-V 或 Apple Silicon Mac 上创建 VM,以及 x64 硬件上的 Hyper-V 不支持 Arm64 VM。 ↩ ↩2
-
Microsoft Learn, Develop AI applications for Copilot+ PCs。关于 Copilot+ PC 是搭载每秒可执行超过 40 万亿次运算(40+ TOPS)的 NPU 的 Windows 11 硬件新品类。 ↩
-
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 出于兼容性也会返回被仿真后的值,以及检测 Arm64 主机应使用 IsWow64Process2 或 GetMachineTypeAttributes。 ↩
-
Microsoft Learn, Adjust emulation settings on Arm。关于可以从 exe 属性的兼容性选项卡更改 Prism 的仿真设置(默认/安全/严格/非常严格等预设及各项细节设置)。 ↩
-
Microsoft Learn, Arm-based Surface devices FAQ。关于 Arm 设备的限制事项(驱动程序必须为 Arm 专门设计、外围设备取决于 Arm64 驱动程序、超出 OpenGL 3.3 或反作弊不受支持的游戏、IME 等定制类应用、需要逐一确认的杀毒软件),以及包括 LOB 应用在内的 App Assure 兼容性支持。 ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Process Interoperability。关于 64 位进程无法加载 32 位 DLL(反之亦然),以及通过进程外 COM 服务器与 RPC 跨越架构边界通信这一惯用手法。 ↩ ↩2
-
Microsoft Learn, Install .NET on Windows。关于 Windows 11/10 的 Arm64 是 .NET 8/9/10 的受支持对象,Arm 机器上 Arm64 版 .NET 安装在 C:\Program Files\dotnet\,x64 版 SDK 安装在 C:\Program Files\dotnet\x64\,以及可能需要调整 PATH 或 DOTNET_ROOT。 ↩ ↩2
-
Microsoft Learn, What’s new in .NET Framework。关于 .NET Framework 4.8.1 增加了 Arm64 原生支持,且在性能上优于在 Arm64 上以仿真方式运行的 x64 代码。 ↩
-
Microsoft Learn, Develop Apps for Windows IoT Enterprise。关于 .NET Framework 4.8.1 的原生 Arm64 支持面向 Windows 11,而 4.8.1 运行时并不支持 Windows 10 设备上的原生 Arm64 应用。 ↩
-
Microsoft Learn, RuntimeInformation.OSArchitecture under emulation。关于从 .NET 7 开始,即使是 Windows Arm64 上的仿真进程,OSArchitecture 也会返回 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 构建的典型因素(不受支持的依赖库、架构相关代码、内核驱动程序)及应对方法,保留 x64 依赖同时用 Arm64EC 重新构建的选项,获取测试用 Arm 实体机・VM 的方法,以及交叉编译构建与 Arm 环境下测试相结合的方式。 ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Visual Studio on Arm-powered devices。关于可以使用 Arm64 原生版 Visual Studio 进行 .NET/C++ 开发,以及在 Arm64 主机上提供以 Arm64/x64/x86 为目标的 MSVC 工具集。 ↩
相关文章
共享相同标签的最新文章。可以围绕相近的主题进一步加深理解。
网络驱动器与 UNC 路径的陷阱 ── 业务应用中处理文件服务器(共享文件夹)的实务
本文整理业务应用向共享文件夹输出、监控时的常见故障:驱动器号(Z:)为何在服务中不可见、各执行账户所需的权限、错误 1219,以及 FileSystemWatcher 的注意事项。
Windows 应用的任务栏托盘常驻与 Toast 通知 —— NotifyIcon 的坑与 AppNotification 的选型
本文整理了将业务 Windows 应用常驻在任务栏托盘(通知区域)并通过 Toast 通知告知用户的实现要点。内容涵盖 NotifyIcon 的正确用法与「关闭后驻留托盘」的设计、资源管理器重启后的重新注册、三种 Toast API(Windows App SDK AppN...
VB6 应用能用到什么时候 ── 运行时支持现状与务实的 .NET 迁移做法
VB6 应用程序到底能用到什么时候?本文整理 VB6 运行时的支持政策(Windows 11 也在支持范围内)与 IDE 支持早已终止这一不对称现状,并以实务指南的形式说明全面重写、自动转换、分阶段迁移的判断表、迁移前的资产盘点、VB6 与 .NET 的不兼容之处,以及 C...
业务应用程序的日本年号・法定节假日・结算日处理 —— 抗改元设计与 JapaneseCalendar・营业日计算实务
报表要显示「令和8年」、营业日计算要排除法定节假日、20日结算次月末付款——日本业务应用程序特有的日期处理背后,隐藏着「日后会变动的规格」:改元、法定节假日的法规修订、月末的进位。本文整理了用 JapaneseCalendar 显示年号、抗改元的设计方式,法定节假日不可写死...
防止 Windows 应用程序重复启动 ── 命名 Mutex 与重复执行时的窗口前置
整理业务型 Windows 应用程序的常见需求——「不让同一个应用程序启动两次」——如何用命名 Mutex 来实现。涵盖 Global\ 与 Local\ 命名空间差异在 RDP 环境中的陷阱、拥有线程限制与 AbandonedMutexException、在 SetFor...
相关主题
与本文相近的主题页面。以本文为起点,可以进一步了解相关服务和其他文章。
Windows 技术主题
汇整 KomuraSoft LLC 关于 Windows 开发、故障调查与既有资产活用文章的主题中心。
ActiveX 迁移
整理保留、包装或替换 COM / ActiveX / OCX 资产的阶段性判断的主题页面。
与本主题相关的服务
本文与以下服务页面相关联,欢迎从最接近的入口查看。
Windows 应用程序开发
支持包含常驻处理、设备联动、运行日志与可维护结构的 Windows 桌面应用程序。
技术咨询 & 设计评审
协助梳理设计方向、架构边界、生命周期责任,以及既有 Windows 资产的处理方式。
常见问题
汇总了咨询这一主题时常见的问题。
- Arm 版 Windows 上普通的 x64 业务应用能运行吗?
- 多数情况下可以运行。Windows 11 on Arm 内置了可以无修改运行 x86/x64 应用的仿真功能,Windows 11 24H2 及以后版本还引入了名为 Prism 的新仿真器,性能也有所提升。不过,仿真只能照顾到用户模式代码:内核模式驱动程序,以及会被加载到 Explorer 等其他进程中的 Shell 扩展、输入法(IME)之类的组件,都必须是 Arm64 原生版本。可以理解为:能否运行,取决于应用本体周边的依赖,而不是应用本体本身。
- x64 的 exe 能调用 Arm64 的 DLL 吗?
- 不能。同一个进程内无法混用 x64 与 Arm64 的二进制文件:x64(或 Arm64EC)进程只能加载 x64 和 Arm64EC 的二进制文件,Arm64 进程只能加载 Arm64 的二进制文件。反过来(从 Arm64 的 exe 调用 x64 的 DLL)同样不可行。如果确实需要一个同时兼容两种架构的 DLL,可以使用让 Arm64 与 Arm64EC 代码共存于同一文件的 Arm64X 格式,或者拆分为多个进程、通过 IPC 进行协作。
- 要让 .NET 应用支持 Arm64,需要做什么?
- .NET 6 及以后版本正式支持 Windows Arm64,只需在发布(publish)时指定 RID(运行时标识符)win-arm64,即可生成 Arm64 原生可执行文件。如果是纯托管代码的应用,这样基本就完成了;但如果 P/Invoke 了原生 DLL,或者使用了包含原生资源的 NuGet 包,就需要逐一确认是否存在对应的 Arm64 版本。对于 .NET Framework 应用,4.8.1 支持在 Windows 11 上进行 Arm64 原生执行。
- 在 Arm 版 Windows 上,哪些软件无法运行?
- 首当其冲的是包含内核模式驱动程序的软件。由于驱动程序不会被仿真,VPN 客户端、安全产品、虚拟设备、USB 加密狗认证等,如果没有 Arm64 驱动程序就无法运行。其次是像 Shell 扩展、输入法(IME)、辅助技术这类会将 DLL 加载到 OS 侧进程中的软件,禁止动态代码生成的应用,以及依赖老旧 OpenGL 或反作弊驱动程序的游戏等。外围设备是否可用,同样取决于是否存在 Arm64 驱动程序。
作者简介
本文作者的个人简介页面。
Go Komura
小村软件有限公司 代表
以 Windows 软件开发、技术咨询与故障排查为中心,擅长难以复现的故障调查,以及既有资产仍在运行的项目。