简单问题,你负责的系统出现了莫名其妙的异常,怎么办?换句话说,你有什么方法搞清楚问题的所在,进而解决问题?对于这一类问题,我最关心的是系统内部的运行时状态,如果能搞清楚系统当前的问题状态,对找出问题的根源是很有帮助的。获取系统运行时状态肯定要利用工具,在windows桌面系统上,简单的如windows自带的Task Manager, VC的Spy++,高级的如Sysinternals的Process Explorer/Process Monitor都是很有用的运行时分析工具。在Windows CE上,这类工具有Process Viewer,Kernel Tracker,以及我的Remote Process Explorer(这也是我写这个工具的目的之一)等。问题是,大多数基于Windows CE的设备的用户界面都是定制的,不像Windows桌面系统有个SHELL,可以随心所欲,什么程序都能跑。对于这类设备,需要找到一种办法,使得既能在不需要时不增加系统负担,又能在需要的时候获取系统控制权来运行程序。
对于支持移动存储(如U盘、SD卡、CF卡等)的设备, 我觉得很好很强大的一个办法是autorun技术。实现方法也简单,思路是在这些存储设备上放一个autorun.exe,系统后台有线程侦测卡的插入,发现卡上autorun.exe就把它运行起来。非常类似于CD/DVD的autorun技术,很简单但很实用。Windows Mobile直接支持了AUTORUN,其实Windows CE上实现起来也很简单:随便写个driver或者service,系统启动时自动运行,等待各种存储卡的插拔事件,检测卡上某个目录是否存在autorun.exe,然后把autorun.exe运行起来。
实现时,首先要在初始化时创建一个消息队列来等待系统的设备插拔时间通知:
然后在线程循环中,用WaitForSingleObject等待并处理该事件:
几个关键的地方是,
- 定义一个MYDEV结构接收消息;
- 用CreateMsgQueue创建消息队列以接收系统消息;
- 用RequestDeviceNotifications接收FATFS_MOUNT_GUID类型消息,这意味着所有FAT文件系统mount和unmount的消息都会得到通知(U盘和各种存储卡一般都使用FAT文件系统);
- 用WaitForSingleObject等待通知,对系统性能没有额外负担。如果有多个事件,可以用WaitForMultipleObjects,如果还有windows消息要处理(比如在主线程循环中),可以用MsgWaitForMultipleObjects;
- 等到后用ReadMsgQueue读取消息,并用IsEqualGUID判断消息类型然后处理。