共用 Visual Basic 6 和 Visual Basic .NET 的最佳实践

发布日期: 2007-06-08 | 更新日期: 2007-06-08

Scott Swigart

Swigart Consulting LLC.

适用于:

Microsoft Visual Basic 6

Microsoft Visual Basic 2005

Microsoft Visual Studio 2005

摘要:Microsoft Visual Basic 6 应用程序可以访问 .NET 类库,但它必须通过互操作层(即客户端可调用包装)才能进行此访问。这种方式先包装所需的 .NET 类,然后再显示它,这样该类就像传统的 COM 对象一样,可以在任何能够使用 COM 对象的环境中使用。了解如何创建这些包装。

下载本文的 Visual Basic Fusion—Best Practices.msi 代码示例。

*
本页内容
概述概述
了解 Visual Basic 6 和 Visual Basic .NET 运行时了解 Visual Basic 6 和 Visual Basic .NET 运行时
调用 Framework调用 Framework
使用 Visual Basic .NET 创建包装使用 Visual Basic .NET 创建包装
选项比较选项比较
使用示例代码使用示例代码
结论结论

概述

许多组织都有大量 Microsoft Visual Basic 6 基本代码,并在努力制定有关这些旧代码的最佳决策。当决定如何处理 Visual Basic 6 应用程序时,基本上有三个选择。可以将 Visual Basic 6 应用程序保持原样,不将任何新技术与该旧应用程序合并。可以将 Visual Basic 6 应用程序完整迁移到 Visual Basic .NET。或者,可以保留 Visual Basic 6 代码,与 Visual Basic .NET 互操作,以便轻松将 .NET Framework 中的任何功能添加到现有的应用程序中。本章将讨论最后这个选择(也称为 Visual Basic Fusion)的最佳实践。

返回页首返回页首

了解 Visual Basic 6 和 Visual Basic .NET 运行时

Visual Basic 6 应用程序本质上是 COM 应用程序。如果想要在 Visual Basic 6 中执行某些操作(例如访问数据库或生成用户界面),您可以添加对相应 COM 组件的引用,然后使用它包含的功能。其他应用程序通常也通过 COM 组件来公开功能。例如,Visual Basic 6 应用程序可以使 Microsoft Word 或 Excel 执行自动操作,因为这些应用程序公开了 COM 接口。

Visual Basic .NET 应用程序不基于 COM,默认情况下不公开 COM 接口。Visual Basic .NET 应用程序可以访问 .NET 类库中的功能。Microsoft .NET Framework 包括成千上万个类库,可允许 Visual Basic .NET 应用程序与数据库进行通信以及访问 Internet、注册表、文件系统、事件日志、系统信息及更多内容。.NET Framework 类库 (FCL) 中提供的功能的数量远远超过 Visual Basic 6 提供的功能。

Visual Basic 6 和 Visual Basic .NET 的构建技术互不兼容。Visual Basic 6 应用程序可以访问 .NET 类库,但它必须通过一个互操作性层(称为客户端可调用包装)才能进行此访问。这种方式先包装所需的 .NET 类,然后再显示它,这样该类就像传统的 COM 对象一样,可以在任何能够使用 COM 对象的环境(Visual Basic 6、Visual Basic 5、ASP、VBA、VBScript 等)中使用。

返回页首返回页首

调用 Framework

如文章在 Visual Basic 6 中使用 .NET Framework 类库中所述,调用 .NET framework 的第一步是将所需的 .NET framework DLL(也称为程序集)注册为 COM 对象。这可以通过随 .NET Framework SDK(作为 Visual Basic Express 产品的一部分安装)提供的 regasm 命令行实用工具来完成。如果您未安装 Visual Studio 2005,强烈建议您下载并安装免费的 Visual Basic Express。

演练 1. 注册 System.dll 以使其可在 Visual Basic 6 中使用

1.

导航到“开始”|“运行”。

2.

在“运行”对话框中,输入“CMD”,然后单击“确定”。

3.

输入“cd C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727”。

4.

输入“regasm system.dll”。

注册了该程序集后,您就可以像使用任何其他 COM 对象一样,从 Visual Basic 6 添加对它的引用:

