我们的C#2.0 CF(CompactFramework)应用程序面向运行Windows CE 5.0和6.0的旧设备。该项目构建了许多DLL来提供诸如RS-232通信之类的功能。
在Windows CE 5.0设备上,引发MissingMethodException
,引用其中一个DLL。这在应用程序启动过程的早期发生,并且仅在电源循环后立即发生。如果我们终止应用程序并重新启动,则不会抛出异常并且应用程序运行正常。如果我们使用Visual Studio进行调试(没有例外),结果相同。
Windows CE 6.0设备上没有异常。
由于这只是在电源循环后立即发生并且我们无法调试项目,我可以尝试追踪导致问题的位置和原因?
josef
的答案很有用。在CE 5.0上使用IsAPIReady
与其中一个子系统:
const uint SH_GDI_CE5 = 16; // Most useful
const uint SH_WMGR_CE5 = 17; // Most useful
const uint SH_SHELL_CE5 = 21; // Most useful
const uint SH_WNET_CE5 = 18;
const uint SH_COMM_CE5 = 19;
const uint SH_FILESYS_APIS_CE5 = 20;
const uint SH_DEVMGR_APIS_CE5 = 22;
const uint SH_TAPI_CE5 = 23;
const uint SH_PATCHER_CE5 = 24;
const uint SH_SERVICES_CE5 = 26;
或者在CE 6.0上使用WaitForAPIReady
和其中一个子系统:
const uint SH_GDI_CE6 = 80; // Most useful
const uint SH_WMGR_CE6 = 81; // Most useful
const uint SH_SHELL_CE6 = 85; // Most useful
const uint SH_WNET_CE6 = 82;
const uint SH_COMM_CE6 = 83;
const uint SH_FILESYS_APIS_CE6 = 84;
const uint SH_DEVMGR_APIS_CE6 = 86;
const uint SH_TAPI_CE6 = 87;
const uint SH_DDRAW_CE6 = 91;
const uint SH_D3DM_CE6 = 92;
但是,令人尴尬的是,实际问题并不是一个低级别的OS / CLR问题,而是应用程序在启动时意外启动了两次。第一次使用HKLM\init
注册表项,但一些(未知)用户添加了Startup
文件夹的快捷方式。这两个实例一个接一个地开始,一开始我没注意到。这是坠毁的第二个实例。
解决方案是使用CreateToolhelp32Snapshot
检查启动时是否有多个应用程序实例。如果检测到第二个实例,则应用程序将中止。
对于跟随...的任何人都会激活这个问题
当设备启动时,并非所有API都可以从头开始使用,因为它们是异步加载的。因此,WinCE提供了isApiReady功能:https://docs.microsoft.com/en-us/previous-versions/windows/embedded/ms885686%28v%3dmsdn.10%29
在设备启动时,它根据init注册表项的顺序加载驱动程序,服务,最后加载shell。您的代码可能使用尚未加载的API,因此失败。
可以在https://github.com/hjgode/RAC_switch/blob/master/RAC_switch/WinAPIReady.cs找到isApiReady使用的示例