Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (中文) » SQL Anywhere 服务器 - 编程 » 部署 SQL Anywhere » 部署数据库和应用程序 » 部署客户端应用程序 » 部署 OLE DB 和 ADO 客户端

 

自定义 OLE DB 提供程序

安装 OLE DB 提供程序时,必须修改 Windows 注册表。通常,使用内置于 OLE DB 提供程序的自行注册功能进行修改。例如,可以使用 Windows regsvr32 工具来进行此操作。注册表条目的标准集由提供程序创建。

在典型的连接字符串中,提供程序的属性是组成部分之一。要指示将使用的 SQL Anywhere OLE DB 提供程序,需要指定提供程序的名称。下面是 Visual Basic 示例:

connectString = "Provider=SAOLEDB;DSN=SQL Anywhere 11 Demo"

对于 ADO 和/或 OLE DB,有许多通过名称引用提供程序的其它方法。下面是一个 C++ 示例,其中不仅指定了提供程序名称而且还指定了要使用的版本。

hr = db.Open(_T("SAOLEDB.11"), &dbinit);

提供程序名称在注册表中查找。如果查看您的计算机系统上的注册表,您会在 HKEY_CLASSES_ROOT 中会找到 SAOLEDB 条目。

[HKEY_CLASSES_ROOT\SAOLEDB]
@="SQL Anywhere OLE DB Provider"

此条目有两个子项,分别包含此提供程序的类标识符 (ClsId) 以及当前版本 (CurVer)。下面是一个示例:

[HKEY_CLASSES_ROOT\SAOLEDB\Clsid]
@="{41dfe9f3-db91-11d2-8c43-006008d26a6f}"

[HKEY_CLASSES_ROOT\SAOLEDB\CurVer]
@="SAOLEDB.11"

还有若干更类似的条目。它们用于标识 OLE DB 提供程序的特定实例。如果在注册表的 HKEY_CLASSES_ROOT\CLSID 下查找 ClsId 并且查看子项,您将看到其中一个条目标识了提供程序 DLL 的位置。

[HKEY_CLASSES_ROOT\CLSID\
{41dfe9f3-db91-11d2-8c43-006008d26a6f}\
InprocServer32]

@="c:\\sa11\\bin64\\dboledb11.dll"
"ThreadingModel"="Both"

此处问题是结构非常单一。如果将 SQL Anywhere 软件从您的系统卸载,OLE DB 提供程序注册表条目将从注册表删除,随后提供程序 DLL 将从硬盘驱动器删除。任何依赖提供程序的应用程序将不再工作。

同样,如果来自不同供应商的应用程序都使用相同的 OLE DB 提供程序,则每次安装相同的提供程序时都将覆盖公用注册表设置。您希望应用程序使用的提供程序版本将由另一较新(或较旧!)的提供程序版本代替。

这种情况所引发的不稳定性无疑是不希望发生的。为解决此问题,可以自定义 SQL Anywhere OLE DB 提供程序。

在下面的练习中,您可以生成一组唯一的 GUID,选择唯一的提供程序名称和唯一的 DLL 名称。这三项操作有助于创建可与您的应用程序一起部署的唯一的 OLE DB 提供程序。

下面是创建自定义版本 OLE DB 提供程序所涉及的步骤。