.

1. Visual Basic 6 添加对 system.dll 的引用

此外,由于已经为 System.dll .NET 程序集创建了 COM 可调用包装,Visual Basic 6 将能够调用该程序集。不过,若要使 .NET 类及其函数显示在 COM 可调用包装中,.NET 类必须遵循一组相当严格的规则。因此,从 Visual Basic 6 中只能直接调用 System.dll 中很少一部分类。可从 Visual Basic 6 调用的一个函数是 WebClient.DownloadFile 函数。

代码清单 1. Visual Basic 6 调用 DownloadFile 函数

Dim webDownload As System.WebClient
Set webDownload = New System.WebClient
webDownload.downloadFile _ 
    "http://www.ssec.wisc.edu/data/west/latest_westir.jpg", _
    App.Path & "\latest_westir.jpg"
返回页首返回页首

使用 Visual Basic .NET 创建包装

上面的示例应当不会产生这样的错觉:只需将 Regasm 用于任何 .NET 程序集,即可在 Visual Basic 6 中使用所有 .NET 功能。在几乎所有情况下,如果您想要调用 .NET framework、第三方 .NET 组件或开放源 .NET 库,都必须写入 Visual Basic .NET 包装类。这是由于 .NET 类必须遵循相当严格的规则,才能将其自身正确表示为 COM 对象,大多数 .NET 类不遵循这些规则。

要访问 .NET 功能,需要在 Visual Basic .NET 中创建一个遵循 COM 互操作性规则的类,此类代表 Visual Basic 6 应用程序调用所需的 .NET 代码。

.

2. 通过 Visual Basic .NET 包装类从 Visual Basic 6 调用 .NET Framework

简单包装类

举一个简单的示例:.NET Framework Guid 类。GUID 是“全局唯一标识符”。Windows 中很多地方使用 GUID 来唯一标识 COM 对象、文件和用户以及其他任何内容。它们采用字符串的形式,例如:13427d57-ccb5-42fd-91f7-b49d4c2ae9a3。GUID 最大的好处是:如果正确生成了一个 GUID,您可以 100% 确定任何其他人都不会生成相同的 GUID。

在 Visual Basic 6 中,没有简单的方法可生成 GUID,但是在 Visual Basic .NET 中,只需一行的代码即可完成:

代码清单 2. Visual Basic .NET 中生成 GUID

Dim g as Guid = Guid.NewGuid()

遗憾的是,Guid 类没有以可从 Visual Basic 6 中直接调用的方式来生成。要从 Visual Basic 6 使用此功能,您需要创建一个非常简单的 Visual Basic .NET 包装类。此 Visual Basic .NET 包装类将其自身公开为可在 Visual Basic 6 中使用的 COM 对象,并根据需要调用 .NET Framework Guid 类。

我能使您对 5000 个类感兴趣吗中详细说明了如何创建包装类,这里将复述基本过程:

演练 2. Guid 类创建 Visual Basic .NET 包装

1.

下载并解压缩本文的示例代码。

2.

ComClass.zip 文件复制到 C:\Documents and Settings\[User Name]\My Documents\Visual Studio 2005\Templates\ItemTemplates\Visual Basic

如果您使用的是 Visual Studio 2005,可以跳过步骤 2。不过,Visual Basic Express 默认情况下不包含 COM 类模板,而此模板对于将 .NET Framework 公开为 COM 对象很有用。将 ComClass.zip 文件复制到此文件夹中后,COM 类模板将可用于 Visual Basic Express。

3.

从“Visual Basic Express”,选择“文件”|“新建工程”菜单命令。

4.

在“新建工程”对话框中:

1.

在“模板”窗格中,选择“类库”。

2.

在“名称”字段中,输入“NetFxWrapper”。它将成为组件的名称,将显示在 Visual Basic 6 提供的引用列表中。

.

3. Visual Basic .NET 中创建包装工程

5.

单击“确定”。

6.

在“解决方案资源管理器”中,删除“Class1”。

7.

选择“工程”|“添加新项”菜单命令。

8.

