65.9K
CodeProject 正在变化。 阅读更多。
Home

Genesis 混合智能客户端框架 - 第 VII 部分

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.75/5 (10投票s)

2009 年 6 月 18 日

Ms-PL

16分钟阅读

viewsIcon

32753

downloadIcon

1709

这是 VII 部分系列文章的第七部分。本文将逐一分解每个项目的代码,介绍其功能。

最新更新

2009 年 7 月 23 日:我一直通过这些文章与使用该代码的开发人员保持沟通,并纠正了安装程序中的许多问题。我还将代码压缩并附加到本文中,并已上传到 Code Plex。

2009 年 7 月 22 日:我刚刚在 Code Plex 上发布了一个带有安装程序的新版本。今天晚些时候,我将更新本文附加的 zip 文件。安装程序可以更轻松地在您开始开发自己的托管应用程序之前设置和配置框架。请遵循发布页面上的说明。

如果您正在从本页面下载源代码,请参阅发行说明,了解有关编译和执行示例的说明。

引言 - 完整源代码

在过去的几篇文章中,我向您介绍了源代码的各个方面。本文将重点介绍实现重要功能的特定源代码。此时,您应该已经了解到该系统有多个组件。一个用于与数据库通信和提供客户端 API 的 Web 服务,一个用作在线文件存储库的 Web 应用程序,一个实现客户端 API 的 Windows 客户端应用程序,以及可能还有其他数据库和 Web 应用程序。您还应该了解客户端如何更新托管的应用程序。

Genesis 管理系统作为完整的托管应用程序和客户端 API 实现,旨在演示如何使用 Genesis 智能客户端框架开发富客户端应用程序。

本文是 VII 部分的第七部分。请访问第一部分查看索引。

有关 Genesis 智能客户端框架或我们任何新闻源的最新信息,请参阅我们的网站 www.bluemarble.co.za

为了积极推动将 Genesis 智能客户端框架的此版本作为开源产品发布,我们在 www.codeplex.com 上创建了一个配置文件,其中我们维护着源代码的最新副本。如果您想要 Genesis 智能客户端框架源代码的最新版本,请访问我们的Code Plex 配置文件从 Code Plex 下载最新版本

探索解决方案

Code Plex 上当前发布的代码包含Solutions文件夹中的三个解决方案文件。这三个解决方案是

  • BlueMarble.Genesis.Client

    此解决方案演示了如何使用 Genesis 智能客户端框架客户端 API 实现您自己的智能客户端应用程序。

  • 模板解决方案

    此解决方案演示了如何使用 Genesis 智能客户端框架客户端 API 实现您自己的托管应用程序。

  • Genesis 智能客户端框架

    此解决方案包含智能客户端应用程序的商业版本,该版本使用了第三方 Ribbon 控件。此解决方案使用 BlueMarble.Genesis.Client 智能客户端应用程序作为默认。

探索架构

Genesis 智能客户端框架采用多层架构,以支持智能客户端技术的大规模企业部署。框架本身(包括客户端 API)使用 C# 语言为 Microsoft .NET 3.5、SOAP Web 服务、SQL Server 2008、TSQL、ASP.NET Web Forms 和 Windows Forms 开发。其目标是实现一个易于使用的框架,使我们能够专注于快速应用程序开发,而无需开发者担心每个新项目的基本内容。我们的框架实现了以下智能客户端概念:

我们的框架实现了以下智能客户端概念:

  • 自动更新/修复

    我们的客户端 API 允许智能客户端应用程序确定何时未使用最新版本的源代码。这使得应用程序可以自行更新,以确保用户始终使用的是最新版本。

  • 高级通信

    通过实现我们的客户端 API 并遵循我们的指南开发应用程序,框架能够促进托管应用程序与服务器之间的高级 SOAP 通信。

  • 安全

    我们的框架处理用户安全问题,开发人员无需担心从其代码中确认用户访问权限,所有访问权限都由安全系统动态处理。操作员可以为选定的用户授予对某些代码功能的临时访问权限。

  • 富客户端性

    通过我们的 Super Browser 组件将 Web Forms 与 Windows Forms 集成,用户可以在使用网站的同时,在托管应用程序内部执行本地代码。超链接可以启动本地 Windows Forms 对话框,允许用户编辑记录。更新后,网页将自动刷新。

  • 控制与一致性

    通过允许操作员控制用户界面的所有方面,从而控制用户体验,良好的治理将带来一致的用户体验。

