将32位dll包装为64位操作系统可与regsvr32.exe一起使用

9
我们目前正在将我们的网站从Windows 2003(32位)转移到Windows 2008(64位),但遇到了一个问题。
我们的一个网站使用支付网关HSBC CPI,需要注册一个DLL(regsvr32.exe),然后在经典ASP网站中使用该DLL。但问题是,该DLL是32位的,因此它不能在Windows 2008操作系统中进行注册。
有没有办法将这个32位的DLL封装在一个C#.net项目中,以便其方法被公开并可以在操作系统中注册?
非常感谢任何帮助。
3个回答

6
如果您想注册使用VC++或Visual Basic 6.0创建的32位COM DLL,那么您必须按照以下步骤进行操作,而不需要更改代码。也不需要进行任何编译,也不需要在WOW模式下运行IIS。几年前我曾遇到过这个问题,我解决了这个问题,并且它对我很有效。
情景:
假设您有一个第三方提供的32位COM DLL。在32位操作系统上,DLL可以正常工作,但当您转移到x64环境时,即使您尝试通过regsv32进行注册,它也无法正常工作。
还假设DLL的名称为“ASXUpload.DLL”。在下面提供的解决方案中,我们将使用此名称。
解决方案:
请按照以下步骤操作:
首先,如果您已在x64操作系统中注册了DLL,请取消注册该DLL。要执行此操作,请在运行命令中键入以下内容:“regsvr32 /u”类似于“regsvr32 /u C:\ MyDLL \ ASXUpload.DLL”。如果您已经从x64 OS取消注册了DLL,则无需运行此步骤。
还要确保您没有将DLL放在通常为C:\ Windows的Windows文件夹中。对于此示例,我已将DLL保存在以下文件夹中C:\ MyDLL。
现在,我们需要使用Microsoft的Component Services添加COM+组件。要启动Component Services,请转到控制面板/管理工具/组件服务。进入组件服务后,向下钻取计算机,然后是我的计算机,然后是COM+应用程序。然后右键单击COM+应用程序,选择“新建”->“应用程序”。
在“欢迎使用COM应用程序安装向导”屏幕上,单击“下一步>”。
单击“创建空应用程序”按钮。
输入名称。由于我的DLL名称为ASXUpload.dll,因此我已将名称键入为“ASXUpload”。当被问及“库或服务器”时,请选择“服务器”。
单击“下一步>”按钮,然后选择“This User”。
输入用户或单击浏览以选择用户。单击浏览更安全,以确保使用正确的域名和拼写。输入密码并确认密码。警告,请务必包括必要的域名/用户名。单击“完成”。 (注意:我们建议使用“This User”,否则必须有人登录到服务器才能运行DLL。)在我的情况下,我选择了域管理员帐户。您还可以添加服务帐户。如果不确定,请咨询系统管理员。
现在,“添加应用程序角色”屏幕将出现。不要添加任何内容,只需单击“下一步>”按钮。
现在,“将用户添加到角色”屏幕出现。不要添加任何内容,只需单击“下一步>”按钮。
现在,您将看到在组件服务->计算机->我的计算机->COM+应用程序下新添加的应用程序。在此示例中,应用程序名称将是“ASXUpload”。现在通过单击“+”图标向下钻取新添加的应用程序“ASXUpload”,然后您将看到“组件”。
现在右键单击“组件”,然后选择“新组件”。在“欢迎使用COM应用程序安装向导”屏幕上,单击“下一步>”。
单击“安装新组件”并选择要注册的DLL。在这种情况下,它将是“C:\ MyDLL \ ASXUpload.DLL”。
一旦您选择了DLL,您将看到它会显示找到的组件。单击“下一步>”按钮以继续,最后点击“完成”按钮以完成。
现在是棘手的部分。右键单击您已添加的应用程序,您将在组件服务->计算机->我的计算机->COM+应用程序下找到它。在我的情况下,应用程序名称为“ASXUpload”。右键单击应用程序后选择“属性”。应用程序属性窗口将打开。单击“安全”选项卡。在安全选项卡中,请确保“授权”部分下的复选框“强制执行此应用程序的访问检查”未选中。

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

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

将“Impersonate Level”设置为“匿名”

  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年再次使用它。

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


6

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

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

一个更简单的选择是向汇丰银行请求一个x64的dll。


谢谢Chris,这有效。不幸的是,汇丰银行不支持64位操作系统。 - Tim Jarvis

2
我们在处理汇丰银行CPI接口时遇到了同样的问题。
汇丰银行没有提供.Net封装器,而COM封装器无法从64位应用程序中调用。
这使得从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));
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接