在“添加新项”对话框中:

1.

在“模板”窗格中,选择“COM 类”。

2.

在“名称”字段中,输入“GuidWrapper”。

.

4. 创建 Visual Basic .NET 包装 COM

9.

单击“添加”。

10.

20 (End Sub 之后、End Class 之前)中,输入以下内容:

代码清单 3.Visual Basic .NET 中的包装函数

Public Function NewGuid() As String
        Dim g As Guid = Guid.NewGuid()
        Return g.ToString()
    End Function

这会创建 Guid 类的一个实例,并将其分配给新生成的 Guid 值。然后它将 Guid 值转换为字符串,并返回该字符串。

11.

选择“生成”|“生成 NetFxWrapper”菜单命令。这将编译该组件并将其注册为 COM 对象。

现在您已经创建了包装,可以在 Visual Basic 6 中调用它了。

演练 3. Visual Basic 6 中使用包装

1.

启动 Microsoft Visual Basic 6.0。

2.

在“新建工程”对话框中,选择“标准 Exe”,然后单击“打开”。

3.

选择“工程”|“引用”菜单命令。

4.

添加对 NetFxWrapper 的引用。

.

5. 添加对 Visual Basic .NET 中创建的 COM 对象的引用

5.

在窗体中添加 CommandButton 和 TextBox。

6.

将 CommandButton Caption 属性设置为 Generate。

7.

对于 CommandButton 的 click 事件,输入:

代码清单 4. Visual Basic 6 调用包装

Private Sub Command1_Click()
    Dim gw As NetFxWrapper.GuidWrapper
    Set gw = New NetFxWrapper.GuidWrapper
    
    Text1.Text = gw.NewGuid
End Sub

8.

运行应用程序。每次单击该按钮时,Visual Basic 6 应用程序都会调用 Visual Basic .NET 包装并生成新的 GUID。该 GUID 将显示在 TextBox 中。

.

6. 显示 GUID

创建包装的规则

由于 Guid 类并不遵循 COM 互操作性规则,因此需要包装类。包装类必须遵循的这些规则是:

1.

包装必须公开默认构造函数

在 Visual Basic 6 中,您需要先创建一个对象实例,然后使用属性和方法初始化该对象。例如:

代码清单 5. Visual Basic 6 中初始化连接对象

Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
cn.ConnectionString = _
    "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=mydb.mdb;" & _
    "User Id=admin;Password=;"

要设置连接对象,必须首先创建该对象的实例,然后设置属性(例如 ConnectionString)。在 Visual Basic 6 中,对象的创建和对象属性的初始化必须在不同的步骤中完成。

但是,在 Visual Basic .NET 中,可以在创建对象的实例时指定初始化信息。Visual Basic .NET 中的等效代码是:

代码清单 6. Visual Basic .NET 中的构造函数传递参数

Dim cn As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" & _
    "Data Source=mydb.mdb;User Id=admin;Password=;")

您可以看到对象是在一行代码中创建并初始化的。之所以可以做到这一点是因为创建该对象时会调用 .NET 类型中的 Sub New,此 Sub New 可以采用参数。一个类甚至可以有多个 Sub New 构造函数方法,每个都采用不同的参数类型或参数数量。

代码清单 7. Visual Basic .NET 类构造函数

Public Sub New()
End Sub
Public Sub New(ByVal connectionString As String)
End Sub

当创建类的实例时,Visual Basic .NET 编译器会计算出将自动调用哪一个 Sub New。如果创建了不包含任何参数的 OleDbConnection 的实例,它将调用不采用任何参数的 Sub New。如果创建了带有连接字符串参数的 OleDbConnection 的实例,编译器将自动调用将字符串作为参数的 Sub New。

不采用任何参数的 Sub New 称为“默认构造函数”,这意味着如果未提供参数,默认情况下将调用该方法。

由于 Visual Basic 6 无法在您创建对象的实例时传递参数,.NET 类必须提供默认构造函数,否则您无法在 Visual Basic 6 中直接使用它。许多 .NET Framework 类不能直接使用的一个原因是它们的 Sub New 方法都需要参数。它们不公开默认构造函数,因此您无法在 Visual Basic 6 中创建它们的实例。

