9

我们目前正在将我们的网站从 Windows 2003(32 位)转移到 Windows 2008(64 位)并且遇到了问题。

我们的一个网站使用支付网关 HSBC CPI,它需要注册一个 DLL (regsvr32.exe),然后在一个经典的 asp 网站中使用这个 DLL。问题是 DLL 是 32 位 DLL,因此它不会在 Windows 2008 操作系统中注册。

有没有办法可以将这个 32 位 dll 包装在 ac#.net 项目中,以便公开它的方法并可以在操作系统中注册?

任何帮助将不胜感激。

4

3 回答 3

6

您可以使用 C:\Windows\SysWOW64 文件夹中的 regsvr32.exe 注册 DLL。

但是,由于您不能混合 64/32 位代码,您必须创建一个在 x86 中运行的 C# 服务(请参阅项目属性、平台目标),然后您可以通过 WCF 从您的 x64 Web 应用程序使用该服务。

一个更简单的选择是向 HSBC 索要 x64 dll。

于 2009-04-20T13:55:03.673 回答
6

如果要注册使用 VC++ 或 Visual Basic 6.0 创建的 32 位 COM dll,则必须按照以下步骤操作,而无需对代码进行任何更改。它也不需要进行任何编译,您也不必在 WOW 模式下运行 IIS。几年前我遇到过这个问题,我解决了这个问题,它对我来说很好。

设想:

让我假设您有一个供应商提供的第 3 方 32 位 COM DLL。该 DLL 在 32 位操作系统上运行良好,当您移至 x64 环境时,即使您尝试通过 regsv32 注册它,它也无法运行。

还让我假设 DLL 的名称是“ASXUpload.DLL”。我将在下面提供的解决方案中使用此名称。

解决方案

请按照以下步骤操作:

  1. 首先,如果您已经在 x64 操作系统中注册了 DLL,请取消注册 DLL。为此,只需在运行命令“regsvr32 /u”中键入以下内容,例如“regsvr32 /u C:\MyDLL\ASXUpload.DLL”。如果您已经从 x64 操作系统注销 DLL,则无需运行此步骤。

  2. 还要确保您没有将 DLL 保存在通常为 C:\Windows 的 Windows 文件夹中。对于此示例,我将 DLL 保存在以下文件夹 C:\MyDLL 中。

  3. 现在我们需要使用 Microsoft 的 Component Services 添加 COM+ 组件。要启动组件服务,请转到控制面板/管理工具/组件服务。一旦进入组件服务,深入到计算机,然后是我的电脑,然后是 COM+ 应用程序。然后右键单击 COM+ 应用程序并选择“新建”->“应用程序”。

  4. 在“欢迎使用 COM 应用程序安装向导”屏幕上,单击“下一步 >”。

  5. 单击“创建空应用程序”按钮。

  6. 输入名称。由于我的 DLL 名称是 ASXUpload.dll,所以我将名称输入为“ASXUpload”。当询问“库或服务器”时,选择“服务器”。

  7. 单击“下一步>”按钮,然后选择“此用户”。

  8. 输入用户或单击浏览以选择用户。单击浏览更安全,以确保使用正确的域和拼写。输入密码并确认密码。警告,如果需要,请务必包含域/用户名。点击“完成”。(注意:我们推荐“此用户”,否则,必须有人登录服务器才能运行 DLL。)。就我而言,我选择了域管理员帐户。您还可以添加服务帐户。如果您不确定,请咨询您的系统管理员。

  9. 现在将出现“添加应用程序角色”屏幕。不要添加任何内容,只需单击“下一步>”按钮。

  10. 现在出现“将用户添加到角色”屏幕。不要添加任何内容,只需单击“下一步>”按钮。

  11. 现在您将看到在组件服务 -> 计算机 -> 我的电脑 -> COM+ 应用程序 -> 您将看到新添加的应用程序。在此示例中,应用程序名称将是“ASXUpload”。现在通过单击“+”图标深入了解新添加的应用程序“ASXUpload”,您将看到“组件”。

  12. 现在右键单击“组件”,然后选择“新建组件”。在“欢迎使用 COM 应用程序安装向导”屏幕上,单击“下一步 >”。

  13. 单击“安装新组件”,然后选择要注册的 DLL。在这种情况下,它将是“C:\MyDLL\ASXUpload.DLL”。

  14. 选择 DLL 后,您会看到它会显示找到的组件。单击“下一步>”按钮继续,最后单击“完成”按钮完成。

  15. 现在是棘手的部分。右键单击您添加的应用程序,您将在组件服务 -> 计算机 -> 我的电脑 -> COM+ 应用程序下找到该应用程序。在我的例子中,应用程序名称是“ASXUpload”。右键单击应用程序后选择“属性”。应用程序属性窗口将打开。单击“安全”选项卡。在“安全”选项卡中,确保未选中“授权”部分下的“强制执行此应用程序的访问检查”复选框。

