Welcome to MSDN Blogs Sign in | Join | Help
Windows Mobile 6.5 Widgets开发初体验

作者:马宁

Windows Mobile 6.5的DTK终于发布了,其中最吸引人的是两个功能:Widgets和Gesture API。Widgets是近来非常流行的一项技术,用于显示一些常用信息,比如天气、股票、新闻和体育等。Google Android和Symbian上已经有了类似的技术,可以说,Widgets是很好地结合了移动设备与互联网的技术。虽然Widgets开发简单,但很有可能改变移动互联网的未来格局。目前Windows Mobile 6.5的Widgets是基于W3C的Widgets草案,支持2008年12月22日草案,链接在http://www.w3.org/TR/2008/WD-widgets-20081222/

开发环境

好了,接下来,我们就要看一下,如何为Windows Mobile 6.5开发一个Widgets控件。首先,我们需要下载Windows Mobile 6.5的DTK,下载链接为:

http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=20686a1d-97a8-4f80-bc6a-ae010e085a6e

Windows Mobile 6.5的DTK需要与Windows Mobile 6 SDK配合使用,Windows Mobile 6 SDK的下载地址:

http://www.microsoft.com/downloads/details.aspx?familyid=06111a3a-a651-4745-88ef-3d48091a390b&displaylang=en

由于很多Widgets都需要联网,所以测试环境也需要ActiveSync的支持。Vista应该使用Windows Mobile Device Center 6.1,下载地址:

http://www.microsoft.com/windowsmobile/en-us/help/synchronize/device-center-download.mspx

编写Widgets

接下来,我们就可以来开发一个Widgets了。首先创建一个WidgetDemo的文件夹,创建一个叫做widget.htm的文件,将下面的HTML代码拷贝到文件中:

<html>

<head> 

<title>Cool Widget!</title> 

</head> 

<body> 

I'm a cool windows mobile 6.5 widget 

<!-- Search Google -->

<form method="get" action="http://www.google.cn/custom" target="google_window">

<table bgcolor="#ffffff">

<tr><td nowrap="nowrap" valign="top" align="left" height="32">

<a href="http://www.google.com/">

<img src="http://www.google.com/logos/Logo_25wht.gif" border="0" alt="Google" align="middle"></img></a>

<label for="sbi" style="display: none">????????</label></tr>

<tr>

<input type="text" name="q" size="31" maxlength="150" value="" id="sbi"></input>

<label for="sbb" style="display: none">??????</label>

<input type="submit" name="sa" value="??" id="sbb"></input>

<input type="hidden" name="client" value="pub-9289651901062754"></input>

<input type="hidden" name="forid" value="1"></input>

<input type="hidden" name="ie" value="UTF-8"></input>

<input type="hidden" name="oe" value="UTF-8"></input>

<input type="hidden" name="cof" value="GALT:#008000;GL:1;DIV:#336699;VLC:663399;AH:center;BGC:FFFFFF;LBGC:336699;ALC:0000FF;LC:0000FF;T:000000;GFNT:0000FF;GIMP:0000FF;FORID:1"></input>

<input type="hidden" name="hl" value="zh_CN"></input>

</td></tr></table>

</form>

<!-- Search Google -->

</body> 

</html>

这个Widget就是调用Google的搜索页面。原来的Widget Demo没有Google搜索的代码,我从网上找了一个示例加了进去。接下来,创建一个叫做config.xml的文件,将下列代码拷贝到文件中:

<?xml version="1.0" encoding="utf-8" ?> 

<widget version="1.0" 

xmlns="http://www.w3.org/ns/widgets" 

id=""> 

<name>My first widget</name> 

<content src="widget.htm" type="text/html" /> 

<access network="true" /> 

<icon src="icon.png"/> 

<description>This is my first widget, 

it won't make a lot of money on the 

marketplace but at least is cute!</description> 

</widget>

这是一个描述性的XML文件,结构非常清晰,不需要多做解释了。注意content,icon和access network三个节点。Content的src就是我们刚编写的widget.htm, 允许Widget访问网络,icon则是显示在Windows Mobile开始菜单里的图标。

zip

现在有了三个文件,我们使用WinZip将其压缩成一个ZIP文件。特别需要指出的是,我们不能压缩这三个文件所在的文件夹,必须选中所有文件之后进行压缩。然后我们将WidgetDemo.zip的扩展名改为WidgetDemo.wgt。

部署Widget

到这里,Widget开发就完成了。通过ActiveSync或者共享目录,将Widget拷贝到Windows Mobile 6.5的模拟器中。

 Widgets1  Widgets2

我们使用File Explorer来找到这个Widget文件,点击之后,会提示是否安装并运行这个Widget。

安装Widget之后,会自动运行,Google的图标来源于网络,所以可能会显示慢一些。如果Google图标没有显示出来,则说明网络连接不通:

Widgets7   Widgets5

输入关键字,点击button,Widget会自动启动IE Mobile,显示搜索结果。

在使用时,我们可以在开始菜单里找到相应的图标,可以打开Widget。还需要说明的是,如何卸载这个Widget。

在开始菜单 - Setting – System - Remove Programs里,可以看到我们的Widget,与卸载普通的应用程序没有区别。

Widgets6

我们的Widget被安装在\Program Files\Widgets\User\7的目录里,目录的序号与安装顺序有关,比如1里就是内置的Live Search。

写在最后

写到这里,Widget的开发就完成了,怎么样?简单吧。Widget开发的简单性,正是它未来可能缔造辉煌的主要优势。任何熟悉HTML和JavaScript的人都可以开发出功能丰富的Widget,而Widget又可以像普通应用程序一样使用。

虽然不像Palm的WebOS那样具有颠覆性,但是依托于目前的技术,才能获得大多数开发者的支持。现在只有Windows Mobile 6.5支持Widget,但其他移动设备是否有可能支持Widget呢?一切皆有可能。

总之,一句话,大有可为!

其实HTML和JavaScript并不是我的强项,下周还是给大家说说Gesture API吧 J