您可以为这些对象创建包装类。包装公开默认构造函数,但是当包装创建实际 .NET framework 类的实例时,它会将所需的参数传递给该类的 Sub New。

举一个具体的示例:.NET Framework FileInfo 类。此类允许您获取磁盘文件的多个特征。但是它不包含默认构造函数。FileInfo 的 Sub New 需要所需的文件的路径,但是它可以按以下方法包装:

代码清单 8. FileInfo Visual Basic .NET 包装

Private fi As FileInfo
Public Sub New()
End Sub
Public Sub Initialize(ByVal filePath As String)
    fi = New FileInfo(filePath)
End Sub

此包装包含不接受任何参数的 Sub New。这会允许此类注册为 COM Interop,以便 Visual Basic 6 应用程序可以创建它的实例。在 Visual Basic 6 应用程序调用 Initialize 方法之前,不会创建内部 FileInfo。将按如下方法在 Visual Basic 6 中使用 FileInfo:

代码清单 9. Visual Basic 6 中使用 FileInfo 包装

Dim fi As NetFxWrapper.FileInfoWrapper
Set fi = New NetFxWrapper.FileInfoWrapper
fi.Initialize ("c:\somefile.txt")

2.

许多数据类型必须在 Visual Basic 6 Visual Basic .NET 之间进行转换

创建包装的大多数工作归结为将 Visual Basic .NET 数据类型转换为 Visual Basic 6 可以使用的类型。请考虑以下两个方法,一个返回字符串,另一个返回 Guid 数据类型:

代码清单 10. Visual Basic .NET 中的包装函数

Public Function NewGuidAsString() As String
        Dim g As Guid = Guid.NewGuid()
        Return g.ToString()
    End Function
    Public Function NewGuidAsGuid () As Guid
        Dim g As Guid = Guid.NewGuid()
        Return g
    End Function

在 Visual Basic 6 中,调用 NewGuidAsString 不会出现问题,因为字符串可以轻松在 Visual Basic 6 和 Visual Basic .NET 之间传递。但是,在 Visual Basic 6 中调用 NewGuidAsGuid 会生成以下错误:

.

7. Visual Basic 6 中调用 NewGuidAsGuid 所生成的错误

这是因为 Guid 类型的对象无法直接从 Visual Basic .NET 传递到 Visual Basic 6。当创建 .NET 类的包装时,大多数时间用在将 .NET 数据类型转换为可在 Visual Basic 6 中使用的类型上。

还可以使用 .NET MarshalAs 属性来指定参数和返回值应当使用哪一个 Visual Basic 6 类型。例如,如果 Visual Basic .NET 函数返回 Decimal 数据类型,则不能从 Visual Basic 6 调用此函数。但是,可以指定将返回值转换为 Currency 类型。这样,Visual Basic 6 就可以使用该函数而不会产生错误了。

代码清单 11. 使用 MarshalAs Visual Basic 6 Visual Basic .NET 类型之间转换:

Public Function ReturnDecimal() As _
<Runtime.InteropServices.MarshalAs(Runtime.InteropServices.UnmanagedType.Currency)> _
    Decimal
    Return 1.1
End Function

下表列出在 Visual Basic .NET 和 Visual Basic 6 类型之间完成的自动转换:

1. Visual Basic .NET Visual Basic 6 的类型转换

Visual Basic .NET 类型

Visual Basic 6 类型

Boolean

Boolean

Byte

Byte

Char

不支持,应以字符串形式返回到 Visual Basic 6。

DateTime

Date

Decimal

不支持,应以 Single、Double 形式返回,或者使用 MarshalAs 属性以 Visual Basic 6 Currency 形式返回。

Double

Double

Guid

不支持,应以字符串形式返回到 Visual Basic 6。

Integer

Long

Long

不支持

Object

Object

SByte

在 Visual Basic 6 中不受支持,应当以 Integer 形式返回。

Short

Integer

Single

Single

String

String

TimeSpan

不支持,应使用 TotalSecondsTotalMinutes 等函数以 Double 形式返回。

