南行取经记(一)重启Windows Mobile设备(转)

临近春节去新加坡参加了Mobility Metro Training,很多来自亚洲各地的MVPMCT们也都参加了这次的培训。这次培训的目的就是将windows mobile 6.0Visual Studio 2008开发的最新技术,快速地推广到全世界。我们也将会在中国进行系列的Mobility Metro Training

这次去新加坡培训的一共四人,临行时的一句玩笑:“二师兄,你的肉现在比师傅的肉还贵”,让这次培训有了个“取经”的别称。如果想了解Mobility Metro Training的全貌,还要等到培训计划公布。

不过我也在这里可以先将一些有趣的知识点写成BLOG,权当年夜饭的下酒菜吧。

重启Windows Mobile设备

在论坛中,很多朋友都曾经问过如何在应用程序中重启Windows Mobile设备的问题。今天我们来看如何在Visual Studio 2008中来实现这个功能。

打开Visual Studio 2008,选择“File”菜单,“New-Project”。我们会看到下面New Project对话框。


 

Project types里,我们选择Visual BASIC中的Smart Device项。哎,经常看我BLOG里的朋友也许会觉得奇怪,我什么时候也开始用Visual Basic来写程序了。稍后咱们再说。

我们只能选择Smart Device Project,右上角的.NET Framework下拉菜单对Windows Mobile程序来说没什么用。将项目名称改为“Reset Pocket PC”,点OK

Smart Device的对话框里,我们将Target platform选为“Windows Mobile 6 Professional SDK”,需要说明的是,Windows Mobile 6SDKVisual Studio 2008中并不是默认安装,所以需要您单独安装。

然后选择.NET CF的版本,我们选择.NET CF 3.5。需要说明的是,.NET CF是没有3.0的。这是为了和.NET Framework保持一致,所以.NET CF 2.0之后就是.NET CF 3.5

最后,我们选择创建Device Application


 

在进入IDE编辑界面后,我们发现IDE环境并没有发生太大的变化。我们直接在下面的菜单中添加两个菜单项“Reset”和“Exit”。

双击“Exit”菜单,进入代码编辑页面。我们在MenuItem1_Click函数之外,点击鼠标右键。在右键菜单中,我们选择“Insert Snippet”。Code SnippetVisual Studio中非常有用的一个功能,将一些有用的代码片段保存为Code Snippet,在需要使用的时候就不需要到处翻以前的代码了。

而我们想使用的重启Windows Mobile设备的代码也是VB.NET中的代码片段,这也是我们为什么选择使用VB.NET的原因。

 

 

选择Insert Snippet之后,会有一个列表,我们逐次选择“Smart Devices-Device Operating SystemReset the Device”。


 

插入了Code Snippet之后,VB.NET代码如下。通过查看代码,我们可以看到,是调用KernelIoControl API函数来实现功能的。KernelIoControl函数是用来实现对通用IO的控制,我们可以通过该函数实现很多的功能,比如获取设备信息、文件系统和电源管理。

 

VB.NET示例代码

    Private Declare Function KernelIoControl Lib "coredll.dll" (ByVal dwIoControlCode As IntegerByVal lpInBuf As IntPtr, ByVal nInBufSize As IntegerByVal lpOutBuf As IntPtr, ByVal nOutBufSize As IntegerByRef lpBytesReturned As IntegerAs Integer

 

    Private Function CTL_CODE(ByVal DeviceType As IntegerByVal Func As IntegerByVal Method As IntegerByVal Access As IntegerAs Integer

        Return (DeviceType << 16) Or (Access << 14) Or (Func << 2) Or Method

    End Function

 

    Private Function ResetPocketPC() As Integer

        Const FILE_DEVICE_HAL As Integer = &H101

        Const METHOD_BUFFERED As Integer = 0

        Const FILE_ANY_ACCESS As Integer = 0

 

        Dim bytesReturned As Integer = 0

        Dim IOCTL_HAL_REBOOT As Integer

 

        IOCTL_HAL_REBOOT = CTL_CODE(FILE_DEVICE_HAL, 15, METHOD_BUFFERED, FILE_ANY_ACCESS)

        Return KernelIoControl(IOCTL_HAL_REBOOT, IntPtr.Zero, 0, IntPtr.Zero, 0, bytesReturned)

 

    End Function

 

在函数创建完成后,我们在菜单的调用方法中调用ResetPocketPC方法。

    Private Sub MenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem1.Click

        ResetPocketPC()

    End Sub

 

编译运行之后,程序运行效果如上图。当我们点击Reset菜单,Windows Mobile设备将会重启。如果Visual Studio使用的是调试模式,此时调试将终止。

 

 

稍后,我们可以看到Windows Mobile设备重启的界面。VB.NET的代码可以正常实现,接下来,C#程序员会问,C#Code Snippet是否也提供相同的功能。遗憾的是,C#中,并没有支持重启的代码片段。我们需要自己实现C#中的代码,好在将这段代码从VB.NET“翻译”成C#并不复杂。C#代码示例如下:

   

[DllImport("coredll.dll")]

public static extern int KernelIoControl(int dwIoControlCode, IntPtr lpInBuf, int nInBufSize, IntPtr lpOutBuf, int nOutBufSize,ref int lpBytesReturned);


private int CTL_CODE(int DeviceType, int Func, int Method, int Access)

{

return (DeviceType << 16) | (Access << 14) | (Func << 2) | Method;

}


private int ResetPocketPC()

{

const int FILE_DEVICE_HAL = 0x101;

const int METHOD_BUFFERED = 0;

const int FILE_ANY_ACCESS = 0;


int bytesReturned = 0;

int IOCTL_HAL_REBOOT;


IOCTL_HAL_REBOOT
= CTL_CODE(FILE_DEVICE_HAL, 15, METHOD_BUFFERED, FILE_ANY_ACCESS);

return KernelIoControl(IOCTL_HAL_REBOOT, IntPtr.Zero, 0, IntPtr.Zero, 0, ref bytesReturned);

}

C#代码运行也可以实现相同的功能。

转自:http://dev.10086.cn/cmdn/wiki/index.php?doc-view-2784.html

posted @ 2011-02-12 14:12  董雨  阅读(223)  评论(0编辑  收藏  举报