参考资料

Getting started with widgets on Windows Mobile 6.5

http://blogs.msdn.com/windowsmobile/archive/2009/06/04/getting-started-with-widgets-on-windows-mobile-6-5.aspx

Developing Widgets for Windows Mobile 6.5

http://msdn.microsoft.com/en-us/library/dd721906.aspx

Windows Mobile 6.5 Widget系列文章

http://www.shangducms.com/post/Windows-Mobile-Widget.aspx

Bing API初体验
作者:马宁 

Bing正式发布没几天,除了功能和搜索结果外,作为开发者来说,我们关心的还有Bing API啥时候能出。周末浏览MSDN网站时,发现Bing Service已经上线了,链接是:http://msdn.microsoft.com/en-us/library/dd900818.aspx

Bing提供的API很丰富,除了搜索外,还增加了广告Ad、图片、新闻、Phonebook、拼写和视频的搜索。而访问协议有三种:JSON, XML和SOAP。JSON协议用于AJAX应用,XML用于Silverlight应用,SOAP用于传统的.NET等强类型程序。可见,微软在推出API方面还是很有效率的。

使用Bing API的第一步,是去Bing Developer Center上申请一个AppId,每个应用应该使用一个单独的AppId。Bing Developer Center的网址是:http://bing.com/developers 。在页面里先用Live ID登录,然后选择Get a new App ID,填写一些基本信息,然后你就会得到一串很长的AppId。需要注意的是,Bing还有一个网址是http://www.bing.com/developer/ ,估计是为1.1版本准备的,现在还不能申请AppId。大家一定要分清楚。

接下来,我们在Visual Studio 2008里创建一个.NET应用。在Project菜单里选择Add Service Reference,在弹出对话框的Address文本框里填入:

http://api.search.live.net/search.wsdl?AppID=yourAppId

注意:AppID=后要填写你申请到的AppId.

BingApi

在找到LiveSearchService的引用后,将其添加到我们的工程中。接下来,我根据PhoneBook和WebSearch两个例子写了DEMO,更多例子可以参考:

http://msdn.microsoft.com/en-us/library/dd251066.aspx

需要提醒的是,可能是文档没有更新,Bing API的类名称还会发生变化。我发现在2009年6月8日导出的引用中,LiveSearchService的名称变成了LiveSearchPortTypeClient。Web Search的代码如下:

        private void button2_Click(object sender, EventArgs e)
        {
            // LiveSearchService implements IDisposable.
            using (LiveSearchPortTypeClient service = new LiveSearchPortTypeClient())
            {
                try
                {
                    SearchRequest request = BuildRequestWeb();

                    // Send the request; display the response.
                    SearchResponse response = service.Search(request);
                    DisplayResponseWeb(response);
                }
                catch (System.Net.WebException ex)
                {
                    // An exception occurred while accessing the network.
                    Console.WriteLine(ex.Message);
                }
            }
        }

        private SearchRequest BuildRequestWeb()
        {
            SearchRequest request = new SearchRequest();

            // Common request fields (required)
            request.AppId = AppId;
            request.Query = "马宁";
            request.Sources = new SourceType[] { SourceType.Web };

            // Common request fields (optional)
            request.Version = "2.0";
            request.Market = "en-us";
            request.Adult = AdultOption.Moderate;
            request.AdultSpecified = true;
            request.Options = new SearchOption[]
            {
                SearchOption.EnableHighlighting
            };

            // Web-specific request fields (optional)
            request.Web = new WebRequest();
            request.Web.Count = 30;
            request.Web.CountSpecified = true;
            request.Web.Offset = 0;
            request.Web.OffsetSpecified = true;
            request.Web.Options = new WebSearchOption[]
            {
                WebSearchOption.DisableHostCollapsing,
                WebSearchOption.DisableQueryAlterations
            };

            return request;

        }

        private void DisplayResponseWeb(SearchResponse response)
        {
            // Display the results header.
            listBox1.Items.Add("Bing API Version " + response.Version);
            listBox1.Items.Add("Web results for " + response.Query.SearchTerms);
            listBox1.Items.Add(string.Format("Displaying {0} to {1} of {2} results",
                response.Web.Offset + 1,
                response.Web.Offset + response.Web.Results.Length,
                response.Web.Total));

            // Display the Web results.
            System.Text.StringBuilder builder = new System.Text.StringBuilder();
            foreach (WebResult result in response.Web.Results)
            {
                builder.Length = 0;
                builder.AppendLine(result.Title);
                builder.AppendLine(result.Description);
                builder.AppendLine(result.Url);
                builder.Append("Last Crawled: ");
                builder.AppendLine(result.DateTime);

                listBox1.Items.Add(builder.ToString());
                Console.WriteLine();
            }
        }

从代码上来看,很简单,先创建一个LiveSearchPortTypeClient的对象,然后,创建SearchRequest对象,在Request里需要设置的是AppId,Query和Sources。AppId不用多说了,Query里填我们要查的关键字,Sources里指定SourceType,我们这里指定的是SourceType.Web。

image

将SearchRequest参数传递给LiveSearchPortTypeClient的Search方法,会返回一个SearchResponse的对象,里边包含我们的搜索结果。结果会包含在response.Web.Results对象里,最主要的参数是Title、Description和Url。

最后的运行结果就是这样的了:

BingApi2

Bing的好坏还需要时间检验,但是Bing API和Google API应该差不多,而且考虑了不同用户的需求,这也许就是软件公司和互联网公司不一样的地方。同时推出的还有Bing Map API,改天试一下。

 

更多关于Windows Embedded CE开发的文章,请参考“Windows Embedded CE 中国研发团队”的中文博客:http://blogs.msdn.com/wincechina/

Smartphone 2.0 = Phone + Service

作者:马宁

Smartphone 2.0,这个概念有点哗众取宠,但是从2002年Smartphone的概念被推出后,智能手机的本身和外部环境改变了很多,在这个时间点上,我们有必要讨论Smartphone下一步会往何处去。我们姑且以Smartphone 2.0为名吧。