♦  自定义 OLE DB 提供程序
  1. 制作下面所示的示例注册文件的副本。由于注册文件过长,因此将在这些步骤之后列出。文件名应当带有 .reg 后缀。注册表值的名称区分大小写。

  2. 使用 Microsoft Visual Studio uuidgen 实用程序创建 4 个有顺序的 UUID (GUID)。

    uuidgen -n4 -s -x >oledbguids.txt
  3. 按以下顺序指派 4 个 UUID 或 GUID:

    1. 提供程序类 ID(下面的 GUID1)。

    2. 枚举类 ID(下面的 GUID2)。

    3. ErrorLookup 类 ID(下面的 GUID3)。

    4. 提供程序帮助类 ID(下面的 GUID4)。此最后一个 GUID 不在 Windows Mobile 部署中使用。

    上述四项之间存在先后顺序(这就是在 uuidgen 命令行中 -x 所起的作用),这一点很重要。每个 GUID 都应出现与以下类似的内容。

    名称 GUID
    GUID1 41dfe9f3-db92-11d2-8c43-006008d26a6f
    GUID2 41dfe9f4-db92-11d2-8c43-006008d26a6f
    GUID3 41dfe9f5-db92-11d2-8c43-006008d26a6f
    GUID4 41dfe9f6-db92-11d2-8c43-006008d26a6f

    请注意,递增的只是 GUID 的第一部分(例如,41dfe9f3)。

  4. 使用编辑器的 [查找/替换] 功能将文本中所有 GUID1、GUID2、GUID3 和 GUID4 更改为相应的 GUID(例如,如果 41dfe9f3-db92-11d2-8c43-006008d26a6f 是由 uuidgen 生成的 GUID,则 GUID1 将用其替换)。

  5. 确定提供程序名称。这是可以在您的应用程序的连接字符串中使用的名称(例如,Provider=SQLAny)。请不要使用以下任何名称。这些名称由 SQL Anywhere 使用。

    版本 10 或更高版本 版本 9 或更早版本
    SAOLEDB ASAProv
    SAErrorLookup ASAErrorLookup
    SAEnum ASAEnum
    SAOLEDBA ASAProvA
  6. 使用编辑器的 [查找/替换] 功能将所有出现的字符串 SQLAny 更改为您所选择的提供程序名称。其中包括所有那些 SQLAny 可能为较长字符串(例如,SQLAnyEnum)的子串的位置。

    假定您选择 Acme 作为提供程序名称。将出现在 HKEY_CLASSES_ROOT 注册表配置单元中的名称以及供比较的 SQL Anywhere 名称如下表所示。

    SQL Anywhere 提供程序 您自定义的提供程序
    SAOLEDB Acme
    SAErrorLookup AcmeErrorLookup
    SAEnum AcmeEnum
    SAOLEDBA AcmeA
  7. 以不同名称制作 SQL Anywhere 提供程序 DLL(dboledb11.dlldboledba11.dll)的副本。请注意,没有用于 Windows Mobile 的 dboledba11.dll

    copy dboledb11.dll myoledb11.dll
    copy dboledba11.dll myoledba11.dll

    特殊注册表项将由脚本基于您所选择的 DLL 名称创建。此名称应不同于标准的 DLL 名称(例如 dboledb11.dlldboledba11.dll),这一点非常重要。如果您将提供程序 DLL 命名为 myoledb11,则提供程序将在 HKEY_CLASSES_ROOT 中查找具有相同名称的注册表条目。上述情况同样适用于提供程序模式辅助 DLL。如果您将 DLL 命名为 myoledba11,则提供程序将在 HKEY_CLASSES_ROOT 中查找具有相同名称的注册表条目。您选择的名称是唯一的并且不可能被任何其他人选择,这一点非常重要。下面是一些示例。

    所选的 DLL 名称 相应的 HKEY_CLASSES_ROOT\名称
    myoledb11.dll HKEY_CLASSES_ROOT\myoledb11
    myoledba11.dll HKEY_CLASSES_ROOT\myoledba11
    acmeOledb.dll HKEY_CLASSES_ROOT\acmeOledb
    acmeOledba.dll HKEY_CLASSES_ROOT\acmeOledba
    SAcustom.dll HKEY_CLASSES_ROOT\SAcustom
    SAcustomA.dll HKEY_CLASSES_ROOT\SAcustomA
  8. 使用编辑器的 [查找/替换] 功能将所有在注册表脚本中出现的 myoledb11myoledba11 更改为您所选择的两个 DLL 名称。

  9. 使用编辑器的 [查找/替换] 功能将所有在注册表脚本中出现的 d:\\mypath\\bin32\\ 更改为 DLL 的安装位置。请务必使用一对斜线来表示单个斜线。此步骤必须在应用程序安装时自定义。

  10. 将注册表脚本保存到磁盘并且运行它。

  11. 尝试运行新的提供程序。切勿忘记将 ADO/OLE DB 应用程序更改为使用新的提供程序名称。

下面列出了将要修改的注册表脚本。

REGEDIT4
; Special registry entries for a private OLE DB provider.

[HKEY_CLASSES_ROOT\myoledb11]
@="Custom SQL Anywhere OLE DB Provider 11.0"

[HKEY_CLASSES_ROOT\myoledb11\Clsid]
@="{GUID1}"

; Data1 of the following GUID must be 3 greater than the
; previous, for example, 41dfe9f3 + 3 => 41dfe9ee.

[HKEY_CLASSES_ROOT\myoledba11]
@="Custom SQL Anywhere OLE DB Provider 11.0"

[HKEY_CLASSES_ROOT\myoledba11\Clsid]
@="{GUID4}" 

; Current version (or version independent prog ID)
; entries (what you get when you have "SQLAny"
; instead of "SQLAny.11")

[HKEY_CLASSES_ROOT\SQLAny]
@="SQL Anywhere OLE DB Provider"

[HKEY_CLASSES_ROOT\SQLAny\Clsid]
@="{GUID1}"

[HKEY_CLASSES_ROOT\SQLAny\CurVer]
@="SQLAny.11"

[HKEY_CLASSES_ROOT\SQLAnyEnum]
@="SQL Anywhere OLE DB Provider Enumerator"

[HKEY_CLASSES_ROOT\SQLAnyEnum\Clsid]
@="{GUID2}"

[HKEY_CLASSES_ROOT\SQLAnyEnum\CurVer]
@="SQLAnyEnum.11"

[HKEY_CLASSES_ROOT\SQLAnyErrorLookup]
@="SQL Anywhere OLE DB Provider Extended Error Support"