后端

Genesis 智能客户端框架的服务器端包含几个项目,包括一个 Web 服务项目、一个 Web 应用程序和一个数据库。此外还有一些通用的共享库。

Genesis.WebServices

Genesis.WebServices 项目是一个 ASP.NET Web 服务项目。它包含实现 API 的标准 Web 服务。这些 Web 服务由 Genesis.Client.Common 库实现,以构成 Genesis 智能客户端框架客户端 API。

理论上,任何使用任何开发平台/技术的应用程序都可以由 Genesis 智能客户端框架进行分发和管理。如果您可以开发自己的库来实现此项目中的 Web 服务,那么您就开发了自己的 Genesis 智能客户端框架客户端 API 移植版本。然后,您可以使用您选择的语言(或平台)开发实现您的移植版本的智能客户端应用程序。

异常

Exception Web Service 处理在智能客户端应用程序执行托管应用程序时发生的登录异常,并将这些异常记录到一个中央数据库,以便开发人员和系统操作员可以访问关键信息。以下方法可用:

  • public void LogException(System.Xml.XmlNode Exception) 

FileManager

FileManager Web 服务处理 Genesis 文件系统中的文件。FileManager Web 服务允许部分文件上传,以应对慢速网络连接或允许智能客户端应用程序支持断开连接的上传。以下方法可用:

  • public Guid UploadFile
    	(string FileName, string FileType, int FileSize, Guid UserGuid)

    此方法允许客户端创建文件上传会话。所需参数为文件名、文件类型、文件大小以及上传文件的用户的 User Guid。此方法返回一个用于部分上传的 Guid。

  • public void UploadFilePart(Guid DocumentGuid, int FilePartNumber, byte[] FilePart)

    此方法上传给定文件上传会话的文件部分。所需参数为文件上传会话 Guid(DocumentGuid)、文件在部分集合中的位置以及包含实际文件部分的字节数组。

  • public void JoinFileParts(Guid DocumentGuid)

    一旦给定文件的所有文件部分都已上传,就可以在服务器上将这些文件部分合并。这只是对构成文件部分的字节数组集合进行端到端绑定。

  • public void DeleteTemporaryFolder(Guid DocumentGuid)

    文件合并后,完整的文件将可供其他用户访问。此方法删除服务器上特定文件的单个文件部分。

  • public int GetArraySize()

    服务器可以确定单个文件部分的字节数组大小。智能客户端应用程序可以向服务器请求文件部分的建议大小。

  • protected string SetFilePath(Guid DocumentGuid)

    此方法返回特定文档的本地服务器路径。

  • protected string SetUrlPath(Guid DocumentGuid)

    此方法返回特定文档的在线服务器 URL。

  • protected string GetFileType(Guid DocumentGuid)

    此方法查询 Genesis 文件系统中文件的类型。

Genesis

Genesis Web Service 处理数据库上的动态查询。以下方法可用:

  • public System.Data.DataTable ExecuteTable(Guid TransactionGuid, 
    	string CommandText, string ConnectionStringKey, 
    	System.Data.CommandType CommandType, string TableName, 
    	params Common.Classes.DataParameter[] Parameters)

    此方法在 SQL 命令上执行 ExecuteDataset 方法。第一个表被提取到 DataTable 中,该 DataTable 是此方法的返回值。所需参数为 TransactionGuid (未实现)、SQL 命令文本、配置文件中连接字符串的名称、要从 Dataset 中提取的表的名称以及参数数组。

  • public object ExecuteScalar(Guid TransactionGuid, string CommandText, 
    	string ConnectionStringKey, System.Data.CommandType CommandType, 
    	string TableName, params Common.Classes.DataParameter[] Parameters)

    此方法在 SQL 命令上执行 ExecuteScalar 方法。所需参数为 TransactionGuid (未实现)、SQL 命令文本、配置文件中连接字符串的名称、要从 Dataset 中提取的表的名称以及参数数组。

  • public void ExecuteNonQuery(Guid TransactionGuid, string CommandText, 
    	string ConnectionStringKey, System.Data.CommandType CommandType, 
    	string TableName, params Common.Classes.DataParameter[] Parameters)

    此方法在 SQL 命令上执行 ExecuteNonQuery 方法。所需参数为 TransactionGuid (未实现)、SQL 命令文本、配置文件中连接字符串的名称、要从 Dataset 中提取的表的名称以及参数数组。

KeepAlive

KeepAlive Web 服务负责保持与服务器的连接活跃,以确保可靠的网络速度。它还可以作为智能客户端应用程序检测何时进入离线模式的测试。以下方法可用:

  • public string Ping()

    此方法仅从服务器返回当前时间。

  • public System.Xml.XmlNode Test(System.Xml.XmlNode TestNode)

    此方法允许智能客户端应用程序将诊断信息通过 XML 数据包传递给服务器。该数据包可以包含来自客户端的信息,例如测试开始时间,以及服务器上的测试要求,例如 Ping 测试。不同的测试可以执行不同的服务器操作。每个服务器操作都会更新返回给客户端的 XML 数据包,用于本地诊断服务器访问时间、吞吐量等。

查找

Lookup Web Service 提供了一个通用的查找数据库表接口。以下方法可用:

  • public DataTable GetLookupValues
        (string TableName, string ValueColumnName, string DisplayColumnName)

    此方法返回一个 datatable,其中包含来自自定义表的查找值。

  • public DataTable GetLookupValuesUsingConnection(string TableName, 
        string ValueColumnName, string DisplayColumnName, string ConnectionStringKey)

    此方法使用不同的数据库连接返回一个 datatable,其中包含来自自定义表的查找值。

模块

Module Web Service 处理应用程序、文件、命令和用户界面元数据。以下方法可用:

  • public DataTable GetApplicationRibbons(Guid SessionGuid)

    此方法返回所有顶级功能区(ribbons)的列表。所需参数为活动用户 SessionGuid

  • public DataTable GetRibbonBars(Guid SessionGuid, Guid RibbonGuid)

    此方法返回特定功能区(ribbon)的所有功能区栏(ribbon bars)的列表。所需参数为活动用户 SessionGuid 和功能区 Guid。

  • public DataTable GetBarItems
        (Guid SessionGuid, Guid RibbonBarGuid, Guid ParentBarItemGuid)

    此方法返回特定功能区栏(ribbon bar)的所有栏项目(bar items)的列表。所需参数为活动用户 SessionGuidRibbonBarGuid 和父栏项目 Guid(用于分层栏项目)。

  • public DataTable GetApplicationFiles(Guid SessionGuid, Guid ApplicationGuid)

    此方法返回特定托管应用程序所需的所有文件的列表。所需参数为活动用户 SessionGuid ApplicationGuid

  • public DataTable GetApplicationCommands(Guid SessionGuid, Guid FileGuid)

    此方法返回特定文件的所有命令列表。所需参数为活动用户 SessionGuid FileGuid

  • public DataTable ApplicationGetList()

    此方法返回所有托管应用程序的列表。

  • public DataTable ApplicationGetByApplicationGuid(Guid ApplicationGuid)

    此方法返回一个特定的托管应用程序。所需参数为 ApplicationGuid

  • public bool ApplicationUpdate(int ApplicationId, Guid ApplicationGuid, 
        string ApplicationName, string ApplicationDescription, int Order, bool Visible)

    此应用程序更新服务器上的托管应用程序记录。所需参数为要更新记录的 ApplicationIdApplicationGuidApplicationNameApplicationDescription、应用程序顺序和可见性。

  • public int ApplicationInsert(Guid ApplicationGuid, string ApplicationName, 
        string ApplicationDescription, int Order, bool Visible)

    此应用程序在服务器上创建新的托管应用程序记录。所需参数为 ApplicationGuidApplicationNameApplicationDescription、应用程序顺序和可见性。

  • public DataTable FileGetList()

    此方法返回托管应用程序的所有文件列表。

  • public DataTable FileGetByFileGuid(Guid FileGuid)

    此方法返回一个特定的文件。所需参数为 FileGuid

  • public DataTable FileGetByFileTypeId(int FileTypeId)

    此方法返回所有特定类型文件的列表。所需参数为 FileTypeId

  • public bool FileUpdate(int FileId, Guid FileGuid, Guid ApplicationGuid, 
        string FileName, string FileDescription, string FilePath, string FileUrl, 
        int FileTypeId, int VersionMajor, int VersionMinor, int VersionBuild, 
        int VersionRevision, int Order)

    此方法更新服务器上的文件记录。所需参数为 FileIdFileGuidApplicationGuidFileNameFileDescriptionFilePathFileUrlFileTypeIdVersion 和文件顺序。

  • public int FileInsert(Guid FileGuid, Guid ApplicationGuid, string FileName, 
        string FileDescription, string FilePath, string FileUrl, int FileTypeId, 
        int VersionMajor, int VersionMinor, int VersionBuild, int VersionRevision, 
        int Order)

    此方法在服务器上创建新的文件记录。所需参数为 FileGuidApplicationGuidFileNameFileDescriptionFilePathFileUrlFileTypeIdVersion 和文件顺序。

  • public DataTable CommandGetList()

    此方法返回所有命令的列表。

  • public DataTable CommandGetListWithNullRecord()

    此方法返回所有命令的列表,包括一个带有 NULL 引用的记录。当允许用户从列表中选择命令,但用户可以选择不选择任何命令作为有效选项时,使用此记录。

  • public DataTable CommandGetByCommandGuid(Guid CommandGuid)

    此方法返回一个特定的命令。所需参数为 CommandGuid

  • public bool CommandUpdate(int CommandId, Guid CommandGuid, Guid FileGuid, 
        string CommandName, string CommandDescription, string CommandCode, 
        string CommandType)

    此方法更新服务器上的命令记录。所需参数为 CommandIdCommandGuidFileGuidCommandNameCommandDescriptionCommandCode CommandType

  • public int CommandInsert(Guid CommandGuid, Guid FileGuid, string CommandName, 
        string CommandDescription, string CommandCode, string CommandType)

    此方法在服务器上创建新的命令记录。所需参数为 CommandGuidFileGuidCommandNameCommandDescriptionCommandCode CommandType

  • public DataTable RibbonGetList()

    此方法返回所有功能区(ribbons)的列表。

  • public DataTable RibbonGetByRibbonGuid(Guid RibbonGuid)

    此方法返回一个特定的功能区(ribbon)。所需参数为 RibbonGuid

  • public bool RibbonUpdate(int RibbonId, Guid RibbonGuid, Guid ApplicationGuid, 
        string RibbonName, int Order)

    此方法更新服务器上的功能区(ribbon)记录。所需参数为 RibbonIdRibbonGuidApplicationGuidRibbonName 和功能区的 Order

  • public int RibbonInsert(Guid RibbonGuid, Guid ApplicationGuid, 
        string RibbonName, int Order)

    此方法在服务器上创建新的功能区(ribbon)记录。所需参数为 RibbonGuidApplicationGuidRibbonName 和功能区的 Order

  • public DataTable RibbonBarGetList()

    此方法返回所有功能区栏(ribbon bars)的列表。

  • public DataTable RibbonBarGetByRibbonBarGuid(Guid RibbonBarGuid)

    此方法返回一个特定的功能区栏(ribbon bar)。所需参数为 RibbonBarGuid

  • public bool RibbonBarUpdate(int RibbonBarId, Guid RibbonBarGuid, 
        Guid RibbonGuid, string RibbonBarName, int Order)

    此方法更新服务器上的功能区栏(ribbon bar)记录。所需参数为 RibbonBarIdRibbonBarGuidRibbonGuidRibbonBarName 和功能区栏的 Order

  • public int RibbonBarInsert(Guid RibbonBarGuid, Guid RibbonGuid, 
        string RibbonBarName, int Order)

    此方法在服务器上创建新的功能区栏(ribbon bar)记录。所需参数为 RibbonBarGuidRibbonGuidRibbonBarName 和功能区栏的 Order

  • public DataTable BarItemGetList()

    此方法返回所有栏项目(bar items)的列表。

  • public DataTable BarItemGetListWithNullRecord()

    此方法返回所有栏项目(bar items)的列表,包括一个带有 NULL 引用的记录。当允许用户从列表中选择栏项目(bar item)但用户可以选择不选择任何栏项目(bar item)作为有效选项时,使用此记录。

  • public DataTable BarItemGetByBarItemGuid(Guid BarItemGuid)

    此方法返回一个特定的栏项目(bar item)。所需参数为 BarItemGuid

  • public bool BarItemUpdate(int BarItemId, Guid BarItemGuid, Guid RibbonBarGuid, 
        Guid ParentBarItemGuid, Guid CommandGuid, string BarItemName, 
        string BarItemImage, int BarItemImageSize, int BarItemTypeId, int Order)

    此方法更新服务器上的栏项目(bar item)记录。所需参数为 BarItemIdBarItemGuidRibbonBarGuidParentBarItemGuidCommandGuidBarItemNameBarItemImageBarItemImageSizeBarItemTypeId 和栏项目的 Order

  • public int BarItemInsert(Guid BarItemGuid, Guid RibbonBarGuid, 
        Guid ParentBarItemGuid, Guid CommandGuid, string BarItemName, 
        string BarItemImage, int BarItemImageSize, int BarItemTypeId, int Order) 

    此方法在服务器上创建新的栏项目(bar item)记录。所需参数为 BarItemGuidRibbonBarGuidParentBarItemGuidCommandGuidBarItemNameBarItemImageBarItemImageSizeBarItemTypeId 和栏项目的 Order

