简介
本文讲述如何使用Powershell通过RAPI来控制Windows Embedded CE和Windows Mobile设备。
缘由
我入行的时候是做AS400 RPG和UNIX C开发的,所有开发环境都是字符界面,因此习惯了vi+grep+make的开发模式。后来开始做Windows的开发,开始也不大习惯,安装了cygwin来使用,离不开命令行。其实合理使用命令行能大大简化日常工作,我记得好像有本书叫做高效程序员,里面提到要合理使用命令行来简化日常工作。我十分赞同这一说法,下面通过一个例子讲述如何简化工作。
AS/400的界面
UNIX的界面
Cygwin的界面
现在在从事Windows Embedded CE 6 R3的应用程序开发,由于某些原因,使用的设备没有备份电池。因此每次重新启动设备的时候,设备的时间会恢复到初始状态。每次启动系统后,我都需要手工修改设备的系统时间,至少需要20次的鼠标点击操作才能完成时间的设置。这是一件非常烦人的事情。作为程序员,应该尽量把大量的重复操作交给计算机来做,因此我考虑使用脚本来完成时间的设置。然后我考虑使用微软提供PowerShell来完成这一次任务。
为什么使用PowerShell
因为PowerShell可以和.NET Framework很好的结合在一起,可以整合现有的.NET的资源。开始我考虑使用CMD的批处理文件。我也曾经使用过批处理文件来简化编译过程,这个自动编译脚本还在使用,但是做过CMD批处理文件的人和做过UNIX Shell开发的人就会知道,CMD的批处理文件非常难使用,和任何一个shell比(SH, KSH, CSH, and BASH)都输一大截。因此我放弃了使用CMD的想法,选择了PowerShell。
安装和配置PowerShell
使用PowerShell需要下载和安装,请到 Download Windows PowerShell 1.0 下载并安装。需要.NET Framework 2.0的支持。
安装完毕后需要修改Execution Policy,这是对执行脚本的安全设置。因为PowerShell的默认Execution Policy是Restricted,Restricted表示只能执行单条命令,不能执行批量脚本。如果执行批量脚本会提示下面的错误。
File C:\Temp\projects\DatetimeSync\DatetimeSync.ps1 cannot be loaded because the execution of scripts is disabled on th
is system. Please see "get-help about_signing" for more details.
At line:1 char:18
+ ./DatetimeSync.ps1 <<<<
因此需要通过Set-ExecutionPolicy RemoteSigned命令来修改Execution Policy。修改后就能执行批量脚本了。
使用OpenNETCF Desktop Communication
由于PowerShell不支持直接操作Windows Embedded CE和Windows Mobile设备,因此需要借助RAPI来完成。如果使用.NET来开发RAPI,我们可以使用OpenNETCF Desktop Communication.关于OpenNETCF Desktop Communication和RAPI,我之前写过一篇文章,可以参考
Windows Embedded CE和Windows Mobile下ActiveSync开发.
先到OpenNETCF Desktop Communication Library下载,然后编译生成OpenNETCF.Desktop.Communication.dll。下面提供的源码已经包含了该DLL,所以这一步可以省略。
PowerShell开发
先新建一个文本文件,把文件扩展名改成ps1。例如我的文件叫做DatetimeSync.ps1 。然后就可以编写脚本了。
注意,Windows不会自动把ps1的文件与PowerShell进行绑定,每次执行ps1文件需要打开PowerShell,然后使用点号(.)执行,这与UNIX shell的风格一致。
例如下图所示:
只是输入DatetimeSync.ps1不能执行该文件,需要输入 ./DatetimeSync.ps1。
源码
$dllPath = Get-Location
$dllPath = $dllPath.Path + "\OpenNETCF.Desktop.Communication.dll"
[System.Reflection.Assembly]::LoadFrom($dllPath) |Out-null
$rapi = New-Object OpenNETCF.Desktop.Communication.RAPI
echo "Connecting to device..."
$rapi.Connect()
if ($rapi.Connected)
{
$dt = get-date
$date = $dt.Month.ToString() + "-" + $dt.Day.ToString() + "-" + $dt.Year.ToString()
echo "Setting date [$date]..."
$rapi.CreateProcess("cmd", "/c date " + $date)
$time = $dt.Hour.ToString() + ":" + $dt.Minute.ToString() + ":" + $dt.Second.ToString()
echo "Setting time [$time]..."
$rapi.CreateProcess("cmd", "/c time " + $time)
echo "Finished"
}
else
{
echo "Cannot connect to the device, please check the physical connection."
}
Get-Location和get-date叫做cmdlet(读作command-let),是代表一个单独功能的命令。例如Get-Location表示取出当前路径,get-date表示取出当前日期与时间。如果需要使用.NET的assembly,需要使用LoadFrom来反射加载。例子中把OpenNETCF.Desktop.Communication.dll加载进来。 New-Object表示实例化对象,在例子中实例化OpenNETCF.Desktop.Communication.RAPI的对象rapi。有了rapi对象就可以调用RAPI的类的方法来操控Windows Mobile 和 Windows Embedded CE的设备了。在例子中首先调用Connect()方法来连接设备,然后使用CreateProcess()函数来调用cmd修改时间和日期。本来可以通过调用API SetSystemTime来修改系统时间,但是如果这样做,需要使用C++开发一个设备上的DLL,然后部署到设备上,为了简化工作,我直接使用了cmd自带的time和date功能来完成时间的修改。
目前为止,这个功能已经实现了。使用PowerShell可以完成很多很多其他功能来简化我们的工作,例如管理设备上的进程,部署程序,启动单元测试等等。请问您在开发中有使用工具来简化工作吗?如果有,欢迎讨论。
如果您觉得文章不错,请点击支持,如果您觉得文章不好,请点击反对,可以的话,请留言指正,您的反馈是我进步的动力,谢谢。
参考
“How to” Series: Automating Windows Mobile with Windows PowerShell
源代码: /Files/procoder/DatetimeSync.zip
本文转自Jake Lin博客园博客,原文链接:http://www.cnblogs.com/procoder/archive/2010/07/15/How-to-use-PowerShell-on-Windows-Embedded-CE.html,如需转载请自行联系原作者