什么是智能手机?有人会说,更大的分辨率、更好的CPU,有人会说能上网,有人会说可以玩游戏、听音乐。

那么,每个人、每天都在用的Phone的功能是什么?电话、短信、联系人。Smartphone增加了浏览器(WAP或WEB)、媒体播放器、游戏、IM、Java VM、Ebook Reader等功能。最近SNS Client、 VoIP、App Store和Widget等功能也被加入到Smartphone中。但是这种功能的累加就是Smartphone的未来吗?

从本质上来剖析这些新功能的本质是什么?是服务(Service)。最简单的服务应该就是网站提供的信息浏览服务,这也是互联网最初的基石。信息浏览服务的方式有两种:Pull和 Push。Pull的方式,是用户主动浏览网站的信息,并且点击超链接来获取自己想读的信息,浏览网站和RSS订阅都应该属于Pull方式;Push方式,是将信息进行编辑、整合后,推送给用户,最典型的例子就是手机报。

在2G时代,Service来自电信运营商,是一个相对封闭的生态链,内容提供商(CP)和服务提供商(SP)必须通过运营商的网络向终端用户提供服务。运营商也通过自己的垄断地位和网络的封闭性,将竞争者隔绝在外。这种情况是短缺经济下的产物,在网络带宽稀缺情况下的必然产物。这种现象在互联网初期也能找到,我们用小猫拨号上网时,访问的163、169网站基本都是电信运营商提供的服务。

3G时代,当网络带宽不再稀缺时,运营商发愁的是如何为用户提供各种各样的服务,从而让带宽使用率提高。用户使用1M和10M流量,运营商的成本几乎没有增加,而赚到的却是10倍的钱。

好了,接下来的问题就是,服务来自于谁?移动运营商吗?必须承认,3G时代,很多服务仍然会来自于移动运营商。但是随着用户规模的扩大,运营商会发现,他们在某些小众领域是力不从心的,而小众领域恰巧是推动互联网发展的最大动力之一。互联网的历史告诉我们,一家公司不可能提供所有的服务,AOL不能,Yahoo不能,中国移动同样也不能。所以,当运营商感觉到他们的力不从心时,运营商构筑的樊篱会在一瞬间土崩瓦解。

那么,3G时代,绝大部分的服务会来自于互联网服务商,无论是PC还是Smartphone,人们想访问到熟悉的服务,而不是两套完全不同的信息服务。

随着Web 2.0时代的到来和无线网络带宽的增加,Service不再是单项的信息输送,用户的参与性会越来越强,而更多的用户信息会被加入到互联网中。SNS已经将我们的人际信息加入到互联网中。Smartphone的移动性,会将用户的地理位置信息加入到互联网中。Google Latitude服务已经展示了Location-aware SNS的魅力,下一步可能是和好友聚会整合。

除了3G的到来外,推动Service发展的还有一个重要的力量——“云计算”。云计算会极大降低服务提供者的成本。服务提供者的身份也会发生质的改变,从大的企业迅速转向到小企业甚至是个人,网络服务也即将进入全民草根时代。一些小众化的网络服务,会在云计算时代,撼动整个互联网的传统格局。以后看到由门口大妈提供的煎饼果子价格指数时,千万别觉得稀奇。

而智能手机会对云计算的发展起到一个助推的作用。如果将张亚勤提出的“云端”概念(Cloud + Client)推广到智能设备上,我们就可以得到下面的公式:

Smartphone 2.0 = Phone + Service

我们不必认为Phone就是智能手机,Netbook和MID等产品也会被包括在内。说白了,只要是能够随身携带、连接无线网络、运行在线服务的客户端的智能设备,我们都应该算在Phone中。

Service也不能简单理解为Cloud,毕竟在云计算之外,很多服务提供商已经为我们提供了很多有用的在线服务,这些服务提供商不会因为云计算时代的到来而衰退,而会走一条逐渐融合的道路。

Service应该包括两个方面:一端是运行在互联网上的服务(服务器端应用);另一端是运行在智能设备上的服务客户端。再好的服务也需要落地,互联网的最后一公里将重现在3G时代的智能手机上。尽管现在的智能手机厂商都在哀叹,寻找合适的服务和软件太难,可是在一年以后,将会出现服务提供商为了将服务预置到Smartphone 上而激烈竞争的盛况。得终端者得天下。一些早起的服务提供商已经开始与终端设备制造商谋求合作了,在国内一些MID产品中已经出现了一些网络购物网站的链接。点击链接会进入浏览器,访问购物网站,这只是预置在线服务的初级模式。

那么Service应该以什么方式预置到Smartphone上呢?对于简单的信息浏览和交互操作,浏览器无疑是最好的客户端,JavaScript跨平台的特性能够让在线网络供应商不必担心不同设备的兼容问题。除了浏览器外, Widget也会成为非常流行的一种客户端,网站开发者只需要用HTML和JavaScript编写简单的代码,就可以同时运行在Symbian和Windows Mobile手机上,这将一个多么大的诱惑?

如果在线服务需要提供更多的交互性又该怎么办呢?比如现在非常流行的开心网,使用了RIA技术来设计用户交互游戏。Flash Lite的确改变了互联网的用户体验,微软的Silverlight尽管还在开发中,但是连接Service的能力也不容小觑。RIA技术将成为移动互联网的主流之一。为不同设备编写RIA运行端的成本,显然要低于为不同的硬件平台开发应用的成本。

最后的一种方式就是编写客户端,对于复杂的应用和用户体验设计,单凭JavaScript和RIA就无法解决了。而且,基于浏览器的技术还有一个致命缺陷——无法适应移动网络的时断时续。比如IM和VoIP等复杂的应用,我们还是需要去编写客户端。但是如果去编写客户端的话,就势必面临为多个手机平台编写应用的困境。研发成本增加了,但是,收入未必能够相应增加。这也是制约在线服务进入移动领域的重要因素。