安全

Security Web 服务处理用户身份验证和模块访问。以下方法可用:

  • public Guid AuthorizeUser(Guid ApplicationGuid, string Username, string Password)
  • public Guid CreateTransaction(string TransactionCode, Guid SessionGuid)
  • public void CompleteTransaction(Guid TransactionGuid)
  • public DataTable RoleGetList()
  • public DataTable RoleGetByRoleGuid(Guid RoleGuid)
  • public DataTable RoleGetByUserGuid(Guid UserGuid)
  • public DataTable RoleGetByApplicationGuid(Guid ApplicationGuid)
  • public DataTable RoleGetByCommandGuid(Guid CommandGuid)
  • public DataTable RoleGetByRibbonGuid(Guid RibbonGuid)
  • public DataTable RoleGetByRibbonBarGuid(Guid RibbonBarGuid)
  • public bool RoleUpdate
    	(int RoleId, Guid RoleGuid, string RoleName, string RoleDescription)
  • public int RoleInsert(Guid RoleGuid, string RoleName, string RoleDescription)
  • public DataTable UserGetList()
  • public DataTable UserGetByUserGuid(Guid UserGuid)
  • public bool UserUpdate(int UserId, Guid UserGuid, string UserName, 
    	string Password, string Email, bool Active, string StartupScript)
  • public int UserInsert(Guid UserGuid, string UserName, string Password, 
    	string Email, bool Active, string StartupScript)
  • public DataTable UserRoleGetList()
  • public int UserRoleInsert(Guid UserGuid, Guid RoleGuid)
  • public int UserRoleDelete(Guid UserGuid, Guid RoleGuid)
  • public DataTable ApplicationRoleGetList()
  • public int ApplicationRoleInsert(Guid ApplicationGuid, Guid RoleGuid)
  • public int ApplicationRoleDelete(Guid ApplicationGuid, Guid RoleGuid)
  • public DataTable CommandRoleGetList()
  • public int CommandRoleInsert(Guid CommandGuid, Guid RoleGuid)
  • public int CommandRoleDelete(Guid CommandGuid, Guid RoleGuid)
  • public DataTable RibbonRoleGetList()
  • public int RibbonRoleInsert(Guid RibbonGuid, Guid RoleGuid)
  • public int RibbonRoleDelete(Guid RibbonGuid, Guid RoleGuid)
  • public DataTable RibbonBarRoleGetList()
  • public int RibbonBarRoleInsert(Guid RibbonBarGuid, Guid RoleGuid)
  • public int RibbonBarRoleDelete(Guid RibbonBarGuid, Guid RoleGuid)

