在COM中引用未签名的.NET程序集(Visual Basic 6)

时间:2012-08-14 04:23:24

标签: .net com

在我深入钻洞之前......一个简单的问题......

有可能吗?

我们在Visual Basic 6中创建了这个遗留系统,我们开始将它移植到.NET,我们希望它是无符号的。问题是我们每次有更新时都必须签署我们的公共库。 (公共库在不同产品之间共享)。

由于我们无法在瞬间移植所有内容,因此我们首先开始移植服务器。目前,我们将客户端接口设计为COM可见,以便Visual Basic UI可以调用它们。

我们拥有的常见框架dll是无符号的,目前许多项目都在使用它。但是对于这个产品,我们需要重新签名,这是太多的工作要做。

如果无法做到这一点,是否有其他方式,如包装器或某些技术来解决此问题?

感谢。

1 个答案:

答案 0 :(得分:3)

我认为这会因为两件事(我猜你可能已经发现)而变得棘手:

  1. 您无法重新签名未签名的库,以便它可以向COM公开。
  2. 您无法从已签名的库中引用未签名的库。
  3. 也许有人有更好的想法,但考虑到这两个限制,我认为你能做的唯一事情就是讨厌的东西......

    假设您在未签名的库中有一个要向COM公开的类,如下所示:

    public class TestClass
    {
        public string SaySomething()
        {
            return "Hello";
        }
    }
    

    您可以从未签名的程序集中引用已签名的程序集,因此第一步可以是为您希望向COM公开的类的位创建一个接口,并将这些接口放在已签名的新程序集中即可。在我们的例子中说我们定义了接口(你可以根据自己的喜好调整各种COM属性):

    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface ITestClass
    {
        string SaySomething();
    }
    

    现在引用原始程序集中的新程序集并更改类定义,以便它实现接口。

    public class TestClass : ITestClass
    

    现在,回到已签名的程序集并添加一个看起来像这样的小帮助工厂(这是可选的,但我认为在一个地方这样做是个好主意):

    internal static class ClassFactory
    {
        // Depending on how you aer hosting this you can use a relative 
        // path here (maybe) - this gets a bit tricky to sort out and is
        // most likely what will cause problems
        private static readonly Assembly UnsignedAssembly =
            Assembly.LoadFrom(@"C:\...\COMClassLibrary.dll");
    
        internal static T CreateClass<T>(string typeName)
        {
            return (T)Activator.CreateInstance(UnsignedAssembly.GetType(typeName));
        }
    }
    

    最后一步是创建一个类的封装版本,你可以像这样公开给COM:

    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("MyClasses.TestClass")]
    public class TestClassWrapped : ITestClass
    {
        private readonly ITestClass _original;
    
        public TestClassWrapped()
        {
            _original = ClassFactory.CreateClass<ITestClass>(
                "COMClassLibrary.TestClass");
        }
    
        public string  SaySomething()
        {
            return _original.SaySomething();
        }
    }
    

    现在使用regasm为COM注册已签名的程序集,并且应该这样做。大量乏味,但考虑到你的限制,这是我唯一能想到的。

    建议阅读: