System.MissingMethodException-仅在设备启动时

时间:2019-03-01 19:54:29

标签: c# compact-framework windows-ce

我们的C#2.0 CF(CompactFramework)应用程序面向运行Windows CE 5.0和6.0的旧设备。该项目构建了许多DLL,以提供诸如RS-232通讯之类的功能。

在Windows CE 5.0设备上,将引用这些DLL之一抛出MissingMethodException。这是在应用程序启动过程的早期发生的,只有在重启后才发生。如果我们终止应用程序并重新启动,则不会引发异常,并且应用程序可以正常运行。如果我们使用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在启动时检查应用程序的多个实例。如果检测到第二个实例,则应用程序中止。

对于所有关注此问题的人,此问题将保持活跃状态​​...

1 个答案:

答案 0 :(得分:2)

设备启动时,并非所有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使用示例。