Genesis.FileHost

Genesis.FileHost 充当 Genesis 文件系统,向智能客户端应用程序公开所需的应用程序文件,并作为智能客户端应用程序创建的文件的上传存储库。此功能很重要,因为它允许从另一个智能客户端应用程序即时访问文件。

文件主机上还有几个功能性网页。它们是:

数据库/文件系统同步

通过在浏览器中打开 /update.aspx 文件,系统将同步数据库和文件系统。将生成一个报告,说明更新的成功情况,包括新/更新的命令和版本号。

数据库备份

通过在浏览器中打开 /deployment/database/backup.aspx 文件并提供必需的参数,系统将备份指定的数据库并将其发布到 Genesis 文件系统中。

在线部署

通过在浏览器中打开 /Deployment/default.aspx 文件,您将能够将部署包上传到服务器。

Web.Config

web.config 文件中包含一些重要的键。

<appsettings>
	<add key="LocalPath" value=".\"/>
	<add key="WebPath" value="https://:1581/Genesis.FileHost/"/>
	<add key="DevelopmentPath" value="..\..\"/>
	<add key="TempPath" value="..\..\Temp\FileHost\"/>
	<add key="BackupPath" value="..\..\Databases\Backup\"/>
</appsettings>
<connectionstrings>
	<add name="GenesisConnectionString" 
		connectionString="Server=VSQL01\SQL01;
		Initial Catalog=BlueMarble.Genesis.Dev;Integrated Security=SSPI;"/>