3.

共享函数不互操作

在 Visual Basic 6 中,为您提供了可以从代码中任何位置调用的全局函数。全局函数的问题是很难知道两个不同全局函数之间是逻辑相关的。在 Visual Basic .NET 中,可以将全局函数组合到一个类中。其好处是您可以使用类名来调用函数,从而不必创建该类的实际实例:

代码清单 12. 共享函数

If Not File.Exists(someFile) Then
    MessageBox.Show("File not found")
End If

在此例中,从 File 类直接调用 Exists 函数。代码未创建 File 类的实例来调用此方法;而是从 File 类型直接调用 Exists。此种函数称为共享(或静态)函数,在整个 .NET Framework 中都会用到它们。

共享函数的问题是它们不与 Visual Basic 6 进行互操作。若要使 Visual Basic 6 调用某函数,该函数必须是真正的全局函数,或者是从类的实例调用的。共享函数不具备这两个条件。

解决方案是创建一个您可以创建其实例的包装,然后使用该包装调用共享函数。

代码清单 13. 调用共享函数的包装

Imports System.IO
<ComClass(FileWrapper.ClassId, FileWrapper.InterfaceId, FileWrapper.EventsId)> _
Public Class FileWrapper
    Public Const ClassId As String = "1596574F-9EE1-4439-854B-DF503099CEAE"
    Public Const InterfaceId As String = "02F98DBC-9298-4E9D-A991-E618C1B1BC53"
    Public Const EventsId As String = "2286FD23-B22D-4D49-B2CE-F3CFEC5C1CA5"
    Public Sub New()
        MyBase.New()
    End Sub
    Public Function Exists(ByVal fileName As String) As Boolean
        Return File.Exists(fileName)
    End Function
End Class

由于 FileWrapper 类公开了默认构造函数,因此可以从 Visual Basic 6 创建该类。调用 Exists 函数时,它会调用共享的 File.Exists .NET 函数并返回结果。Visual Basic 6 调用 FileWrapper 的实例方法,而 FileWrapper 调用 .NET Framework File 类的共享方法。

在 Visual Basic 6 中,可以按如下方法使用该函数:

代码清单 14. Visual Basic 6 中使用 File.Exists

Private Sub Command5_Click() Dim fw As New NetFxWrapper.FileWrapper Label2 = fw.Exists("c:\platform.ini")End Sub

4.

包装不应使用重载函数

在 .NET Framework 中,您可以使用名称完全相同但参数不同的多个函数。请看以下代码:

代码清单 15. Visual Basic .NET 中的重载函数

Public Sub Save(ByVal fileName As String)
    _image.Save(fileName)
End Sub
Public Sub Save(ByVal fileName As String, 
    ByVal format As ImageFormatWrapper)
    Dim imageFormat As Imaging.ImageFormat
    Select Case format
        Case ImageFormatWrapper.Bmp
            imageFormat = Imaging.ImageFormat.Bmp
        Case ImageFormatWrapper.Emf
            imageFormat = Imaging.ImageFormat.Emf
        Case ImageFormatWrapper.Exif
            imageFormat = Imaging.ImageFormat.Exif
        Case ImageFormatWrapper.Gif
            imageFormat = Imaging.ImageFormat.Gif
        Case ImageFormatWrapper.Icon
            imageFormat = Imaging.ImageFormat.Icon
        Case ImageFormatWrapper.MemoryBmp
            imageFormat = Imaging.ImageFormat.MemoryBmp
        Case ImageFormatWrapper.Png
            imageFormat = Imaging.ImageFormat.Png
        Case ImageFormatWrapper.Tiff
            imageFormat = Imaging.ImageFormat.Tiff
        Case ImageFormatWrapper.Wmf
            imageFormat = Imaging.ImageFormat.Wmf
    End Select
    _image.Save(fileName, imageFormat)
End Sub

一个函数采用文件名作为参数,另一个函数还采用其他图形格式参数。这两个函数都被命名为 Save。从 Visual Basic .NET 调用这两个函数时,编译器可以根据传递的参数来确定调用哪一个函数。如果只传递一个参数,则调用第一个函数。如果传递两个参数,则调用第二个函数。

