使用 4.0 框架和 Visual Studio 2010 为 ASP Classic 构建 COM 互操作库 [英] Building a COM interop library for ASP Classic using 4.0 framework and Visual Studio 2010

查看:18
本文介绍了使用 4.0 框架和 Visual Studio 2010 为 ASP Classic 构建 COM 互操作库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在浏览了许多不同的文章后,没有找到任何特别能引导我逐步完成整个过程的结论,我来寻求帮助.

After going through a number of different articles and not finding anything especially conclusive that takes me step-by-step through the process, I've come seeking help.

场景

我的一个客户只精通 ASP Classic 的开发.他们最近获得了一个最初用 ASP.NET 编写的站点的帐户.他们正在将站点转变成他们可以积极维护的东西,但该站点最初包含一个图像处理程序,该处理程序获取有关水位的动态变化数据并输出包含该数据的图形表示的图像.要求是开发一个 COM 互操作库,可以在服务器上注册并用 CreateObject 调用使用 响应生成相同图像的字节数组以进行输出.二进制写入.COM 互操作库必须在 Windows 2000 Server 的远程站点上注册,我无法假设他们可以访问 regasm/gacutil 来完成该任务.

A client of mine is only proficient in development for ASP Classic. They have recently acquired an account for a site originally written in ASP.NET. They are rolling the site into something they can actively maintain, but the site originally included an image handler that took dynamically changing data regarding water levels and outputs an image containing a graphical representation of that data. The requirement is to develop a COM interop library that can be registered on the server and called with CreateObject to generate the same image's byte array for output using Response.BinaryWrite. The COM interop library must be registered at the remote site on a Windows 2000 Server, and I can't make any assumptions about their having access to regasm/gacutil to accomplish that task.

困难

我通过在 Visual Studio 2010 中创建一个类库项目,从模板中选择COM 类",并插入我的代码来生成一个具有单个公共方法的类,从而构建了类库当给定一个整数时返回一个字节数组(好吧,枚举器,但都是一样的).不幸的是,即使在我自己的开发机器上构建库并注册(regasm)和缓存程序集(gacutil)后,我也无法通过经典 ASP 调用来实例化对象,而是接收到ActiveX 组件无法创建对象"错误.而且,当然,在服务器站点,无法注册 DLL 文件,响应为找不到所需的模块".

I've built the class library by creating a Class Library project in Visual Studio 2010, choosing "COM Class" from the template, and inserting my code to generate a class with a single public method to return a byte array when given an integer (well, enumerator, but all the same). Unfortunately, even on my own development machine after building the library and registering (regasm) and caching the assembly (gacutil), I can't make a call through Classic ASP to instantiate the object, receiving instead an "ActiveX component can't create object" error. And, of course, at the server site, the DLL file can't be registered, the response being "Required module was not found."

我使用过的资源

我已经浏览了以下文章,但没有找到我需要的答案:

I've already had a look through the following articles and haven't turned up the answers I need:

  1. (基本步骤)演练: 使用 Visual Basic 创建 COM 对象
  2. 构建和部署 .NET COM 程序集
  3. 具有经典 ASP 的 .NET COM+ 互操作组件

我需要什么

基本上我需要的是一步一步地了解满足要求并创建一个COM+ 互操作模块在 Visual Studio 2010 中正确.创建实际的类对象本身并不是非常困难.

Essentially what I need is a bit of hand-holding on a kind of step by step of what it's going to take to meet the requirements and create a COM+ interop module correctly in Visual Studio 2010. Creating the actual class object itself isn't terribly difficult.

但是,我浏览过的所有文章都没有真正讨论过使用 Visual Studio 2010 或 .NET 4.0 Framework 的项目选项或构建过程,也没有任何文章真正讨论过部署到旧系统时是否有特殊注意事项,例如Windows Server 2000 和库在系统上的实际注册,例如,regsvr32.

However, none of the articles I've looked through really discuss project options or build procedures with Visual Studio 2010 or the .NET 4.0 Framework, nor have any of them really discussed if there are special considerations for deploying to older systems like Windows Server 2000 and the actual registration of the library on a system with only, say, regsvr32 on hand.

推荐答案

将基本的 .NET 程序集暴露给 COM 应该相当简单 - 我从未尝试过 COM Class 项目模板,所以这就是我的方式过去管理过它:

It should be fairly straightforward to get a basic .NET assembly exposed to COM - I've never tried the COM Class project template, so this is the way I've managed it in the past:

使用 C# 或 VB 创建一个新的(bog 标准).NET 类库.定义一个 COM 接口(用你自己的 GUID 替换):

Create a new (bog standard) .NET class library using C# or VB. Define a COM interface (replace GUIDs with your own):

[ComVisible(true)]
[Guid("8999F93E-52F6-4E29-BA64-0ADC22A1FB11")]
public interface IComm
{
    string GetMyGroups();
}