我们有什么解决办法吗?不妨换一个思路来看,当Service无法适应多个Phone时,我们能否让Phone去适应Service呢?看到这句话,可能很多人的脑海里都会出现一个词——定制手机。

定制手机的概念,最早来自于移动运营商,为了增加服务的黏性,运营商凭借垄断地位,要求手机厂商将提供的服务预置到手机中,比如移动的“心机”。再进一步时,运营商对Shell、用户体验都提出要求,为同一运营商定制的手机,无论运行什么样的操作系统,提供的外观、用户体验都是一致的,比如OMS。这就是定制手机。

移动运营商为什么要定制手机?要推广自己的服务。那么,定制手机符合我们对于Smartphone 2.0的定义,是Phone与Service的结合体。但是Service一定要来自运营商吗?上面,我们已经探讨过这个问题,答案是不一定。那么,定制手机一定要来自于移动运营商吗?

所有的服务提供商都可以按自己的要求去定制手机,这不是移动运营商的专利。Google虽然没有定制手机,但是

推自己定制手机前,恐怕要想清楚这么几个问题:

1, 你的服务是否有足够多的人在用?

2, 用你服务的人是否愿意为了使用你的服务而买一部新手机?

3, 你是否有足够多的钱来推广你的服务和手机?

其实这么算起来,能够推出自己定制手机的服务提供商并不多,符合这几个条件的,可能也只有腾讯、百度、新浪、魔兽世界、淘宝等几家了。

我们来想像下这几家定制手机的样子:

1,腾讯,现在已经成为一个庞然大物了,几乎覆盖了所有互联网的领域,IM、在线游戏、门户网站、商城、SNS。但是,在移动领域,QQ一直受制于移动的短信,处于受支配的地位,也一度因为利益分配而和移动吵翻。如果腾讯能够掌握手机终端,将自己的服务预置其中,那么很多年轻人在自己手机上做的,就不再是发短信,而是聊QQ了。QQ用户的忠诚度极高,且对QQ文化极度认可,如果手机定价合理,加上QQ的定制外观,一定会有人趋之若鹜。

2,百度,是一个雄心勃勃的公司,将服务推广到手机领域,是百度必须要做的事情。因为Google已经做了。但是,怎么推广到手机领域,将是百度面临的一个大问题。为运营商提供搜索服务,给移动运营商打工吗?如果那样,百度会重蹈腾讯与移动合作的覆辙,难免为人作嫁衣。将自己的搜索、贴吧、地图、购物等服务,有效整合起来。比如购物时,可以在贴吧里搜索产品评价,然后在地图里寻找附近的实体店,如果发现实体店价格偏高,还可以在购物中下订单。

不过百度不适合自己推定制手机,而应该将自己的服务预置到手机中。那么百度会和谁合作呢?Android手机恐怕不是百度的最佳选择(PR会强烈反对吧?)。本着先易后难的原则,魅族M8也许应该成为百度的第一个合作目标。这两家的业务互补性非常强,一家缺应用,一家缺终端,而且绝对不会到对方的领域中兴风作浪。百度手机、魅族的搜索引擎?不靠谱吧?

3,魔兽世界,在这里指代网络游戏。手机网游不是没人做,而是做不出来,最要命的问题还是出在终端的兼容性上。随着手机硬件性能的提高,游戏在手机上运行将不再是问题,但是如何在手机上跑出最好的效果,定制也许是一条路。

另外,网络游戏是否会有新的玩法,比如结合现实的地理位置,和附近同一个工会的兄弟一起去打怪,或者交换装备?西单的下一个支柱产业也许是游戏装备?

当然,还有一些针对特定人群的服务提供商,比如携程,如果能够直接在手机上订机票和酒店,并且将航班信息保存到手机的日程里,至少这种功能对我来说是有诱惑力的。

定制手机可以用双方的渠道来进行推广,但1+1能否大于2,就看Service和Phone合作上是否能够齐心协力了。合作上可能会有这样几个难点:

1,互联网知名度和手机销售渠道如何整合,Service 提供商必须拥有强大的现金流,对终端的推广进行补贴, 手机厂商要利用自己的渠道推广Service的服务;使用Service的渠道销售手机,比如网上直销,也应该获得分成;

2,在线服务的收益如何分成,iPhone不存在这个问题,因为Phone和Service是一家,但是合作的双方肯定会遇到这个问题;

3,Service和Phone是否真的合适?Service 的更新速度快,Phone的操作系统、开发环境、硬件性能,是否能跟得上Service的发展。

单纯从技术角度上来说,PPLive和开心网也具有定制手机的可能,但是考虑到他们的运营情况和现金流,短时间内恐怕很难。

最后再说说+的问题,对,这个加号也有学问。没有加号,Phone和Service永远都是两个东西。我们可以将+看作一个渠道,沟通服务和用户的渠道。这个渠道做什么用?给用户提供订阅的服务,然后将用户的钱拿走。

提供更多的服务是运营商要关心的事情,3G、WIFI,无非是一条提供服务的高速公路。如何收到钱,这才是Phone和Service要关心的事情。这就涉及到支付的问题了。移动运营商、信用卡、银联、支付宝,都是支付的渠道。支付会是移动互联网最后一公里上的制高点。提供了服务、控制了终端,钱收不上来,也是白搭。现在谁也说不好,谁会赢得最后的胜利,但是缺少了支付手段,Smartphone 2.0恐怕也是水中月、镜中花。

只是想将自己最近的所思所想记录下来,没想到写了这么长,希望对奋斗在3G康庄大道上的朋友们有价值吧。

更多关于Windows Embedded CE开发的文章,请参考“Windows Embedded CE 中国研发团队”的中文博客:http://blogs.msdn.com/wincechina/

如何修改Windows CE的平台类型

作者:马宁

在开发Windows CE的应用程序时,经常需要检测平台类型,了解我们的应用程序运行在Pocket PC、Smartphone还是Windows CE上。在这篇文章里,我们介绍如何编写一个应用程序来检测当前运行的平台类型。