在“安全级别”部分下,选择单选按钮“仅在进程级别执行访问检查。安全属性不会包含在对象上下文中。COM+ 安全调用上下文将不可用。”</p>

确保未选中“应用限制策略”选项。

将“模拟级别”设置为“匿名”</p>

  1. 如果要从 Web 应用程序访问 DLL,请确保添加 IUSR 和 IWAM 帐户。为此,请转到 COM+ 应用程序 -> 应用程序名称(在本例中为 ASXUpload)-> 角色 -> CreateOwner -> 用户。右键单击用户并添加 Internet Information Server 使用的 IUSR 和 IWAM 帐户。

  2. 还要对保存 DLL 的文件夹设置 NTFS 权限。在这种情况下,我将 DLL 保存在文件夹 C:\MyDLL 中。现在右键单击文件夹“MyDLL”并转到安全选项卡,然后添加 IUSR 和 IWAM 帐户。

这就是您需要做的所有事情,并且您应该能够使用 DLL。

我在过去曾在生产环境中工作过的两个不同组织中使用过这种技术两次,并且没有任何问题。首先我在 2005 年尝试过,然后在 2008 年再次使用它。

如果您遇到任何问题,请告诉我。

于 2010-09-10T21:18:35.967 回答
2

我们在 HSBC Cpi 接口上遇到了同样的问题。

HSBC 不提供 .Net 包装器,并且无法从 64 位应用程序调用 COM 包装器。

这使得从 64 台服务器(可能覆盖 25% 的新生产服务器)上部署它几乎是不可能的。

我们查看了列出的一些方法,但它们似乎需要做很多工作。最后经过一番折腾,我们想出了自己的实现,看起来像这样。

使用以下 Java 代码获取中间哈希

import java.io.Console;
import java.lang.*;
import java.util.*;
import com.clearcommerce.CpiTools.security.HashGenerator;
import com.clearcommerce.CpiTools.security.SecCrypto;
import javax.xml.bind.annotation.adapters.HexBinaryAdapter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Vector;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class Extract {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try
        {
            String encryptedKey = "<YOUR SECRET KEY HERE>";
            if (args.length == 1)
                encryptedKey = args[0];

            HexBinaryAdapter hb = new HexBinaryAdapter();
            SecCrypto sc = new SecCrypto();

            byte abyte0[] = sc.decryptToBinary(encryptedKey);
            System.out.println("New Secret Base64 Encoded : " + new String(Base64Coder.encode(abyte0)));
            System.out.println("New Secret Hex Encoded    : " + hb.marshal(abyte0));
            return;
        }
        catch(Exception ex)
        {
            System.out.println("Error:" + ex.getMessage());
        }
    }
}

然后使用以下 .net 代码计算哈希

using System;
using System.Collections.Generic;
using System.Text;

namespace HsbcIntergration
{
    internal static class CpiHashing
    {
        <USE THE VALUE RETURNED FROM THE JAVA CODE HERE>
        private static readonly byte[] _secret = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

        public static string ComputeHash(List<string> inputList)
        {
            return ComputeHash(inputList, _secret);
        }

        public static string ComputeHash(List<string> inputList, byte[] secretData)
        {
            List<string> orderedDataToHash = new List<string>(inputList);
            orderedDataToHash.Sort(StringComparer.Ordinal);

            StringBuilder sb = new StringBuilder();
            foreach (string s in orderedDataToHash)
                sb.Append(s);

            List<byte> dataToHash = new List<byte>();
            dataToHash.AddRange(Encoding.ASCII.GetBytes(sb.ToString()));
            dataToHash.AddRange(secretData);

            System.Security.Cryptography.HMAC sha = System.Security.Cryptography.HMACSHA1.Create();
            sha.Key = secretData;
            return Convert.ToBase64String(sha.ComputeHash(dataToHash.ToArray(), 0, dataToHash.Count));
        }
    }
}
于 2009-11-24T17:16:03.830 回答