C# 为 64 位操作系统包装 32 位 dll 以与 regsvr32.exe 一起使用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/768336/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 00:24:11  来源:igfitidea点击:

wrap 32 bit dll for 64 bit operating system to work with regsvr32.exe

c#asp-classicdllregistration

提问by Tim Jarvis

We are currently transferring our websites from Windows 2003 (32-bit) to Windows 2008 (64-bit) and have hit a problem.

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

One of our website use the payment gateway HSBC CPI which requires a DLL to be registered(regsvr32.exe), this DLL is then used inside a classic asp website. The problem is the DLL is a 32-bit DLL and so it will not register with the the Windows 2008 operating system.

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

Is there a way we can wrap this 32 bit dll in a c#.net project so that it's methods are exposed and can be registerd with the OS?

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

Any help would be very much appreciated.

任何帮助将不胜感激。

采纳答案by laktak

You can register the DLL with regsvr32.exe from the C:\Windows\SysWOW64 folder.

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

However since you can't mix 64/32bit code you'd have to create a C# service running in x86 (see the project properties, platform target) that you can then use from your x64 web app via WCF.

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

An easier option would be to ask HSBC for a x64 dll.

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

回答by Colin

We hit the same problems with the HSBC Cpi interface.

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

HSBC don't supply a .Net wrapper, and the COM wrapper can not be called from a 64bit app.

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

This makes deploying it from on a 64 server (which probably covers 25% of new production servers) practically imposible.

这使得在 64 位服务器(可能覆盖 25% 的新生产服务器)上部署它实际上是不可能的。

We looked at some of the approaches listed, but they seemed like a lot of work. In the end after a bit of messing around we came up with our own implementation, which looks something like this.

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

Use the following Java code to get the intermediate hash

使用以下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());
        }
    }
}

Then use the following .net code to calcualte the hash

然后使用以下 .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));
        }
    }
}

回答by Sarbashish Bhattacharjee

If you want to register the 32-bit COM dll created using VC++ or Visual Basic 6.0 then you have to follow the steps below without making any changes in the code. It also does not require any compilation to be done and also you do not have to run the IIS in WOW Mode. I have faced this issue few years back and I resolved this issue and it works fine for me.

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

Scenario:

设想:

Let me assume that you have a 3rd party 32-bit COM DLL provided by a vendor. The DLL works fine on 32bit Operating system and the moment you move to a x64 environment it does not work even though you have tried to register it through regsv32.

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

Also let me assume that the name of the DLL is "ASXUpload.DLL". I will use this name in the solution which I am providing below.

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

Solution

解决方案

Please follow the steps below:

请按照以下步骤操作:

  1. First of all if you have already registered the DLL in x64 Operating System the unregister the DLL. To do that just type the following in the run command "regsvr32 /u " something like "regsvr32 /u C:\MyDLL\ASXUpload.DLL". If you have already unregistered the DLL from the x64 OS then no need to run this step.

  2. Also make sure that you have not kept your DLL inside the Windows folder which is normally C:\Windows. For this example I have kept the DLL in the following folder C:\MyDLL.

  3. Now we need to add the COM+ Components using Component Services of Microsoft. To start Component Services, go to Control Panel / Administrative Tools/ Component Services. Once inside component Services, drill down into Computers, then My Computer, then COM+ Applications. Then Right-click on COM+ Applications and choose "New" -> "Application".

  4. At "Welcome to the COM Application Install Wizard" screen, click “Next >”.

  5. Click on “Create an Empty Application” button.

  6. Enter the name. Since my DLL name is ASXUpload.dll so I have typed in the name as “ASXUpload”. When asked "Library or Server", select “Server”.

  7. Click “Next >” button and then choose “This User”.

  8. Enter the User or click Browse to select the user. Clicking Browse is safer, to ensure that the correct domain and spelling are used. Enter the password and confirm the password. Warning, be sure to include the domain/username if required. Click on “Finish”. (Note: We recommend "This User", otherwise, someone must be logged onto the server in order for DLL to run.). In my case I have chosen the domain administrator account. You can also add a Service Account. If you are not sure please consult with your system administrator.

  9. Now “Add Application Roles” screen will appear. Do not add anything just click on the “Next >” button.

  10. Now “Add Users to Role” screen appear. Do not add anything just click on the “Next >” button.

  11. Now you will see that under Component Services -> Computers -> My Computer -> COM+ Application -> you will see the newly added application. In this example the application name would be "ASXUpload". Now drill down the newly added application “ASXUpload” by clicking the “+” icon and you will see “Components”.

  12. Now right-click on “Components” and then choose “New Component”. At "Welcome to the COM Application Install Wizard" screen, click “Next >”.

  13. Click on “Install new component(s)” and now select the DLL which you want to register. In the case it would be “C:\MyDLL\ASXUpload.DLL”.

  14. Once you select the DLL you will see that it will show you the components found. Click on the “Next >” button to proceed and finally hit the “Finish” button to complete.

  15. Now is the tricky part. Right click on the application you have added which you will find under Component Services -> Computers -> My Computer -> COM+ Application. In my case the application name is “ASXUpload”. After you right click on the Application select “Properties”. The application properties window will open up. Click on the “Security” tab. In the Security tab make sure that under “Authorization” section the checkbox “Enforce access checks for this application” is unchecked.

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

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

  3. 现在我们需要使用 Microsoft 的组件服务添加 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”。右键单击应用程序后,选择“属性”。应用程序属性窗口将打开。单击“安全”选项卡。在“安全”选项卡中,确保“授权”部分下的“强制对此应用程序进行访问检查”复选框未选中。

Under “Security Level” section select the radio button “Perform access checks only at the process level. Security property will not be included on the object context. COM+ security call context will not be available.”

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

Make sure that option “Apply restriction policy” is unchecked.

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

Set “Impersonate Level” to “Anonymous”

将“模拟级别”设置为“匿名”

  1. If you want to access the DLL from web Application then make sure that you add the IUSR and IWAM account. To do this go to COM+ Application -> Application Name (In this case it will be ASXUpload) -> Roles -> CreateOwner -> Users. Right click on the Users and add the IUSR and IWAM account used by Internet Information Server.

  2. Also set the NTFS permission on the folder where you kept the DLL. In this case I have kept the DLL inside the folder C:\MyDLL. Now right click on the folder “MyDLL” and go to the security tab and then add the IUSR and IWAM account.

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

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

This is all you need to do and you should be able to consume the DLL.

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

I have used this technique twice in two different organizations I have worked in the past on the Production Environment and it works without any issues. First I tried this in the year 2005 and then I used it again in 2008.

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

Let me know if you are facing any issues.

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