在开发Windows CE的操作系统时,我们会遇到另外一种情况:某些应用程序限制了运行的操作系统平台,比如只允许运行在Pocket PC上。而我们如果想在Windows CE上运行的话,就需要修改操作系统的平台类型。注意:这种情况只能出现在测试时,不应该修改实际产品的平台类型,否则会引起很多安全性的问题。

创建平台检测程序

首先,我们需要创建一个应用程序来检测当前的平台类型,我们使用C++和Platform Builder来创建这个程序。如果你熟悉.NET Compact Framework的开发,想开发托管的平台检测程序,请参考:

如何检测你的应用程序是否运行在模拟器上

http://blogs.msdn.com/netcfteam/archive/2006/09/15/756755.aspx

检测你的程序运行在Pocket PC或Smartphone上

http://blogs.msdn.com/netcfteam/archive/2006/09/22/766343.aspx

检测平台是否支持触摸屏

http://blogs.msdn.com/netcfteam/archive/2006/10/02/Platform-detection-III_3A00_-How-to-detect-a-touch-screen-on-Windows-CE-in-.NET-CF.aspx

创建OS Design和编译的过程在此略过,可以参考《Windows CE 6.0 R2开发初体验》. 我们首先在Platform Builder里创建一个子工程(Subporject),在Solution Explorer里找到Subporject节点,右键选择Add New Porject,会启动向导。

clip_image001

在向导中,选择WCE Application,将工程名称改为”CheckPlatform”.

clip_image002

为了少写代码,我们选择”Hello World” application,一般情况下,我们应该选择simple Windows Embedded CE application.

clip_image003

我们打开Subprojects节点中的CheckPlatform(工程名称)中的Source files节点中找到CheckPlatform.cpp文件。在文件中找到WndProc函数,将代码修改为:

TCHAR szPlatform[1024];

switch (message)

{

case WM_PAINT:

hdc = BeginPaint(hWnd, &ps);

// TODO: Add any drawing code here...

RECT rt;

GetClientRect(hWnd, &rt);

if (SystemParametersInfo(SPI_GETPLATFORMTYPE,sizeof(szPlatform),szPlatform,0)!=0)

{

DrawText(hdc, szPlatform, _tcslen(szPlatform), &rt, DT_CENTER);

}

EndPaint(hWnd, &ps);

break;

default:

return DefWindowProc(hWnd, message, wParam, lParam);

}

代码写的并不好,主要是为了验证SystemParametersInfo函数,我们就将Platform Type显示到窗体上了。正常情况下,我们应该用下面的代码判断运行平台:

if (SystemParametersInfo(SPI_GETPLATFORMTYPE,sizeof(szPlatform),szPlatform,0)!=0)

{

if (lstrcmp(szPlatform,TEXT("PocketPC"))==0)

; // Pocket PC

else if (lstrcmp(szPlatform,TEXT("Smartphone"))==0)

; // smartphone

}

如果使用SPI_GETOEMINFO参数,我们可以获得OEM信息,如果返回字符串中包括“Microsoft DeviceEmulator”,则表示当前应用程序运行在模拟器中。

CheckPlatform程序编译好后,会自动加入到NK.bin 中。我们可以通过Command Shell,运行应用程序。调用Attach Device启动Windows CE操作系统后,选择Target菜单中的Target Control(快捷键Alt+1),输入”s chekplatform”,就可以运行CheckPlatform程序。

clip_image004

好了,最后看一下运行结果:

clip_image006

修改操作系统的类型

上面的话题其实很多文章都讨论过了。但是在实际工作中,我们会遇到一些平台迁移的工作。我们会首先将Windows Mobile的软件在Windows CE上运行,以验证功能。不过有些软件检测了操作系统类型,在不修改软件代码的情况下,我们是否可以在Windows CE上运行检测平台类型的应用程序呢?

Windows CE操作系统的Platform Type类型值是在BSP中被指定的,我们可以通过修改BSP中的Platform Type来改变系统的Platform Type。注意:这种情况只能出现在测试时,不应该修改实际产品的平台类型,否则会引起很多安全性的问题。

我们打开Windows CE 6.0 R2的源代码,位置在:

x:\WINCE600\PLATFORM\DEVICEEMULATOR\SRC\INC

我们修改的是DEVICEEMULATOR的代码,如果是其他平台的代码,则去相应BSP文件夹中的指定位置。在BSP的INC文件夹中,我们会找到一个ioctl_cfg.h文件。

在ioctl_cfg.h文件中,我们会找到下面的代码:

#if defined( project_smartfon )

#define IOCTL_PLATFORM_TYPE (L"SmartPhone\0")

#elif defined( project_wpc )

#define IOCTL_PLATFORM_TYPE (L"PocketPC\0SSDK\0")

#else

#define IOCTL_PLATFORM_TYPE (L"DeviceEmulator")

#endif

#define IOCTL_PLATFORM_OEM (L"Microsoft DeviceEmulator")

Device Emulator的BSP通过编译选项区分了不同的平台类型,如果是Windows CE系统,则Platform Type为DeviceEmulator。好了,我们可以通过修改IOCTL_PLATFORM_TYPE的值,来“欺骗”操作系统,让应用程序认为自己运行在Pocket PC或Smartphone上。注意:因为Windows Mobile和Windows CE的函数库存在巨大差异,Windows Mobile的应用程序在Windows CE上未必能够直接运行。

修改IOCTL_PLATFORM_TYPE之后,我们需要重新编译BSP,才能够完成Platform Type的修改。在Build菜单中选择Advanced Build Commands中的Rebuild Current BSP and Subprojects。

clip_image007

我们可以编译BSP和Subporject后,调用BuildRel和Makeimg生成新的NK.bin。这样,我们就可以节省大量的重新编译的时间。在我的机器上大概几分钟就完成了BSP的编译,如果是重新Build操作系统的话,需要二十分钟左右。