COM 不支持重载函数,因此如果此类是通过 COM interop 公开的,COM 包装必须为这些函数生成唯一的函数名称。对于 Visual Basic 6,它们显示为:

.

8. Visual Basic 6 调用重载函数

请注意,Save 函数被命名为 Save 和 Save_2。这样,您可以确定要从 Visual Basic 6 调用哪一个函数,但是名称不具有描述性。最好不在包装中使用重载,而改为给每个函数赋予唯一的名称:

代码清单 16. 函数的唯一名称

Public Sub Save(ByVal fileName As String)
    _image.Save(fileName)
End Sub
Public Sub SaveWithImageFormat(ByVal fileName As String, _
    ByVal format As ImageFormatWrapper)
    Dim imageFormat As Imaging.ImageFormat
    Select Case format
        Case ImageFormatWrapper.Bmp
            imageFormat = Imaging.ImageFormat.Bmp
        Case ImageFormatWrapper.Emf
            imageFormat = Imaging.ImageFormat.Emf
        Case ImageFormatWrapper.Exif
            imageFormat = Imaging.ImageFormat.Exif
        Case ImageFormatWrapper.Gif
            imageFormat = Imaging.ImageFormat.Gif
        Case ImageFormatWrapper.Icon
            imageFormat = Imaging.ImageFormat.Icon
        Case ImageFormatWrapper.MemoryBmp
            imageFormat = Imaging.ImageFormat.MemoryBmp
        Case ImageFormatWrapper.Png
            imageFormat = Imaging.ImageFormat.Png
        Case ImageFormatWrapper.Tiff
            imageFormat = Imaging.ImageFormat.Tiff
        Case ImageFormatWrapper.Wmf
            imageFormat = Imaging.ImageFormat.Wmf
    End Select
    _image.Save(fileName, imageFormat)
End Sub

现在,每个函数都有唯一的名称,可以在 Visual Basic 6 中更方便地使用了。

.

9. 具有唯一名称的函数

5.

包装应当放在全局程序集缓存中

当注册 COM 对象时,系统注册表包含 COM 对象 DLL 的文件路径。这样,当您的程序创建 COM 对象的实例时,操作系统可以找到该 DLL 并将其加载到内存中。

.NET 程序集的工作方式与之不同。.NET framework 需要程序集与使用它的可执行文件位于同一位置中,或者需要程序集位于称为“全局程序集缓存”(GAC) 的位置中。为了确保在运行时始终可以找到 .NET 包装类,应将它们放在 GAC 中。

将程序集放入 GAC 需要两个步骤。首先,必须对程序集进行签名。这可以通过如下方法完成:

1.

返回到 Visual Basic Express 中的 NetFxWrapper 工程。

2.

在解决方案资源管理器中,双击“我的工程”。此操作将打开工程属性页。

3.

单击“签名”选项卡。

4.

单击“为程序集签名”复选框。

5.

在“选择强名称密钥文件”下拉列表中,单击“<新建...>”。

6.

对于“密钥文件名称”,输入“MyKeyFile”。

7.

取消选中“使用密码保护密钥文件”复选框。

8.

单击“确定”。

9.

选择“生成”|“生成 NetFxWrapper”菜单命令。

这会向工程中添加一个密钥文件,每次编译该工程时,都用此密钥对生成的 DLL 进行签名。必须先对程序集进行签名,然后才能将它们放到全局程序集缓存中。

10.

导航到“开始”|“运行”。

11.

输入“cmd”,然后单击“确定”打开命令窗口。

12.

在命令窗口中,切换到包装类要编译到的目录。在我的计算机上,它是:C:\Documents and Settings\Administrator\My Documents\Visual Studio 2005\Projects\NetFxWrapper\NetFxWrapper\bin\Release

13.

输入“"C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil" -i NetFxWrapper.dll”。

注意 要特别注意指向 gacutil 的路径前后的引号。您应当看到一条消息,指出该程序集已成功添加到全局程序集缓存中。

