WPF是Windows Presentation Foundation的缩写,是.NET Framework 3.0的一部分。.NET 3.0是Windows Vista技术中最重要的,与开发人员关系最大的一项用户界面的创新。除了WPF,.NET 3.0也就是之前的WinFX,还包括Windows Communication Foundation(WCF)和Windows Workflow Foundation(WF)。
进入正题之前先唠叨两句微软混乱的命名,WPF和WCF这种缩写还算正常,Windows Workflow Foundation缩写成WF让人感觉有点难以捉摸。组建对象模型COM这名字也很烂,以前google上甚至不让搜,因为作为网站后缀出现过于频繁;后来又有.NET,和COM类似,比COM还要烂,这回还多了一个点,同样没法用google搜到合适的结果;.NET 3.0则是继承了.NET的传统,一如既往的烂,甚至青出于蓝,原因如下:.NET 2.0是.NET 1.0的更新换代,.NET 2.0比.NET 1.0支持功能更多,是1.0的超集,这是正常的软件版本号;但是.NET 3.0却是.NET 2.0的扩展,两者功能没有交集,.NET 3.0甚至依赖于.NET 2.0。开发人员还好,说两句都能明白,反正据说是用户搞都蒙了。接下来真正的.NET 2.0的升级版出现了估计要叫.NET 3.5,.NET 3.0的升级版会叫什么?那时所有人都乱了。
言归正传,msbuid是微软为开发人员提供的一款项目构建工具,用XML做项目构建的描述,有点类似于开源项目ant。ant是用java语言写的,功能主要面向java程序的构建,所以.NET平台也有一个nant。以前开发java的时候折腾过一阵ant,了解比较多,也曾试用过nant一晚上,感觉nant在基础结构方面具有很多比ant更人性化、更便捷的设计,用nant写循环和判断就要比ant方便得多。msbuild的优势是“微软制造”,按理来说应该会比较适合.NET的开发。
现在Visual Studio 2005生成的所有Project文件都已经是msbuild格式的xml文件了,.NET Framework SDK中就已经包含msbuild的命令行工具和编译器,可以用来构建Visual Studio生成的项目,而不需要安装Visual Studio。
我学习msbuild的主要目的有三:
- 少安装一个盗版软件;
- 撕开用户界面的层层封装,看看.NET Framework纯朴的一面;
- 了解一下WPF和.NET程序是怎么构建的。
下面看看四个简单的例子。
第一个例子:C#和msbuild的Hello World
- sample.cs的代码。随便从google上搜了一个C#的例子,不是重点。
class MainApplication { static void Main(string[] args) { System.Console.WriteLine("Hello World!"); } }
- sample.proj。msbuild格式的项目文件
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003“> <ItemGroup> <Compile Include=”sample.cs”/> </ItemGroup> <Target Name=”Build”> <Csc Sources=”@(Compile)” /> </Target> </Project>
该文件可谓是最简单的msbuild文件,包含一个ItemGroup,其中定义了一个Compile元素,指定了源码sample.cs;一个Target元素,只包含一个任务,用Csc命令编译源码。这里的Project、ItemGroup、Target、Csc等标签都具有特殊含义,而Compile标签则不具有特殊含义,只是用户定义的名字而已,该标签只需要同Csc的Source属性值前后一致就可以。msbuild文件中还可以定义多个Target,这时如果不特别指定,第一个是默认的Target。和Ant类似,msbuild文件中还可以指定Property,放在PropertyGroup标签中。
这个例子只要装了.NET Framework 2.0 SDK,就可以试。开一个SDK命令行,在项目目录下,运行msbuild命令,msbuild会自动寻找该目录下有没有*.proj, *.csproj, *.vbproj等文件,如果有,就会根据该文件的描述开始构建。然后就可以得到sample.exe文件。
第二个例子:XAML的Hello World
- hello.xaml
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml” > <Button>Hello, world!</Button> </Page>
XAML是WPF的一部分,是一种XML的用户界面描述语言。有点类似于Linux下面的glade,但是glade的界面描述语言纯手工书写可能没有XAML方便(我没手写过glade界面),用XAML手写界面和写代码差不多(没写过复杂的),可以快如行云流水。
这个例子需要运行在Vista下,或者在老版本Windows上安装.NET Framework 3.0也行。把这个文件存为hello.xaml,双击之,将启动IE显示用户界面效果。
可以看出XAML文件中只有界面设计,没有任何后台代码。只有在加上后台业务逻辑之后,才能成为一个完整的WPF程序。
第三个例子:WPF的Hello World
- App.xaml
<Application x:Class="WpfSample.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml” StartupUri=”Page1.xaml”> </Application>
所有的WPF程序都需要有一个App.xaml。这时XAML文件都会先编译成.NET中间代码。x:Class=”WpfSample.App”表示这个标签会被编译为WpfSample名字空间下的App类。StartupUri指定该WPF程序的启动页面文件名。既然有启动页面,就有其他页面,WPF程序支持多页面并可在多个XAML页面之间切换。
- Page1.xaml
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml” x:Class=”WpfSample.Page1″ > <Button Click=”HelloWorld” Name=”Button1″>Click Me!</Button> </Page>
这个xaml与上个例子相比,只有三处变化:一处是Page标签多了x:Class属性,前面已经解释过它表示编译后的类名是WpfSample名字空间中的Page1类;另两处分别是Button的Click属性,和Name属性。Click属性指定Button的点击响应函数为(Page1类的)HelloWorld函数,Name属性指定该Button在代码中的引用名为Button1。这三处都必须和后面业务逻辑代码一致。
- Page1.xaml.cs
using System; using System.Windows; using System.Windows.Controls; namespace WpfSample { public partial class Page1 : Page { void HelloWorld(object sender, RoutedEventArgs e) { MessageBox.Show("Hello, world!"); } } }
这个源码中定义了一个部分类(Partial Class)叫Page1,包含一个消息响应函数HelloWorld。和上面的xaml源码对应。
- wpfsample.proj
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003“> <PropertyGroup> <OutputType>winexe</OutputType> </PropertyGroup> <ItemGroup> <ApplicationDefinition Include=”App.xaml” /> <Page Include=”Page1.xaml” /> <Compile Include=”Page1.xaml.cs” /> </ItemGroup> <ItemGroup> <Reference Include=”System” /> <Reference Include=”WindowsBase” /> <Reference Include=”PresentationCore” /> <Reference Include=”PresentationFramework” /> </ItemGroup> <Import Project=”$(MSBuildBinPath)Microsoft.CSharp.targets” /> <Import Project=”$(MSBuildBinPath)Microsoft.WinFX.targets” /> </Project>
这是最简单的一个WPF项目文件。与前面的msbuild文件相比要复杂一点:多一个Property的定义,OutputType为winexe表示编译为图形界面程序(不带命令行窗口);另外ItemGroup中也多了一些内容,尤其是Reference。最后,这个文件没有定义任何Target,只是Import两个系统预定义targets文件。
将这个例子中的4个文件放到一个目录下,打开命令行,直接运行msbuild就可以编译生成可执行程序wpfsample.exe。下图是该程序的运行效果图:
第四个例子:XBAP的Hello World
XBAP是XAML Browser Application的缩写。顾名思义,就是用XAML作界面描述,在浏览器中运行的程序。XBAP可以取代以前用ActiveX、Java Applet、Flash写的B/S结构的富客户端应用程序。
写一个XBAP程序和写一个WPF程序是基本上是完全一样的。唯一的区别是他们的构建方式不尽相同。也就是说为了将普通WPF程序编译为能在浏览器中运行的程序,除了项目文件之外,其他文件都不需要修改。下面是修改后的项目文件
- xbapsample.proj
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003“> <PropertyGroup> <OutputType>winexe</OutputType> <HostInBrowser>True</HostInBrowser> <Install>False</Install> <TargetZone>Internet</TargetZone> <StartAction>Program</StartAction> <StartProgram>$(WINDIR)System32PresentationHost.exe</StartProgram> <ApplicationExtension>.xbap</ApplicationExtension> <StartArguments>-debug “$(MSBuildProjectDirectory)bin$(Configuration)$(AssemblyName)$(ApplicationExtension)”</StartArguments> <SignManifests>true</SignManifests> <BootstrapperEnabled>false</BootstrapperEnabled> <ManifestKeyFile>TemporaryKey.pfx</ManifestKeyFile> <ManifestCertificateThumbprint>958189C248E39D2C5408327122F0F83E3DBBF6D1</ManifestCertificateThumbprint> </PropertyGroup> <ItemGroup> <ApplicationDefinition Include=”App.xaml” /> <Page Include=”Page1.xaml” /> <Compile Include=”Page1.xaml.cs” /> <None Include=”TemporaryKey.pfx” /> </ItemGroup> <ItemGroup> <Reference Include=”System” /> <Reference Include=”WindowsBase” /> <Reference Include=”PresentationCore” /> <Reference Include=”PresentationFramework” /> </ItemGroup> <Import Project=”$(MSBuildBinPath)Microsoft.CSharp.targets” /> <Import Project=”$(MSBuildBinPath)Microsoft.WinFX.targets” /> </Project>
上面的红色内容是相比原来的wpfsample.proj多的部分。基本上都是对于任何项目都通用的内容。因为XBAP程序是网络直接安装运行,可能遇到安全问题,所以要求XBAP程序必须内嵌数字签名。ManifestKeyFile指定签字用的证书文件名,ManifestCertificateThumbprint指定证书文件摘要。在本例中,项目目录中还必须有一个TemporaryKey.pfx证书文件用于数字签名。pfx文件应该是标准的PKCS#12格式的个人数字标示文件,我则是直接从SDK中找了一个现成的文件,改了个名。下图是该程序在浏览器中的执行效果。
参考资源
上面的例子编译出来的可执行程序在Windows Vista环境中都可以运行,如果不想装Windows Vista,装.NET Framework 3.0 Runtime和2.0 Runtime之后也可以运行。如果想编译上面的例子,还需要安装Windows SDK和.NET 2.0的SDK,如果觉得msbuild这种命令行工具就够了,Visual Studio都没有必要装。
Windows Vista SDK相关下载
MSBuild在MSDN上的帮助