NK编译成功后,选择Attach Device,重新运行系统和CheckPlatform程序,会得到下面的运行结果:

clip_image009

最后还需要提示一下,这种方法只对通过SystemParametersInfo API检测Platform Type的应用程序有效。如果软件使用了其他方法检测Platform Type的话,那就需要具体问题具体分析了。

更多关于Windows Embedded CE开发的文章,请参考“Windows Embedded CE 中国研发团队”的中文博客:http://blogs.msdn.com/wincechina/

终于有了MSDN上的Blog

在MSDN Blog上申请自己的Blog有一阵子了,但是一直没空打理。前几天,张欣在MSN上问我是不是失踪了,才发现太久没有更新Blog了。下面是我在MSDN上Blog的地址。

http://blogs.msdn.com/ninma/

因为MSDN Blog属于微软的官方博客,所以内容可能会关注于我目前的工作:Windows Embedded CE。想和大家分享Windows Embedded CE中的新技术、开发技巧、使用心得。其他方面的内容,我会发表于博客园和CSDN的Blog上。

写Blog的历史,应该从2001年CSDN的网友专栏开始,到现在也有差不多8年的时间了。一直将Blog作为记录自己开发中心得的地方。因为比较专注于Windows Embedded和Windows Mobile,所以访问量也很不错,也有一定的知名度。我现在维护的Blog主要有下面几个:

CSDN Blog:http://blog.csdn.net/aawolf

博客园:http://aawolf.cnblogs.com/

嵌入式在线:http://blog.mcuol.com/aawolf/index.htm

谢谢大家的关注,我会继续努力…

让Windows CE 6.0 R2支持.NET CF 3.5

作者:马宁

原文:http://blog.mcuol.com/User/aawolf/Article/6389_1.htm

      .NET Compact Framework已经升级到3.5的版本了,.NET CF 3.5支持LINQ和WCF等新的特性。对于Windows Mobile的开发人员来说,只需要安装一个更新的CAB包就可以了。可是Windows CE的开发者如果想将.NET CF 3.5加入到OS Design,还是需要花一点功夫的。我们会使用革新2410D开发板作为我们的平台,关于该开发板的介绍和开发过程,大家可以参考我之前的文章——《革新2410D开发板试用手记》,链接如下:
http://www.cnblogs.com/aawolf/archive/2008/05/29/1209854.html
      来自Mike Hall的QFE
      这篇文章的起因是Mike Hall在自己BLOG上发表的一篇文章:
http://blogs.msdn.com/mikehall/archive/2008/03/17/net-compact-framework-3-5-component-for-windows-embedded-ce-6-0-catalog-component.aspx

      这篇文章介绍了微软在2008年一月份推出的一个QFE的包,其中包括了.NET Compact Framework 3.5的组件。所谓QFE,就是Quick Fix Engineering,用于快速修复一些BUG或者增加一些新的功能,修改比SP要小,所以可以每月推出。
好了,既然有老大级的人物给我们指明了方向,小弟们跟着干就是了,首先在微软网站上下载这个QFE包:
http://www.microsoft.com/downloads/details.aspx?FamilyID=a83124d5-7c8e-4abe-87fd-69654561be40&displaylang=en

    然后确认你的开发计算机上已经装了下面的东西:
      1. Visual Studio 2005
      2. Visual Studio 2005 SP1
      3. Visual Studio 2005 SP1 Update for Vista (if applicable)
      4. Windows Embedded CE 6.0 Platform Builder
      5. Windows Embedded CE 6.0 SP1 (required if PB 6.0 Tools have been installed)
      6. Windows Embedded CE 6.0 R2

      别紧张,基本上来说,只要你用的是Windows CE 6.0 R2,那么这些东西就都有了。

      接下来,我们确认将Visual Studio 2005关闭,然后运行QFE的安装程序就可以了。如果是在Vista下安装的话,可能会遇到安装文件出错的问题,这是由权限问题造成的。我们可以参考下面的文章解决:
http://support.microsoft.com/kb/950793/en-us
      不过我在Vista下安装时没有碰到这个问题。
      创建.NET Compact Framework 3.5的应用程序

      好了,安装完成后,我们是不是需要打开Visual Studio 2005开始我们的平台定制历程了?不,首先还是让我们先换一台机器。

      换机器干嘛?因为我们遇到了一个逻辑问题——.NET CF 3.5的应用程序在哪里?.NET CF 3.5的应用程序是由Visual Studio 2008开发的,而我们的Platform Builder 6.0是运行在Visual Studio 2005之上的。您可以将VS 2005和VS 2008装在同一台机器上,但是我没有那么做,而是换了台装有VS 2008的机器,来进行下面的应用程序开发。

      需要说明的是,按照常规,我们应该先用Platform Builder 6.0构建一个CE 6.0的平台,然后导出SDK,然后再装有VS 2008的机器上安装,安装完成后再使用VS 2008开发一个针对该CE 6.0平台的应用程序。如果真这么干,拐弯就拐到爪哇国去了。

      幸好Visual Studio 2008为我们提供了另一种方式,还是来看一下:

      打开Visual Studio 2008后,还是首先选择File – New – Project菜单项。在New Project对话框中选择Visual C#中的Smart Device,然后选择创建Smart Device Project,名字随便定。

      接下来的对话框对于经常看我文章的朋友也会很熟悉:

      只是这一次我们选择的Target platform不是Pocket PC或者Smartphone,而是Windows CE,还要记得一定要选择.NET CF 3.5。

      好了,接下来就进入了IDE的窗口设计器,看起来和普通的WinForm程序没有太多区别。我们添加了三个按钮和一个ListBox,还有两个菜单项。