在部署使用包装类的 Visual Basic 6 应用程序时,应用程序安装程序需要使用 gacutil 将该包装类安装到 GAC 中。

返回页首返回页首

选项比较

虽然本文将重点放在使用 Visual Basic Fusion 方法时的最佳实践上,但是现在需要花一点时间检查用于处理 Visual Basic 6 应用程序的所有选项,并确定 Visual Basic Fusion 或其他一些策略是否是特定 Visual Basic 6 应用程序的最佳选项。

这些选项包括将 Visual Basic 6 应用程序保持原样、将整个应用程序迁移到 .NET 中或使用 Visual Basic Fusion 技术。每个选项都是特定情况的相应解决方案。

保持原样

在此选项中,您选择只将以 Visual Basic 6 编写的应用程序保留为 Visual Basic 6,完全不使用 .NET framework。

优点:

简单:该应用程序是使用 Visual Basic 6 编写的(或迁移到 Visual Basic 6 的),因此最简单的选项是将应用程序保持原样。开发人员很可能已经了解这种语言和开发环境,可以对应用程序快速进行许多更改和错误修复。

缺点:

添加新功能:Visual Studio 6.0 是 1998 年发布的。从那时起,除了 Service Pack,Visual Basic 6 没有再进行其他增强。但是,如今对应用程序功能的期望已经发生了很大变化。通常,人们期望应用程序能够在新版本可用时自动更新、脱机工作、本地缓存数据、集成 Internet 功能、可与 Web 服务进行通信等等。虽然使用今天的技术能够轻松完成这些任务,但这些技术在 Visual Basic 6 中不可用,因此只使用 Visual Basic 6 进行这些增强可能需要大量工作。因为只使用 Visual Basic 6 进行增强成本很高且难度很大,最终结果是无法增强许多 Visual Basic 6 应用程序来包括此类新功能。

消失的功能:自从 2002 年发布 Visual Basic .NET 后,开发人员已经从 Visual Basic 6 迁移到 Visual Basic .NET。因此,新 Visual Basic 信息(书籍、文章、博客、新闻组公告等)中的绝大部分都是关于 Visual Basic .NET 的信息。同时,有关 Visual Basic 6 的可用信息量已经在下降。另外,许多开发人员认为转移到 Visual Basic .NET 会带来更多的职位机会,因为这种语言将不断更新和增强。这并不是暗示自本文发表之日起,就很难找到 Visual Basic 6 问题的在线技术帮助了,或很难招聘到 Visual Basic 6 开发人员了;但是随着时间推移,在可用信息和人才库方面,Visual Basic 6 都会步许多旧语言的后尘。

迁移到 Visual Basic .NET

此选项需要将 Visual Basic 6 应用程序完整迁移到 Visual Basic .NET。

优点:

对技术的访问:将应用程序迁移到 Visual Basic .NET 是确保能够快速集成创新功能和技术的最佳方法。Microsoft 和其他公司将工作重点主要放在 .NET Framework 的功能上。这意味着新 SDK 将侧重于 .NET 语言,或只适用于 .NET 语言。Web 服务、应用程序自动更新和 Internet 功能(http 和 ftp 支持)等新技术本来是为 .NET 应用程序提供的,不会一直向后迁移到 Visual Basic 6。像 GotDotNetSourceForge 等网站包含了成千上万个可在 .NET 应用程序中直接使用的可再分发组件以及源代码。

开发人员生产力:另外,Visual Studio 的新版本与 Visual Studio 6.0 相比,可以大大提高生产力,这些新版本只能与 .NET 应用程序一起使用。

缺点:

风险:将整个应用程序从 Visual Basic 6 迁移到 Visual Basic .NET 不是轻而易举的。如果应用程序非常重要,并且开发人员没有开发 Visual Basic .NET 的经验,就会存在迁移不成功的风险。

时间:迁移应用程序并使其在 .NET 中达到 Visual Basic 6 中的能力需要一定的时间。虽然这为应用程序的将来增强奠定了更好的基础,但是不能忽略迁移所需的时间和成本。

Visual Basic Fusion

Visual Basic Fusion 是在 Visual Basic 6 应用程序中使用 .NET 功能的一种方法。

