POS for .NET 应用程序与 32 位 OPOS 服务对象的兼容性(POS for .NET v1.14 SDK 文档)

由于 OLE for Retail POS (OPOS) 服务对象仅作为 32 位对象存在,因此在某些情况下,引用适用于 .NET 的 Microsoft 服务点 (POS for .NET) 程序集的 64 位应用程序可能无法加载 OPOS 服务对象。 如果应用程序满足某些要求,则可以使用本主题中讨论的两个过程之一来与 32 位 OPOS 服务对象进行互操作。

编译为 32 位的 POS for .NET 应用程序应适用于所有 OPOS 服务对象,不需要本主题中所述的任何过程。

要求

应用程序必须满足以下所有条件才能使用本主题中所述的过程:

  • 应用程序在 64 位 Windows 上运行。
  • 应用程序使用 OPOS 服务对象。
  • 引用 POS for .NET 的可执行文件编译为 Microsoft 中间语言 (MSIL)(“anycpu”平台)。
  • 应用程序引用的所有托管程序集也编译为 MSIL。

在这些情况下,公共库运行时 (CLR) 将看到所有托管程序集都是 MSIL,因此它将选择将托管应用程序作为 64 位进程运行。 当 POS for .NET 尝试将 32 位 OPOS 服务对象加载为进程内 COM 服务器时,它将无法加载,并且设备对应用程序不可见。 这是因为 64 位进程无法将 32 位 COM 服务器加载到其进程空间中。

可以使用以下两种解决方案之一来解决此问题:

将托管进程编译为 32 位进程

可以通过编译主可执行文件以面向 x86 或 anycpu32bitpreferred 平台来强制进程作为 32 位进程运行。 这会导致托管应用以 32 位形式运行,并将 OPOS 对象加载为进程内 COM 服务器。

在命令提示符下将应用程序编译为 32 位

  1. /platform:x86 编译器选项添加到 C# 编译器命令,如以下示例所示:

    csc /platform:x86 <filename>.cs

    有关详细信息,请参阅 MSDN 上的 /platform(C# 编译器选项)

在 Visual Studio 2013 中将应用程序编译为 32 位

  1. 在 Microsoft Visual Studio 2013 中打开项目。

  2. 打开“生成”菜单,选择“Configuration Manager”。

  3. 在“Configuration Manager”对话框的“平台”列中,单击单元格以展开下拉菜单,然后选择“x86”。 如果“x86”不可用,请选择“<新建...>”,然后选择“x86”作为新平台并单击“确定”。

  4. 重新生成项目。

将托管进程编译为 64 位进程并修改 OPOS 对象的 COM 注册表

可以修改 OPOS 服务对象的 COM 注册以使用 32 位主机进程。 这会导致 Windows 处理进程内通信 (IPC) 和 64 位托管进程与 32 位 COM 代理主机进程之间的数据封送。

修改 OPOS 服务对象的 COM 注册表

  1. 在注册表中,在 HKEY_CLASSES_ROOT/Wow6432Node/CLSID 下找到 COM 对象 GUID 项。

  2. 找到 COM 对象 GUID 键后,添加新字符串值 (REG_SZ)。 将名称设置为 AppID,并将数据设置为 COM 对象 GUID,包括大括号。

  3. 在 HKEY_CLASSES_ROOT/Wow6432Node/AppID 下添加新键,其名称与 COM 对象 GUID 键相同。

  4. 在刚刚添加的新键下,添加新的字符串值 (REG_SZ)。 将名称设置为 DllSurrogate。 将此值留空。

  5. 在 HKEY_LOCAL_MACHINE/Software/Classes/AppID 下创建一个与 COM 对象的 GUID 同名的新键(如果尚不存在)。 无需向此键添加任何值。

或者,可以使用以下 Windows PowerShell 脚本修改所有 OPOS 公用控件对象 (CCO) 的 COM 注册表,以使用进程外 COM 服务器。 可以运行此脚本,确保所有 OPOS 服务对象都能够与 64 位应用程序互操作。 必须从管理员 Windows PowerShell 提示符运行脚本。

# This Windows PowerShell script modifies the COM registry for all OPOS
# Common Control Objects (CCO) so that they use out of process COM servers.
# This enables OPOS service objects to work with both 32-bit and 64-bit
# POS for .NET applications.

# .Synopsis
# Create-Regkey: This function creates a new key in the registry
function Create-Regkey {
    param(
        [string] $Key
    )

    if (!(test-path -path $Key -pathType container)) {
            New-Item -path $Key -type container | Out-Null
    }
}

# .Synopsis
# Set-RegEntry: This function creates a new registry key in the registry and
# creates a new value in the key.
function Set-RegEntry {
    param(
        [string] $Key,
        [string] $Name,
        [string] $PropertyType,
        $Value
    )

    Create-RegKey -Key $Key
    Remove-ItemProperty -Path $Key -Name $Name -ErrorAction SilentlyContinue
    New-ItemProperty -Path $Key -Name $Name -PropertyType $PropertyType -Value $Value | Out-Null
}

# Iterate through all of the OPOS Common Control Objects, setting registry
# entries and values for each object.

for ($i = 2; $i -lt 38; $i++) {
    $clsid = '{{CCB90{0:D2}2-B81E-11D2-AB74-0040054C3719}}' -f $i

    Set-RegEntry -Key "hklm:\SOFTWARE\Classes\Wow6432Node\CLSID\$clsid" -Name 'AppID' -PropertyType String -Value $clsid
    Set-RegEntry -Key "hklm:\SOFTWARE\Classes\Wow6432Node\AppID\$clsid" -Name 'DllSurrogate' -PropertyType String
    Create-RegKey -Key "hklm:\SOFTWARE\Classes\AppID\$clsid"
}

If you need to revert the COM registry after running the previous script, you can run the following Windows PowerShell script to remove the new COM registry entries:

# This Windows PowerShell script restores the COM registry for all OPOS
# Common Control Objects (CCO) to their original values.

for ($i = 2; $i -lt 38; $i++) {
    $clsid = '{{CCB90{0:D2}2-B81E-11D2-AB74-0040054C3719}}' -f $i

    Remove-ItemProperty -Path "hklm:\SOFTWARE\Classes\Wow6432Node\CLSID\$clsid" -Name 'AppID'
    Remove-Item -Path "hklm:\SOFTWARE\Classes\Wow6432Node\AppID\$clsid"
    Remove-Item -Path "hklm:\SOFTWARE\Classes\AppID\$clsid"
}

另请参阅

其他资源