在第一个Button“Message”里添加下面的事件处理函数:
    private void button1_Click(object sender, EventArgs e)
     {
        MessageBox.Show("Hello,.NET CF 3.5");
}
      我承认我没追求,所有程序不都是从Hello World开始的吗?为了要突出一下.NET Compact Framework 3.5的新特性,我们还要添加对于LINQ的支持:
    private void button2_Click(object sender, EventArgs e)
    {
        listBox1.Items.Clear();

        var numbers = new List() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

        var evenNumbers =
              from p in numbers
              where (p % 2) == 0
              select p;

        foreach (var number in evenNumbers)
           listBox1.Items.Add(string.Format("{0} ", number));
}
      关于LINQ我就不多作解释了,记得添加System.Linq的引用,还有:
using System.Linq;
在添加完Linq后,我们还有一个更直接的办法,就是版本号:
    private void button3_Click(object sender, EventArgs e)
    {
       MessageBox.Show(Environment.Version.ToString());
}
      System.Environment中的Version属性可以很直接的告诉我们当前运行的.NET CLR的版本号。具体细节看MSDN帮助吧。

      好了,程序编写好了,接下来就要运行它了。但是我们的Visual Studio 2008里并没有Windows CE的模拟器。没办法,只好选择Windows Mobile 6 Professional的模拟器来跑了。

        事实证明,在应用程序开发方面,Windows CE和Windows Mobile的差距的确不大。程序不但跑起来了,而且菜单还按照Windows Mobile的方式显示到了窗体下方。

         上面就是点击Version按钮后的运行结果,可以看到我们的.NET CLR是3.5的。
        创建支持.NET CF 3.5的OS Design
        OK,终于可以回到我们的Platform Builder里创建包含.NET CF 3.5的OS Design了。我们可以创建一个新的OS Design,或者利用已有的OS Design。
        具体方法请参考:
        革新2410D开发板试用手记(三)
http://www.cnblogs.com/aawolf/archive/2008/06/03/1212696.html
Windows Embedded CE 6.0开发初体验(五)构建CE平台
http://www.cnblogs.com/aawolf/archive/2008/01/15/1040306.html

        当我们打开OS Design的Catalog Item View页面。在Core OS - CEBASE – Application and Services Development下,我们可以看到.NET Compact Framework 2.0和.NET Compact Framework 3.5两个选项。选择.NET CF 3.5的选项和简体中文资源,以及OS Dependencies for .NET Compact Framework 3.5的选项。

      当然,我们也可以在OS Design的创建向导里选择.NET CF 3.5的组件。
为了验证我们的.NET CF 3.5 CLR可以良好运行,我们还需要添加一个.NET CF 3.5的应用程序。怎么添加呢?

      第一步,呃,从另外一台机器上把应用程序拷过来……
      第二步,在Solution Explorer里选择OS Design下的Parameter Files下的Project.bib文件。在《Windows Embedded CE 6.0开发初体验(六)平台定制》中我们详细讨论过bib文件,请参考:
http://www.cnblogs.com/aawolf/archive/2008/02/03/1063444.html
      第三步,将.NET CF 3.5的应用程序加入到OS Design中:

       就一句话,简单吧?然后就是OS Design的编译、下载、运行和调试了。需要说明一点的是,可能由于Debug版的NK.bin太大,我一直没有成功运行起来。不过Release版的一切正常。

       关于编译和下载的话题,可以参考下面的文章:
革新2410D开发板试用手记(六)
http://www.cnblogs.com/aawolf/archive/2008/06/24/1228752.html
Windows Embedded CE 6.0开发初体验(七) 编译和调试平台
http://we.cnblogs.com/article.aspx?id=20

       好了,最后来看一下运行结果:我们点击了Version按钮,显示当前的.NET CF CLR确实是.NET CF 3.5版本。

       最后让大家看看开发板的裸照吧(开发板本来就……)

Windows Embedded Standard的U盘启动

作者:马宁

原文:http://tech.it168.com/a2008/1223/260/000000260962.shtml 

     现在大多数主板都支持USB启动,而U盘便于携带的特点,能够让你打造一个属于你自己的PC环境,使用自己熟悉的界面。现在U盘启动的系统已经非常时髦了,比如Ubuntu Linux。而大家有没有想过将Windows XP放到U盘里?
     Windows XP Home或Pro放在U盘里的确有点难度,但是Windows XP Embedded(也就是现在的Windows Embedded Standard)放在U盘里却不是件太难的事情,我们可以根据自己的需要定制出一个比较小的操作系统镜像(最小可以达到20M左右,一般在300M左右)。
  Windows Embedded Standard开发的文章请参考:
  http://www.cnblogs.com/aawolf/archive/2008/06/25/1229698.html
  准备启动环境
  开发工具自然就是Windows Embedded Studio,具体使用方法请参考《Windows Embedded Standard开发初体验》。除了开发工具外,我们还需要准备存储介质——U盘,从市面上随便买一个就可以,建议容量是1GB,小一点也没关系,最好是USB 2.0的,否则在拷贝文件时会比较慢。
  接下来就是U盘的准备步骤:
  1.使用usboot设置U盘的工作模式
  我们使用的usboot166是第三方工具,可以在雷志刚的博客上找到:
  http://cid-ea7144b242d01ad2.skydrive.live.com/browse.aspx/Public/%e7%ac%ac%e4%b8%89%e6%96%b9%e5%b7%a5%e5%85%b7
  将U盘插到计算机上之后,我们打开USBoot的界面,就可以看到磁盘的列表。

WindowsEmbeddedStandard的U盘启动

  第一个是计算机的硬盘,第二个才是我们要格式化的U盘,所以千万别弄错。
  选择了要格式化的U盘之后,还要选择工作模式,点击界面下方的链接处。

