对于.NET,人们比WEB应用程序投入了更大的关注。VB第一次承诺,可以额外提供对控制台程序以及Windows服务的支持。因为这一点,Rob Macdonald回过头来问:用VB.NET究竟可以做什么?换一句话说,VB.NET是否适合你?
目前为止,许多软件公司(包括Microsoft)都将他们的产品压缩在一个安装包里提供给开发人员。我们就一直忍受着那些令人头痛的配置和版本匹配的问题。我们为了产品在真实环境中的运行绞尽脑汁。为了测试,我们还要花费大量的时间来设置一个干净的机器。接下来的几年中,绝大多数的软件供应商和独立软件开发工作室将摆脱这样的工作,原因很简单――这太好了。
打个比方吧,当Microsoft Office XP投入市场时,你既可以选择按照原来产品包的价格购买,或者支付少量的许可费用从而租用一年。将软件象产品那样的买卖转变为租用服务的方式,这就是一部分的转变手段。最终,我想你可以不必在你的PC中(或者PDA,手机,冰箱,无论什么)安装任何东西。你只需要通过永远在线的网络,找到存放你所需要软件的那台服务器即可。在某些领域,这已经是很普遍了(WEB e-mail服务就是一个绝佳的例子)。不过,当大多数的软件都可以通过这样的方式快速的获得时,对我们这样的开发人员来说,是不是合适呢?
因此,从某种程度而言,我认为Microsoft推出VB.NET就是试图帮助我们这些开发人员为这些即将来临的以服务为中心的范例做好准备。WEB服务之所以受到如此多的关注,是因为通过这些技术(HTTP,XML,SOAP),任何操作系统(包括Windows, Linux, IBM, Palm)都将有可能以这样的方式制作并提供各自的服务。这当然也部分解释了为什么HTTP,XML,SOAP都是那样的简单。因为计算机本身就必须“读懂”他们。
当然,并不是所有的应用程序都可以通过基于服务的方式来获得。VB.NET针对完成桌面上的一些新的、更好的应用,提供了一些真正实际的新特性。举例而言,在VB6中使用的那些“美丽的”窗体只适用于VB,而在.NET中新的Windows窗体不单可以提供给其他.NET语言使用,而且还有一些重大的创新。我特别高兴的看到,它对窗口缩放的支持,以前这都是需要我自己编写的,现在我只要简单的点击鼠标就可以建立起窗口缩放的规则。
控制台程序
VB.NET带来最大的好处之一就是它允许VB开发人员实现一些以前做不了的事。如类的继承和结构化的错误处理。另一项让我们长久等待的功能就是它可以用来编写那些通过命令行和用户交互的应用程序了。VB.NET使这个工作变得简单,同时保留了所有.NET的功能。
在Visual Studio.NET中,你可以建立一个新的工程,叫做“控制台程序(Console Application)”。其实,你完全也可以不通过Visual Studio来建立VB.NET的应用程序。你真正需要的只是.NET Framework SDK和记事本,因为VB编译器作为一个完全独立的产品,已经和Visual Studio脱离了。(事实上,无论是编译VB的程序,还是为已定义的数据集自动生成源代码,这些Visual Studio.NET看来神奇的功能,都是通过.NET Framework中附带的工具来实现的。Visual Studio.NET只是把他们集成到了一个易用的开发环境中。作为独立的命令行软件他们都是可用的。)
就让我们用命令行的方式建立一个命令行的程序吧。以下为我在记事本中输入的一些文本,并把它保存为文件“speaktome.vb”:
Imports System
Imports Microsoft.VisualBasic
Module Module1
Sub Main()
Dim i, count As Integer
Try
count = CInt(Command())
For i = 1 To count
Console.WriteLine("Hello")
Next
Catch
Console.WriteLine("Invalid argument")
End Try
End Sub
End Module
这段代码按照count数值,循环运行若干次,每次按照标准输出文本流,输出“Hello”。缺省的它就是一个命令行控制程序。程序通过调用command()函数初始化count变量,它取代了我们在VB6中熟悉返回命令行中在程序名后面出现的所有文本的全局变量Command。
尽管这些代码已经是相当的直接了,我们仍然需要一些注解。首先,我们注意到一开始它就使用Imports申明了对两个名字空间的引用。名字空间System包含了Console类,而名字空间Microsoft.VisualBasic则包含了命令函数,包括全部很多新的功能。当你在Visual Studio中建立一个VB.NET工程时,这些名字空间会被自动的导入,但当我们直接使用编译器的时候,我们就需要自己手工的添加他们了。并且注意我声明我那两个变量的方式。在vb6中,象这样的dim声明,会建立一个Variant,一个整数,但在.NET中。这种传统的VB方式彻底消失了,我得到了我所预期的两个整数。
VB.NET编译器可以处理不同的参数,但当我只是将.vb文件作为一个单一的参数传递给它时,它将编译一个和它同名的EXE文件。图1(http://msdn.microsoft.com/library/en-us/dnvbdev01/html/rob0301fig1.jpg)显示了当我编译完这个程序时的控制会话。(编译器叫做“VBC”)
命令行的编译器使得自动化的编译进程变得简单。能够编写控制台应用程序,对于VB来说,虽然微不足道但确实是一次有价值的扩展。
Windows服务
另一种新类型的应用程序是Windows服务。除了那些胆大的VB开发人员,这可能超越了其他人的视野。典型的,这是一些长久运行的程序,而并不需要依靠登录用户或客户程序来保持它的运行。它们没有自己的用户界面,可以在它们自己独有的安全级别和会话上下文中运行。我们比较熟悉的Windows服务范例包含了从打印池到SQL服务器以及它的分布式事务协作(DTC)。
服务只可以运行在NT和2000下运行,它们通过Microsoft Management Console (MMC)提供了一个专门的管理界面。你可以想象,编写一个服务会涉及到非常多的内容,在这里我不可能花费太多的篇幅,但是我可以告诉你如何建立一个简单的样例。
在.NET beta1版的在线帮助中,有许多相关的信息-在写这篇专栏时我就在使用beta1版--如果你打算建立一个可操作的Windows服务程序,你应该仔细的看一看。
我介绍一下我将建立的Windows服务原型,它用来记录指定的机器上正在运行的进程数量。是的,我知道我可以使用PerfMon来实现这个功能,不过我只是装作我想扩展我的服务,以便它可以计算一些统计功能,并把他们写入数据库,也许还可以在超过某一个阀值时,发mail给我。
我首先开始建立一个新的Visual Studio.NET应用程序,选择VB作为我的开发语言,而工程类型则是Windows服务。这个操作自动为我建立了一个新的类,它是继承了.NET内建了System.ServiceProcess.ServiceBase类。同时它提供给我一个可视化的设计器,一个图形化的快速开发工具,它特别的为那些本身没有用户界面的工程。我可以点击这个设计器,设定我的服务的名字(我命名为"Process Tracking")。接着我从工具栏中拖了两个元件到设计器中-一个PerformanceCounter元件、一个Timer元件。我可以设置通过属性栏来设置它们,感觉上他们是那种可视的控件,尽管我不需要一个窗体来放置它们。我配置Timer每60秒激活一次,PerformanceCounter则用来监控在我机器上运行的进程数量。你可以在图2(http://msdn.microsoft.com/library/en-us/dnvbdev01/html/rob0301fig2.jpg)中看见设计器和PerformanceCounter元件的属性设置。(我可以在设计器和代码窗口之间进行切换,就如我建立一个窗体一样。)
Visual Studio生成缺省的Sub Main,用来处理开始服务的运行。因为你的代码是从ServiceBase类中继承来的,那么在服务的生命周期中,你可以获取一些标准事件。这些事件在服务的生命周期中是至关重要的。它们是:
• OnStart
• OnStop
• OnPause
• OnContinue
• OnShutDown
这些代码和VB6窗体中的Load/Unload/Activate/Deactivate事件非常象。这里是我对OnStart和OnStop设计的编码:
Protected Overrides Sub OnStart(ByVal args() _
As String)
Dim fs As New FileStream ( "c:\log.txt", _
FileMode.OpenOrCreate, FileAccess.Write)
Dim sw As New StreamWriter(fs)
sw.BaseStream.Seek(0, SeekOrigin.End)
sw.WriteLine("Service Started: " + CStr(Now()))
sw.Close()
End Sub
Protected Overrides Sub OnStop()
Dim fs As New FileStream("c:\log.txt", _
FileMode.OpenOrCreate, FileAccess.Write)
Dim sw As New StreamWriter(fs)
sw.BaseStream.Seek(0, SeekOrigin.End)
sw.WriteLine("Service Stopped: " + CStr(Now()))
sw.Close()
End Sub
这些例程都是打开一个log.txt的文件,写入一个带有时间戳的简单信息。StreamWriter类提供了我们一个有效的方法来创建一个字符流,而FileStream类则允许将StreamWriter类和一个物理文件联系起来。关闭StreamWriter同时也关闭了他所连接的文件。
Public Sub Timer1_Tick(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Timer1.Tick
Dim LogRecord As String = CStr(Now())+ " "
Dim fs As New FileStream("c:\log.txt", _
FileMode.OpenOrCreate, FileAccess.Write)
Dim sw As New StreamWriter(fs)
LogRecord += PerformanceCounter1.NextValue.ToString
sw.BaseStream.Seek(0, SeekOrigin.End)
sw.WriteLine(LogRecord)
sw.Close()
End Sub
如你所见,代码用当前的时间初始化了一个字符串,并将它和从PerformanceCounter读出的值(它返回了当前在我机器上运行的进程数量)连接起来。然后将这个字符串写入log文件的最后。
将这个工程转变为服务的话,需要比简单的编译它多做一些。首先,你需要增加一些安装代码,这样程序在作为服务被安装后就能正常工作了。很幸运,可视化的设计器提供了菜单选项("Add Installer"),它可以自动的生成这段代码。然后,在你编译了这个工程后,你需要在命令行状态下运行InstallUtil.exe(这是.NET SDK的工具之一)处理已编译的工程,这样就将服务安装到了你的系统上并建立必须的注册表项目。
一旦安装了服务,我们需要启动它-通过服务管理工具这一点都不难。不同的系统,访问这个工具的方法也不同。在Windows 2000 Professional中,你可以在控制面板中的管理工具得到。在图3(http://msdn.microsoft.com/library/en-us/dnvbdev01/html/rob0301fig3.jpg)中,你可以看到服务已经被手动启动了。你也可以看到它被配置为自动启动,这就意味着下次我启动我的系统,服务就开始运行,甚至在我还没有登录系统之前。
图4(http://msdn.microsoft.com/library/en-us/dnvbdev01/html/rob0301fig4.jpg)显示了在我的系统上,这个服务生成的部分log。在这期间,我建立了一些进程,退出登录,再次登录,重启机器(这也导致了服务的重新启动)。
.NET工程类型
我着重介绍了两类特定的VB.NET工程。对于VB开发人员可以实现的工程类型都列在了表1中(无论如何,在beta1中)还有一些和独立于语言的工程类型,如:安装,配置工程,数据库工程,以及分析工程。
工程类型 描述
Windows Application 通过Windows 基于窗体的用户界面生成应用程序。
Class Library 为其他应用程序中生成class libraries。
Windows Control Library 在基于Windows的控件。
Web Application 用静态或动态Web页面作为用户界面生成应用程序。
Web Service 从其它应用程序中生成 Web Services 。
Web Control Library 生成在Web 应用程序中的控件。
Console Application 用于生成命令行应用程序。
Windows Service 为Windows生成服务。
展示控制台与服务应用程序的原因之一是要强调一点:VB.NET 并不强制我们都要变成n层 Web开发人员。 事实上,Microsoft大量投资以提供对传统桌面应用程序的支持。虽然.NET意味着要学习大量的新东西,你可以把VB.NET看作是 一场雄心勃勃的大变革—它会扫清VB的一些弊端,在提供向后兼容的前提下, 把它推向鼎盛。
为什么选择VB.NET?(转贴)
80酷酷网 80kuku.com