现在定义一个实现该接口的类(同样,用您自己的 GUID 替换):

Now define a class that implements that interface (again, replace GUIDs with your own):

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[GuidAttribute("C5C5A1A8-9BFB-4CE5-B42C-4E6688F6840B")]
[ProgId("Test.Comm.1")]
public class Comm : IComm
{
    public string GetMyGroups()
    {
        var comm = new CommunicatorAPI.MessengerClass();

        var groups = comm.MyGroups as IMessengerGroups;
        return string.Join(", ", groups.OfType<IMessengerGroup>().Select(g => g.Name).ToArray());
    }
}

此类的 Prog ID 属性是您将用于从 ASP 实例化组件的内容.

The Prog ID attribute on this class is what you will use to instantiate your component from ASP.

强命名程序集(项目属性 -> 签名"选项卡 -> 签名程序集" -> 使用下拉列表创建新的强名称密钥文件)

Strongly-name the assembly (Project properties -> "Signing" tab -> "Sign the assembly" -> Create a new strong name key file using the dropdown)

现在,构建程序集,并使用 Regasm 注册 -如果您不想在 GAC 中注册(我建议这样做,因为不是 GACing 使部署更简单),请务必使用 -Codebase 参数(这只是添加了一个 reg 条目,告诉客户在哪里可以找到程序集) - 例如:

Now, build the assembly, and register using Regasm - if you don't wish to register in the GAC (which i'd recommend, as not GACing keeps the deployment simpler), be sure to use the -Codebase parameter (this just adds a reg entry that tells clients where to find the assembly) - e.g:

regasm ClassLibrary2.dll /codebase "S:TestingClassLibrary2ClassLibrary2inDebugClassLibrary2.dll"

现在您应该能够实例化组件,并在其上调用方法 - 例如(在 javascript 中):

Now you should be able to instantiate the component, and call methods on it - for example (in javascript):

var a = new ActiveXObject("Test.Comm.1");
alert(a.GetMyGroups());

在部署方面,Regasm 和 Regsvr32 所做的重要工作是将各种设置写入注册表,以便客户端可以找到 COM 组件(基于 Prog ID,或 COM Class ID).您需要做的就是找出在本地机器上运行 Regasm 时正在写入的 COM 设置,并将这些写入服务器上的注册表.您可以使用 ProcMon 来监视运行 Regasm 时写入注册表的内容.

When it comes to deployment, the important work that Regasm and Regsvr32 do is to write various settings into the registry, so that clients can find the COM component (based on Prog ID, or COM Class ID). All you need to do is work out what COM settings are being written when you run Regasm on your local machine, and write these to the registry on the server. You can use ProcMon to monitor what gets written to the registry when Regasm is run.

一般来说,您可以期待看到写入注册表的内容:

Generally speaking, you can expect to see something like this written to the registry:

[HKEY_CLASSES_ROOTTest.Comm.1]
@="ClassLibrary2.Comm"

[HKEY_CLASSES_ROOTTest.Comm.1CLSID]
@="{00585504-90C8-4760-A359-67CAF08FFED1}"

[HKEY_CLASSES_ROOTWow6432NodeCLSID{00585504-90C8-4760-A359-67CAF08FFED1}]
@="ClassLibrary2.Comm"

[HKEY_CLASSES_ROOTWow6432NodeCLSID{00585504-90C8-4760-A359-67CAF08FFED1}Implemented Categories]

[HKEY_CLASSES_ROOTWow6432NodeCLSID{00585504-90C8-4760-A359-67CAF08FFED1}Implemented Categories{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}]

[HKEY_CLASSES_ROOTWow6432NodeCLSID{00585504-90C8-4760-A359-67CAF08FFED1}InprocServer32]
@="mscoree.dll"
"ThreadingModel"="Both"
"Class"="ClassLibrary2.Comm"
"Assembly"="ClassLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cf55d4e60653257a"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///S:/Testing/ClassLibrary2/ClassLibrary2/bin/Debug/ClassLibrary2.DLL"

[HKEY_CLASSES_ROOTWow6432NodeCLSID{00585504-90C8-4760-A359-67CAF08FFED1}InprocServer321.0.0.0]
"Class"="ClassLibrary2.Comm"
"Assembly"="ClassLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cf55d4e60653257a"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file:///S:/Testing/ClassLibrary2/ClassLibrary2/bin/Debug/ClassLibrary2.DLL"

[HKEY_CLASSES_ROOTWow6432NodeCLSID{00585504-90C8-4760-A359-67CAF08FFED1}ProgId]
@="Test.Comm.1"

希望这有帮助:)

这篇关于使用 4.0 框架和 Visual Studio 2010 为 ASP Classic 构建 COM 互操作库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