[HKEY_CLASSES_ROOT\SQLAnyErrorLookup\Clsid]
@="{GUID3}"

[HKEY_CLASSES_ROOT\SQLAnyErrorLookup\CurVer]
@="SQLAnyErrorLookup.11"

[HKEY_CLASSES_ROOT\SQLAnyA]
@="SQL Anywhere OLE DB Provider Assist"

[HKEY_CLASSES_ROOT\SQLAnyA\Clsid]
@="{GUID4}"

[HKEY_CLASSES_ROOT\SQLAnyA\CurVer]
@="SQLAnyA.11" 

; Standard entries (Provider=SQLAny.11)

[HKEY_CLASSES_ROOT\SQLAny.11]
@="Sybase SQL Anywhere OLE DB Provider 11.0"

[HKEY_CLASSES_ROOT\SQLAny.11\Clsid]
@="{GUID1}"

[HKEY_CLASSES_ROOT\SQLAnyEnum.11]
@="Sybase SQL Anywhere OLE DB Provider Enumerator 11.0"

[HKEY_CLASSES_ROOT\SQLAnyEnum.11\Clsid]
@="{GUID2}"

[HKEY_CLASSES_ROOT\SQLAnyErrorLookup.11]
@="Sybase SQL Anywhere OLE DB Provider Extended Error Support 11.0"

[HKEY_CLASSES_ROOT\SQLAnyErrorLookup.11\Clsid]
@="{GUID3}"

[HKEY_CLASSES_ROOT\SQLAnyA.11]
@="Sybase SQL Anywhere OLE DB Provider Assist 11.0"

[HKEY_CLASSES_ROOT\SQLAnyA.11\Clsid]
@="{GUID4}" 

; SQLAny (Provider=SQLAny.11)

[HKEY_CLASSES_ROOT\CLSID\{GUID1}]
@="SQLAny.11"
"OLEDB_SERVICES"=dword:ffffffff

[HKEY_CLASSES_ROOT\CLSID\{GUID1}\ExtendedErrors]
@="Extended Error Service"

[HKEY_CLASSES_ROOT\CLSID\{GUID1}\ExtendedErrors\{GUID3}]
@="Sybase SQL Anywhere OLE DB Provider Error Lookup"

[HKEY_CLASSES_ROOT\CLSID\{GUID1}\InprocServer32]
@="d:\\mypath\\bin32\\myoledb11.dll"
"ThreadingModel"="Both"

[HKEY_CLASSES_ROOT\CLSID\{GUID1}\OLE DB Provider]
@="Sybase SQL Anywhere OLE DB Provider 11.0"

[HKEY_CLASSES_ROOT\CLSID\{GUID1}\ProgID]
@="SQLAny.11"

[HKEY_CLASSES_ROOT\CLSID\{GUID1}\VersionIndependentProgID]
@="SQLAny" 

; SQLAnyErrorLookup

[HKEY_CLASSES_ROOT\CLSID\{GUID3}]
@="Sybase SQL Anywhere OLE DB Provider Error Lookup 11.0"
@="SQLAnyErrorLookup.11"

[HKEY_CLASSES_ROOT\CLSID\{GUID3}\InprocServer32]
@="d:\\mypath\\bin32\\myoledb11.dll"
"ThreadingModel"="Both"

[HKEY_CLASSES_ROOT\CLSID\{GUID3}\ProgID]
@="SQLAnyErrorLookup.11"

[HKEY_CLASSES_ROOT\CLSID\{GUID3}\VersionIndependentProgID]
@="SQLAnyErrorLookup" 

; SQLAnyEnum

[HKEY_CLASSES_ROOT\CLSID\{GUID2}]
@="SQLAnyEnum.11"

[HKEY_CLASSES_ROOT\CLSID\{GUID2}\InprocServer32]
@="d:\\mypath\\bin32\\myoledb11.dll"
"ThreadingModel"="Both"

[HKEY_CLASSES_ROOT\CLSID\{GUID2}\OLE DB Enumerator]
@="Sybase SQL Anywhere OLE DB Provider Enumerator"

[HKEY_CLASSES_ROOT\CLSID\{GUID2}\ProgId]
@="SQLAnyEnum.11"

[HKEY_CLASSES_ROOT\CLSID\{GUID2}\VersionIndependentProgID]
@="SQLAnyEnum" 

; SQLAnyA

[HKEY_CLASSES_ROOT\CLSID\{GUID4}]
@="SQLAnyA.11"

[HKEY_CLASSES_ROOT\CLSID\{GUID4}\InprocServer32]
@="d:\\mypath\\bin32\\myoledba11.dll"
"ThreadingModel"="Both"

[HKEY_CLASSES_ROOT\CLSID\{GUID4}\ProgID]
@="SQLAnyA.11"

[HKEY_CLASSES_ROOT\CLSID\{GUID4}\VersionIndependentProgID]
@="SQLAnyA"