优点:

对技术的访问:通过编写小 Visual Basic .NET 修补程序,您可以从 Visual Basic 6 应用程序中访问整个 .NET framework 类库、调用 Web 服务或者使用第三方或开放源 .NET 库。

低风险:大多数应用程序代码都保留为 Visual Basic 6,继续按原样工作。您编写的 Visual Basic .NET 代码量非常小。这意味着不存在迁移失败的风险,因为不需要迁移整个应用程序。另外,没有 Visual Basic .NET 开发经验的开发人员只需了解 .NET Framework 的小部分内容便可访问所需的功能。

高投资回报:与迁移整个应用程序相比,此方法的投资非常低,因此投资回报(尤其是短期回报)非常高。

缺点:

Visual Basic 6由于应用程序的大部分仍保留为 Visual Basic 6,当对应用程序进行操作时,您需要继续使用 Visual Basic 6 IDE 和 Visual Basic 6 语言。该语言和 IDE 不如 Visual Basic .NET 生产力高。

调试:若要有效调试使用 Visual Basic 6 和 Visual Basic .NET 代码的应用程序,您需要同时打开这两个开发环境,并且需要特殊知识才能在 Visual Basic 6 和 Visual Basic .NET 之间进行有效调试。

包装开发:要在 Visual Basic 6 中访问 .NET 功能,您需要编写 .NET 类的包装,以便将它们公开为可在 Visual Basic 6 中使用的 COM 对象。如果将整个应用程序迁移到 Visual Basic .NET,则不需要这些包装。

返回页首返回页首

使用示例代码

本文提供了对所有讨论的主题进行说明的示例代码。该示例代码将被提取到名为“最佳实践代码”的文件夹中。在此文件夹中,可以找到以下内容:

1.

Install.bat — 用于注册和安装 .NET 包装,以便可以在 Visual Basic 6 中使用这些包装。

2.

NetFxWrapper — 包含 Visual Basic .NET 包装类的源代码的文件夹。

3.

Best Practices Visual Basic 6 — 包含使用包装类的 Visual Basic 6 示例的文件夹。

4.

ComClass.zip — 包含 ComClass 工程项。如果此文件放在 C:\Documents and Settings\[User Name]\My Documents\Visual Studio 2005\Templates\ItemTemplates 文件夹中,此工程模板将可用于 Visual Basic Express 工程。

如果未安装 Visual Studio 2005 或 Visual Basic Express,只需双击 install.bat 即可注册包装类。随后您可以打开 Visual Basic 6 工程,运行它,并检查代码以查看它如何使用包装。

如果您安装了 Visual Studio 2005 或 Visual Basic Express,还可以打开包装类的源代码并检查它们的构造方式。

返回页首返回页首

结论

对于必须在现有基础上增强的 Visual Basic 6 应用程序而言,Visual Basic Fusion 是一个有用的方法。通过 Visual Basic Fusion,您无需重新编写应用程序,即可在现有应用程序中访问 .NET Framework 提供的任何功能。要使用 Visual Basic Fusion 方法,必须创建 Visual Basic .NET 包装类以访问 .NET Framework 功能。这些包装类通常很容易编写,但是必须遵循某些规则,以便它们将自身正确公开为 COM 对象。本文为您介绍了创建包装类的最佳实践,并针对现有 Visual Basic 6 应用程序应采用 Visual Basic Fusion 还是某些其他方法提供了指导性意见。

作者简介

Scott Swigart (http://www.swigartconsulting.com/) 负责为公司提供咨询,指导如何充分使用当今的技术和为明天做准备。在这一方面,Scott 为 Visual Basic Fusion 网站做出了值得骄傲的贡献,该网站为希望通过最省力的方式最大限度地利用 Visual Basic 的开发人员提供了实用信息和策略。Scott 还是 Microsoft MVP,并且是许多书籍和文章的合著者。如果您对本文有任何问题或评论,可以随时发送邮件至 scott@swigartconsulting.com

© 2007 Microsoft Corporation 版权所有。保留所有权利。使用规定。


返回页首返回页首