支持 ARM 上的 Windows 10 桌面应用程序 - MFC 和 COM 和 OPOS 是否有效?
我试图了解将在 x86 Windows 10 上运行的 C++ MFC 应用程序移植到配备 Qualcomm Snapdragon 处理器的 ARM Windows 10 设备的障碍.
32位应用具有以下特点:
- 使用 C++ 的 MFC 用于用户界面
- 用于业务逻辑的 C
- 源代码分为大约 30 个不同的项目,一些静态库,一些 DLL,一些 EXE
- 依靠 Windows API 实现多线程、信号量、互斥体、密码学
- 使用来自第三方提供商的 COM 对象、OPOS 服务对象和 OPOS 控制对象
- 依赖于使用 ADO 数据库的 SQL Server Express 本地实例
此应用程序可与面向 x86 和 Windows 10 的 Visual Studio 2015/2017/2019 完美编译.
我的问题是:使用 Snapdragon 处理器将此应用程序迁移到 ARM Windows 10 可能存在哪些障碍?
第二个问题是什么是合适的低成本 ARM Windows 10 设备?惠普、三星和联想的大多数 Windows 10 ARM Snapdragon 设备的价格似乎都在 800 美元以上,我想要更便宜的,比如不到 200 美元.
附带问题:Snapdragon 410 处理器能否用于初始测试和兼容性检查.我将 Arrow 的 DragonBoard 410C 视为一种低成本的测试平台.
在尝试各种方法来构建 ARM64 MFC 时,我遇到了 MSB8041 链接器错误的问题,请参阅 MSB8041:此项目需要 MFC 库.
我对 Visual Studio 2019 安装进行了几次修改,最终似乎可以工作,并且我能够对生成的 MFC 应用程序源代码主体进行 ARM64 MFC 编译.
我将 MFC 应用程序 .exe 转移到树莓派 4 中,当我尝试运行它时,我收到 MFC .dll
未找到的错误.
然后我修改了构建属性以将 MFC 库用作静态库,将生成的 MFC .exe
文件传输到 Raspberry Pi 4,然后能够运行它.
注意:我将 Visual Studio 2019 C++ Redistributable 安装程序的副本传输到 Raspberry Pi 4 并运行安装程序.这样做之后,使用 MFC 作为 .dll
而不是静态库的测试 MFC 应用程序的版本可以正常运行.该文件的名称是 VC_redist.arm64.exe
,可以从 Microsoft 下载 最新支持的 Visual C++ 下载 或者可以在 Visual Studio 2019 的安装目录中找到.社区版,文件夹路径为
C:Program Files (x86)Microsoft Visual Studio2019CommunityVCRedistMSVCv142
.
Nullsoft 脚本安装系统 (NSIS)
我之前曾在 Intel 上为 Windows 7 和 Windows 10 使用过开源 Windows Installer builder、NSIS 或 Nullsoft Scriptable Install System,因此想在 Windows 10 ARM 上尝试相同的软件.
我认为可能有某种脚本编译器开关或设置来创建 Windows 10 ARM 安装程序,但是阅读文档并查看支持论坛似乎在构建时没有可用的 Windows 10 ARM 目标.
支持论坛中的一个线程提到,虽然使用由 NSIS 创建的专门针对 Windows 10 ARM 的安装程序不可用并且可能不可用,但由 NSIS 创建的 Windows Installer 应该也可以在 Windows 10 Intel 上运行作为 Windows 10 ARM,Microsoft 进行了最新更改以支持 Windows 10 ARM 上的 x86 应用程序.
我创建了一个简单的 NSIS 脚本,从一个旧脚本开始,用于一个不同的、更复杂的 Windows x86 应用程序.我没有使用解决方案编译/链接输出文件夹的标准路径,而是使用 ARM64 编译/行输出文件夹的路径.
我重新编译了我的 MFC 测试应用程序,然后编译了 NSIS 脚本以创建 Windows 安装程序.我将它转移到运行预览版 Windows 10 ARM 版本的 Raspberry Pi 4 上.然后我运行了成功完成的安装程序.
MFC 测试程序显示在开始"菜单中,我可以通过从开始"菜单中选择应用程序来运行它.
然后我使用 Windows 控制面板将其卸载并正确卸载.
此测试的构建组件是使用 MFC 作为 .dll 编译的单个 MFC 应用程序.构建中只有两个文件:用于 MFC 应用程序的 .exe 和放在同一文件夹中的短文本文件.我没有使用标准的 Windows 应用程序路径进行此测试,而是使用正确创建的 C:frameworksaratoga
.
其他说明和注意事项
来自 UUP 的 Windows 10 ARM 预览版缺少 MFC .dll
根据我的经验,UUP 为 Raspberry Pi 4 构建的 Windows 10 ARM 预览版缺少 MFC .dll
.我不知道三星和惠普、联想和微软等不同制造商提供的用于 Snapdragon 设备的标准 Windows 10 ARM 构建是否具有 MFC .dll.
解决方法是使用静态 MFC 库编译 MFC 应用程序.
我查看了在我的工作站上安装了 Visual Studio 2019 的 MFC .dll
的 ARM 版本,但找不到.我确实为 ARM 找到了一个可再分发的运行时安装程序,所以可能有一个 MFC .dll
.我没有使用可再发行运行时安装程序,因此标准 Visual Studio 2019 C++ 运行时似乎是来自 UUP 的 Windows 10 ARM 预览版的一部分.
注意:找到适用于 ARM 的 Visual Studio 2019 C++ Redistributable 并在安装在 Raspberry Pi 4 上的 Windows 10 ARM 上运行后,MFC .dll 现在可用并且非静态链接测试应用程序的版本运行良好.
Windows 10 ARM 预览版处于测试模式
来自 UUP 的 Windows 10 ARM 预览版在桌面右下角有一条注释,说明它处于测试模式".并附加说明需要激活 Windows.
我不知道这是否意味着此 Windows 安装将在一定时间内变得无法使用.
Nullsoft 脚本安装系统
使用 NSIS 创建 Windows 应用程序安装程序似乎可以创建适用于 Intel 上的 Windows 以及 Windows 10 ARM 的安装程序.
据我所知,随着最近对 Windows 10 ARM 的增强和对 x86 应用程序的支持,任何使用为 x86 编译的引擎(不是 64 位应用程序)的 Windows Installer 创建程序都可以可在 Windows 10 Intel 或 Windows 10 ARM 上使用.
I am trying to understand the barriers to porting a C++ MFC application that runs on x86 Windows 10 to an ARM Windows 10 device with the Qualcomm Snapdragon processor.
The 32 bit application has the following characteristics:
- MFC with C++ used for the user interface
- C used for the business logic
- the source code is divided into about 30 different projects, some static libraries, some DLLs, some EXE
- relies on Windows API for multi-threading, semaphores, mutexes, cryptology
- uses COM objects from Third Party providers, OPOS Service Objects and OPOS Control objects
- relies on local instance of SQL Server Express using ADO for database
This application compiles fine with Visual Studio 2015/2017/2019 targeting x86 and Windows 10.
My question is: what are the possible barriers to migrating this application to ARM Windows 10 using the Snapdragon processor?
A secondary question is what would be an appropriate, low cost ARM Windows 10 device? Most Windows 10 ARM Snapdragon devices from HP, Samsung, and Lenovo seem to be in the US$800 and up pricing and I'd like something more inexpensive as in less than US$200.
A side question: will the Snapdragon 410 processor work for initial testing and compatibility checks. I'm looking at the DragonBoard 410C from Arrow as a low cost test platform. https://www.arrow.com/en/products/dragonboard410c/arrow-development-tools
This DragonBoard? 410C based on 96Boards? specification features the Qualcomm? Snapdragon? 410 processor, a Quad-core ARM? Cortex? A53 at up to 1.2GHz clock speed per core, capable of 32-bit and 64-bit operation.96Boards is a 32-bit and 64-bit ARM? Open Platform hosted by Linaro? with the intension to serve the software/ maker and embedded OEM communities. DragonBoard 410C supports Android 5.1, Linux based on Debian and Win10 IoT Core advanced processing power, WLAN, Bluetooth, and GPS, all packed into a board the size of a credit card. It is designed to support feature-rich functionality, including multimedia, with the Qualcomm? Adreno? 306 GPU, integrated ISP with up to 13 MP camera support, and 1080p HD video playback and capture with H.264 (AVC).
The DragonBoard 820C may be a more appropriate test hardware as it is closer to what most Windows 10 ARM Snapdragon product offerings are shipping with. https://www.arrow.com/en/products/dragonboard820c/arrow-development-tools
What I have been able to find thus far
This posted question, Win32 support on Windows 10 , seems to be the closest to my question however there is no real answer. The accepted answer says "There's no x86 Win32 emulation at all. You need to use a toolset designed for the platform." which appears to be wrong according to the following articles:
- https://www.techradar.com/news/windows-10-on-arm-is-set-to-become-more-useful-with-emulation-for-traditional-64-bit-apps
Right now, with Windows 10 on ARM laptops, it’s possible to run 32-bit x86 desktop software using emulation, but not dedicated 64-bit software like, say, Adobe’s Premiere Pro video editing app for example.
https://channel9.msdn.com/Events/Build/2017/P4171 is a video that mentions x86 emulation
https://docs.microsoft.com/en-us/windows/uwp/porting/apps-on-arm-x86-emulation discusses x86 emulation
Emulation for x86 apps makes the rich ecosystem of Win32 apps available on ARM. This provides the user the magical experience of running an existing x86 win32 app without any modifications to the app. The app doesn’t even know that it is running on a Windows on ARM PC, unless it calls specific APIs (IsWoW64Process2)
- https://www.howtogeek.com/309119/what-is-windows-10-on-arm-and-how-is-it-different-from-windows-rt/
Windows 10 on ARM is completely different [from Windows/RT]. This is the full Windows desktop experience. Microsoft has created a special emulator layer that allows traditional 32-bit desktop applications to run on ARM processors, so everything should "just work". Microsoft even showed off a version of Windows 10 Professional on ARM, and said it supports all the usual advanced features you’d find on Windows 10 Professional.
The emulation works completely transparently to both users and the programs they run. It uses the same WOW (Windows on Windows) technology that Windows uses to run 32-bit applications on 64-bit versions of Windows today. However, the x86-to-ARM emulation happens entirely in software.
Compiling for ARM with VS 2017 and software component considerations
This article, https://pete.akeo.ie/2017/05/compiling-desktop-arm-applications-with.html , provides some details about compiling desktop applications for ARM using Visual Studio 2017.
This article, https://support.microsoft.com/en-us/help/4521606/windows-10-arm-based-pc , under the section about limitations mentions:
Drivers for hardware, games and apps will only work if they're designed for a Windows 10 ARM-based PC. For more info, check with the hardware manufacturer or the organization that developed the driver. Drivers are software programs that communicate with hardware devices―they're commonly used for antivirus and antimalware software, printing or PDF software, assistive technologies, CD and DVD utilities, and virtualization software.
If a driver doesn’t work, the app or hardware that relies on it won’t work either (at least not fully). Peripherals and devices only work if the drivers they depend on are built into Windows 10, or if the hardware developer has released ARM64 drivers for the device.
The article also says in the same section:
64-bit (x64) apps won’t work. You'll need 64-bit (ARM64) apps, 32-bit (ARM32) apps, or 32-bit (x86) apps. You can usually find 32-bit (x86) versions of apps, but some app developers only offer 64-bit (x64) apps.
Here is a Microsoft portal to Windows 10 on ARM documentation, https://docs.microsoft.com/en-us/windows/arm/ with links to various resources on the page as well as a left hand sidebar with additional documentation links.
Some considerations and additional information
Can SQL Server Express (or any version) run on RPi? and the answer appears to be there is no ARM version of SQL Express. However there is a comment that says there is an ARM version of SQL Server Compact. SQL Server Compact has been replaced by SQL Server localDB however I'm not sure if there is an ARM version of that or not however it seems to use parts of SQL Server so an ARM version seems doubtful. See https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/sql-server-express-localdb?view=sql-server-ver15
On the other hand it looks like Microsoft is releasing Azure SQL Edge which does run on x64 and ARM64. https://azure.microsoft.com/en-us/services/sql-edge/
This Developer Minute video from Microsoft describes the steps to enable ARM64 builds in Visual Studio. https://www.youtube.com/watch?v=OZtVBDeVqCE&feature=youtu.be and there are also instructions at this link https://blogs.windows.com/windowsdeveloper/2018/11/15/official-support-for-windows-10-on-arm-development/
解决方案This post covers three related activities:
- creating a low cost Windows for ARM device using the Raspberry Pi 4
- testing a simple MFC application with Windows 10 ARM on that hardware
- testing creating a Windows installer using Nullsoft Scriptable Install System (NSIS)
This post will be updated with additional information once I have done further tests with a larger and more complex MFC application.
- pull the source and recompile the OPOS Control objects for ARM64
- test with an ADO database engine interface
- use semaphores, critical regions, and multiple threads
Note: since in my testing I'm using a preview version of Windows 10 ARM that is not supported by Microsoft on a device that is not supported by Microsoft or other vendor, there may be some difference between my experience and using actual Microsoft products.
The problem is that currently Windows 10 ARM is not sold as a separate product as is Windows 10 for Intel. It is an OEM product only. The only way I've found to use Windows 10 ARM on a cheap device for testing is this approach with a preview build of Windows 10 ARM.
Hardware setup with Windows ARM on Raspberry Pi 4
Looking at the prices for a Windows on Arm device, what I found was mostly in the US$500 and up range. I did find an announcement of a low cost development platform that Microsoft and Qualcomm were doing, the Snapdragon Developer Kit, however I was unable to find where that was available.
Availability of the Snapdragon Development Kit for Windows ARM
So I moved forward with Windows 10 ARM on a Raspberry Pi 4 B with 4GB of RAM and a 128 GB SSD using a USB 3.0 to SATA enclosure for my boot device.
I ordered a CanaKit from Amazon that contained everything I needed including case, power supply, Raspberry Pi 4 B with 4GB of memory, and a microSD card with Raspbian. I picked the 4GB version as that was enough memory for Windows 10 ARM and I wanted to limit costs.
I assembled the Raspberry Pi 4 and case with fan and heat sinks, inserted the microSD card, and powered up the Raspberry Pi. It booted from the microSD card and allowed me to install Raspbian with NOOBS. NOOBS seems to be improved since the last time I used a Raspberry Pi 3 B a couple of years ago. WiFi worked and I was able to update Raspbian.
For the storage with Windows 10 ARM, I used an older 128GB SSD I had lying around in a USB 3.0 SATA to USB enclosure. From what I've read, the difference between a microSD card and an SSD over USB 3.0 is considerable.
I used the UUP dump website to download the necessary components and create the .iso
file for a preview build of Windows 10 ARM. Then I used the WoR project tool to create a bootable SSD from the .iso
file created by the UUP dump tool.
This procedure takes a while for the tools to do their job however what I found was that the tools were impressively user friendly and building the preview Windows 10 ARM .iso
file was straightforward.
One word of warning: the documentation for these procedures seems to be something of a moving target and the tools are improving. For an overview of the procedure see the following:
- https://raspberrytips.com/install-windows10-raspberry-pi/
- https://www.windowslatest.com/2020/07/24/install-windows-10-on-raspberry-pi/
This Ars Technica article, New script makes it easy(ish) to put Windows 10 or 11 on a Raspberry Pi, mentions this argument concerning using the preview Windows 10 ARM components:
The script's creator argues that it violates no laws or Windows licensing agreements since it downloads all its code directly from Microsoft's servers and installs Windows in an unlicensed, deactivated state, just as it would install on a regular x86 PC without a product key. Microsoft only sells licenses of the ARM versions of Windows to OEMs. WoR-flasher has officially been tested using the 32-bit version of the Raspberry Pi OS (and that's what I used to create some install media, too), but it should run without issue on any Debian-based Linux distributions.
While there is mention of having to update the Raspberry Pi 4 firmware to support a boot from USB, what I found was that the Raspberry Pi 4 I purchased Sept. 2021 already had the updated firmware. See Booting my Raspberry Pi 4 from a USB device
First, as I just said, USB boot is enabled by default on the Pi 4B (and the Pi 400, by the way), but there is a small caveat to that. It seems that some early bootloader firmware versions did not properly support this, so you have to be sure that your Raspberry Pi 4 has bootloader eeprom firmware dated Sep 3 2020 or later. There are two ways to do this; either remove the microSD card and then boot, so you can read the firmware date from the diagnostic screen, or simply run
vcgencmd bootloader_version
. I have three Pi 4 units (with 1GB, 2GB and 4GB of memory) which I got from the first batch available in Switzerland, and all of them have Sep 3 firmware so I assume the older firmware is not very common. If you happen to have an older version, the instructions for updating are given in the USB mass storage boot section of the Raspberry Pi Hardware Documentation.The other requirement for USB boot is that you have to be booting Raspberry Pi OS version 2020-08-20 or later. In practical terms this simply means that you should use the latest Raspberry Pi OS image from the downloads page (which currently is 2020-12-02), or if you are going to copy an existing SD card check the contents of /etc/rpi-issue. I am not going to get into a discussion of booting other Linux distributions at this point, because I haven't had time to try it out myself yet.
I shutdown Raspbian and powered off the Raspberry Pi. I removed the microSD card with Raspbian and plugged the USB 3.0 SSD enclosure into a USB 3.0 port and powered on the Raspberry Pi. Windows 10 ARM initialized and booted up.
I did have to do a couple of actions to allow the Windows 10 ARM installation to finish:
- set region and keyboard
- plug an Ethernet cable into the RJ-45 connector of the Raspberry Pi
- use a personal Microsoft user account
Once completed I had a standard Windows 10 desktop with the Edge web browser. A simple check of task manager with Edge running showed I had about 1GB of memory available.
It appears that though Task Manager reports 4 GB of memory installed, Windows 10 ARM preview build on the Raspberry Pi 4 is using only 3 GB of that memory. I've seen mention of a BIOS change needed to enable the use of all of the 4 GB of memory.
Note: It looks like here is the BIOS change needed, Only 3 GB of RAM are available. How can I fix this?
- keep pressing the ESC key after plugging in the power cord, until you see the UEFI setup screen.
- go to Device Manager -> Raspberry Pi Configuration -> Advanced Configuration and change Limit RAM to 3 GB to Disabled.
- press ESC several times to go back, then Y to save the settings when prompted and finally reboot the board.
Using Visual Studio 2019 for MFC on ARM
I decided to use Visual Studio 2019 Community Edition for my test MFC application.
I used Visual Studio to create an MFC project. I then tried to change to an ARM64 build which failed.
First of all I had to modify my Visual Studio 2019 installation to include the ARM MFC functionality. This required me to use the Visual Studio 2019 installer available in the Apps & Features panel of the Control Panel.
Press the Modify button and scroll down to near the bottom of the Individual components tab of the installer. Select the C++v14.29 MFC for v142 build tools (ARM)
and C++v14.29 MFC for v142 build tools (ARM64)
.
During trying various things to get an ARM64 MFC build I ran into a problem with a linker error of MSB8041, see MSB8041: MFC Libraries are required for this project.
I did the Modify of the Visual Studio 2019 installation a couple of times and it finally seemed to work and I was able to do an ARM64 MFC compile of a generated MFC application source code body.
I transferred the MFC application .exe to the Raspberry Pi 4 and when I tried to run it, I received an error of the MFC .dll
not being found.
I then modified the build Properties to use the MFC library as a static library, transferred the resulting MFC .exe
file to the Raspberry Pi 4 and was then able to run it.
Note: I transferred a copy of the Visual Studio 2019 C++ Redistributable installer to the Raspberry Pi 4 and ran the installer. After doing so, the version of the test MFC application that used MFC as a .dll
rather than as static library ran correctly. The name of the file is VC_redist.arm64.exe
and can be downloaded from Microsoft from The latest supported Visual C++ downloads or it can be found in the installation directory for Visual Studio 2019. For Community Edition, the path to the folder is
C:Program Files (x86)Microsoft Visual Studio2019CommunityVCRedistMSVCv142
.
Nullsoft Scriptable Install System (NSIS)
I have previously used the open source Windows Installer builder, NSIS or Nullsoft Scriptable Install System, for Windows 7 and Windows 10 on Intel so wanted to try the same software with Windows 10 ARM.
I thought that there may be some kind of script compiler switch or setting to create a Windows 10 ARM installer however reading the documentation and looking at the support forums it appears that there is no Windows 10 ARM target available when doing a build.
One of the threads in a support forum mentioned that while using an installer created by NSIS targeting Windows 10 ARM specifically was not available and probably would not be available, the Windows Installer created by NSIS should work on both Windows 10 Intel as well as Windows 10 ARM with the latest Microsoft changes to support x86 applications on Windows 10 ARM.
I created a simple NSIS script starting with an old one for a different, more complex x86 application for Windows. Instead of the standard path to the solution compile/link output folder, I used the path to ARM64 compile/line output folder.
I recompiled my MFC test application then compiled the NSIS script to create a Windows Installer. I transferred it to my Raspberry Pi 4 running a preview Windows 10 ARM build. I then ran the installer which completed successfully.
The MFC test program showed in the Start menu and I was able to run it by selecting the application from the Start menu.
I then uninstalled it using the Windows Control Panel and it uninstalled correctly.
The build components of this test was a single MFC application compiled using MFC as a .dll. There were only two files in the build: the .exe for the MFC application and a short text file to put into the same folder. I did not use the standard Windows application path for this test using instead C:frameworksaratoga
which was created properly.
Additional notes and considerations
Windows 10 ARM preview build from UUP lacks MFC .dll
Based on my experience, the Windows 10 ARM preview build from UUP for the Raspberry Pi 4 lacks the MFC .dll
. I don't know if the standard Windows 10 ARM build for the Snapdragon devices offered by various manufacturers such as Samsung and HP and Lenovo and Microsoft have the MFC .dll or not.
The workaround is to compile the MFC application with the static MFC libraries.
I looked to see if there was an ARM version of the MFC .dll
with my Visual Studio 2019 installation on my workstation but was unable to find one. I did find a redistributable runtime installer for ARM so perhaps an MFC .dll
is in there. I did not use the redistributable runtime installer so it appears that the standard Visual Studio 2019 C++ runtime is a part of Windows 10 ARM preview from UUP.
Note: After finding the Visual Studio 2019 C++ Redistributable for ARM and running it on the Windows 10 ARM installed on the Raspberry Pi 4, the MFC .dll is now available and the non-static linked version of the test application runs fine.
Windows 10 ARM preview build is test mode
The Windows 10 ARM preview build from UUP has a note on the desktop in the lower right hand corner that it is in "test mode" with an additional note that Windows needs to be activated.
I don't know whether that means that this Windows install will become unusable within a certain amount of time or not.
Nullsoft Scriptable Install System
Using NSIS to create a Windows application installer appears to create an installer that works for Windows on Intel as well as Windows 10 ARM.
From what I have been able to find, it appears that with the more recent enhancements to Windows 10 ARM and support of x86 applications, any Windows Installer creating program which uses an engine compiled for x86 (not a 64 bit application) can be used on either Windows 10 Intel or Windows 10 ARM.
相关文章