Search code examples
c#compact-frameworkwindows-ce

System.MissingMethodException - only on device startup


Our C# 2.0 CF (CompactFramework) application targets older devices running Windows CE 5.0 and 6.0. The project builds a number of DLLs to provide functionality such as RS-232 comms.

On the Windows CE 5.0 device, a MissingMethodException is thrown, referencing one of these DLLs. This happens early in the application startup process and only immediately after a power cycle. If we kill the application and restart, the exception is not thrown and the application works perfectly. Same result if we deploy using Visual Studio for debugging (no exception).

No exception is thrown on the Windows CE 6.0 devices.

Since this occurs only immediately after a power cycle and we cannot debug the project, what can I try to track down where and what is causing the problem?

Update

The answer from josef is useful. Use IsAPIReady on CE 5.0 with one of these sub-systems:

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;

Or use WaitForAPIReady on CE 6.0 with one of these sub-systems:

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;

But, embarrassingly, the actual problem turned out not to be a low-level OS/CLR problem but that the application had been accidentally started twice on power-up. The 1st time was using the HKLM\init registry key, but some (unknown) user had added a shortcut to the Startup folder. These two instances started up so quickly one after each other I did not notice at first. It was the 2nd instance that crashed.

The solution was to check on startup for multiple instances of the application using CreateToolhelp32Snapshot. If a 2nd instance is detected, the application aborts.

Will leave this question active for anyone who follows...


Solution

  • When a device starts, not all APIs are ready to use from the beginning as those are loaded asynchronously. Therefor WinCE offers the isApiReady function: https://learn.microsoft.com/en-us/previous-versions/windows/embedded/ms885686%28v%3dmsdn.10%29

    On startup of device it loads drivers, services and finally the shell according to the order of the init registry key. Your code probably uses an API that is not yet loaded and so fails.

    An example of isApiReady use can be found at https://github.com/hjgode/RAC_switch/blob/master/RAC_switch/WinAPIReady.cs