WindowsEmbeddedStandard的U盘启动

  我选择使用的是HDD模式,据说FDD模式也可以,没试过。有一款Thin Client竟然不支持USB-HDD模式启动,抓狂……
  接下来的工作,就是按照提示,等待U盘格式化完成,再写入引导文件。
  其实这一步主要是改变U盘的工作模式,因为我们不使用DOS启动,所以启动文件还要通过下一步来做。
  2.使用ufdprep写入启动信息
  假设Windows Embedded Standard的开发工具安装在C盘,我们可以在下面的目录中找到一个名叫UFDPrep的程序:C:\Program Files\Windows Embedded\utilities

  我们在命令行中执行这个程序:
  如果不知道该怎么使用,可以用ufdprep /?来查询参数。
  如果我们想格式化U盘,则需要使用下面的命令行:
  Ufdprep /size=1000 /ntfs /y g:
  /size,表示使用U盘上多大的空间,不能超过磁盘的最大存储空间;/ntfs,是磁盘格式;/y,表示安全提示时选择y;g:是U盘的盘符。
  可能需要等待一段时间,如果看到格式化成功的提示,则表示该操作完成。
  我们还可以使用下面命令行来验证ufdprep是否成功:
  Ufdprep /verify g:
  制作最小化系统
  接下来我们就需要将操作系统拷贝到U盘上去了。我们要做的不是DOS启动盘,所以刚才将U盘格式化为NTFS格式的了。所以接下来,我们要做一个Windows Embedded Standard的操作系统。因为不知道目标设备的驱动,所以,比较稳妥的方式就是构建一个命令行的Windows Embedded Standard平台,将一些常用工具拷贝进去,个人感觉,比DOS启动盘好用。
  构建步骤,与步骤三类似,所以详情参考“制作XPe镜像”:
  1.  打开Target Designer,创建一个新的Configuration,取名MiniOS。
  2.  在组件列表中,选择Software-> Test&Development 下的MinLogon组件,下图红圈所示位置:

WindowsEmbeddedStandard的U盘启动

  3.选择USB boot 2.0组件(见“制作XPe镜像”一节);
  4. 选择Configuration菜单中的Dependency Check,或者F5,进行依赖检查;
  5. 选择Configuration菜单中的Build Target Image,或者F7,编译操作系统。
  6.编译出来的操作系统大约20M左右,只提供命令行界面。我们将C:\Windows Embedded Images文件夹下的所有文件拷贝到U盘的根目录中。
  7. 我们在U盘的根目录中建一个Tools文件夹,将一些常用工具拷贝进去,比如:
System32目录下的Diskpart、edit等命令
  因为要收集硬件信息,所以要拷贝C:\Program Files\Windows Embedded\utilities下的TAP程序到Tools目录中。大家注意,在这里我们使用的是32位版本的TAP,而不是16位版本的TA,这也说明我们运行的环境是32位操作系统环境。
  8. 将U盘从计算机上安全删除;插到目标设备的USB端口上;
  9. 重新启动目标设备,在BIOS中选择USB-HDD启动;
  10. 进入FBA过程;
  11. FBA过程完成后,会重新启动,然后显示XP的启动画面,进入命令行界面;
  12.运行Tools目录中的TAP命令,该命令会收集硬件信息,在Tools目录下产生device.PMQ文件。

  到这一步,我们的工作就基本完成了,这个命令行的Windows Embedded Standard系统一定要好好保存。自从软盘退出历史舞台后,这是我用过的最适合随身携带的工具盘。宝贝啊。

  制作XPe镜像

  1. 导入PMQ文件
  接下来的工作就比较正常了,将U盘插回到计算机上,将U盘里的device.PMQ文件拷贝到计算机上来。如果之前你没有做完FBA的Mini操作系统,建议你也拷一份出来,毕竟20多M的小东西还是很好用的。
  我们打开Windows Embedded Studio中的Component Designer将PMQ文件转换为组件文件(.sld文件)。Target Designer会根据硬件信息组件(sld文件)判断将哪些驱动程序加入到操作系统镜像中来。
  选择Component Designer的File菜单里的Import选项,会让你打开PMQ文件,然后打开下面的对话框:

WindowsEmbeddedStandard的U盘启动

  点击Start开始导入过程,一般来说,会比较慢,需要几分钟的时间。导入完成后,会生成一个sld文件,将其保存到我们制定的目录下即可。

  2. 导入组件数据库
  接下来,我们要将生成的组件sld文件导入到组件数据库中。在这一步前,请确认所有的Target Designer和Component Designer都已经被关闭。
  然后打开Component Database Manager ,界面如下图所示:

WindowsEmbeddedStandard的U盘启动

  为了导入组件,我们点击Import按钮,打开下面的界面:

WindowsEmbeddedStandard的U盘启动

  点击SLD file文本框后的按钮,上图红圈所示,选择刚才保存的sld文件,然后点击Import按钮。Component Database Manager会提示导入是否成功。

  3.生成WES镜像
  导入sld文件成功之后,我们就可以重新打开Target Designer,来编译我们的操作系统Image文件。
  首先需要新建一个Configuration文件,进入Target Designer主界面。
  我们会看到刚才被导入的组件,会默认出现在组件列表的根目录中,我们双击,将该组件加入我们的操作系统中。
接下来,我们添加功能组件:
  1. Runtime Quick Start Helper Macro,位于Software -> Test & Development目录下

WindowsEmbeddedStandard的U盘启动

  2. USB boot 2.0组件和User Account组件,位于Embedded Enabling Features目录下,其中USB boot 2.0是为了支持USB启动的组件,而User Account组件是默认的登录用户。

WindowsEmbeddedStandard的U盘启动

  3. 设置User Account组件

WindowsEmbeddedStandard的U盘启动

  中间部分是我们已经添加到操作系统中的组件,我们打开User Account组件,选择Settings,在IDE的右侧会显示属性窗口,设置帐号的用户名和密码:

WindowsEmbeddedStandard的U盘启动

  4. 依赖检查;
  5. 编译目标操作系统。
  6. 将编译好的Image文件,拷贝到我们的U盘上。
  7.经过FBA过程后,重启动,我们就可以进入Windows Embedded Standard的界面了。

  参考资料
  http://blogs.msdn.com/ningling/archive/2007/06/20/xpe-usb-2-0.aspx
  http://lzg-ad.blog.sohu.com/77528224.html

Page view tracker