</connectionstrings>

数据库

有两个数据库项目。一个包含 TSQL 存储过程,另一个包含 CLR 存储过程。CLR 存储过程由身份验证系统使用,TSQL 存储过程在 Web 服务中实现,并构成了 API 的一部分。

客户端 API

客户端 API 是为 Microsoft .NET 3.5 实现的 Genesis.WebServices 项目中的 SOAP Web 服务。它包含几个项目,所有这些项目都具有基类和接口,以简化开发周期。

Genesis.Client.Common

Genesis.Client.Common 类库实现了最常用的 Genesis API。它实现了 ExceptionFileManagerGenesisKeepAlive Lookup Web 服务的 SOAP 客户端。它还包含一些用于对话框和窗体的基类。此类库是使用 C# 为 Microsoft .NET 3.5 开发的。

Genesis.Client.Module

Genesis.Client.Module 类库实现了 Genesis Module API。它实现了 Module Web 服务的 SOAP 客户端。此类库是使用 C# 为 Microsoft .NET 3.5 开发的。

Genesis.Client.Security

Genesis.Client.Security 类库实现了 Genesis Security API。它实现了 Security Web 服务的 SOAP 客户端。此类库是使用 C# 为 Microsoft .NET 3.5 开发的。

Genesis.Client.Host

Genesis.Client.Host 类库实现了 Genesis Host API。它包含所有智能客户端应用程序所需的接口和默认窗体。

智能客户端应用程序

智能客户端应用程序实现了 Genesis 智能客户端框架客户端 API。它充当 Genesis 智能客户端框架中托管应用程序的主机。在此源代码版本中,有两个不同的智能客户端应用程序可用。

Genesis.Host

Genesis.Host Windows 应用程序作为应用程序的主机。它实现了 Genesis 智能客户端框架客户端 API,并支持用户身份验证和应用程序登录。它可以下载所需的应用程序更新,并显示应用程序的用户界面组件。

Genesis.Host Smart 客户端应用程序依赖于 Genesis.Client.HostFormLibrary 类库来提供其用户界面组件。它还依赖于第三方 Ribbon 控件。

Genesis.Client.HostFormLibrary

Genesis.Client.HostFormLibrary 包含一些用户界面元素,用于 Genesis.Host 智能客户端应用程序使用的第三方 Ribbon 控件。

其他信息

Blue Marble 自豪地成为 Microsoft BizSpark 初创公司。

免责声明

Genesis 智能客户端框架是一个商业闭源应用程序。它在 Code Project 上提供,并享有 Code Project 文章赋予用户的各项权益(即免费和公平使用)。但是,必须注意,某些模块包含我们无法通过 Code Project 获得许可的第三方控件。所有文章上传完毕后,代码将被提取到一个单独的混淆库中,以保护我们的供应商的知识产权。该库将提供完整的源代码,但不包含可能泄露我们许可证的几行代码。此外,还将为希望使用完全免费版本的开发人员提供替代方案。

免责声明更新

已创建标准 Microsoft .NET 控件用户界面的实现,并从 Code Plex 上的 1.30.1024.0 版本开始提供。此版本符合所有 Code Project 文章发布条款和条件。

更新历史

2009 年 7 月 23 日

  • 添加了 zip 格式的源代码,以补充 MSI 安装程序。
  • 解决了安装程序中的一些问题,特别是与 Windows XP 安装 IIS 5 相关的问题。

2009 年 7 月 22 日

  • 更新了指向 Code Plex 上最新版本的链接。
  • Code Plex 版本现在包含在 MSI 安装项目中,并正确安装数据库和 Web 组件。它还将一个项目模板安装到 Visual Studio 中。
  • 待办事项:Code Plex 上的版本目前仅为安装程序,我正在忙于构建仅源代码的 ZIP 文件,以便发布到 Code Project(本文)和 Code Plex。

2009 年 6 月 22 日

  • 已向本文档添加更新历史记录部分。
  • 添加了每个方法的简短描述(不完整)
© . All rights reserved.