更改COM类的ProgID

5

我正在用C#创建一个COM组件。当它被安装时,它的ProgID表示为其<Namespace>.<Classname>。但是我想将其更改为<Vendor>.<ClassName>.<VersionNumber>

我该如何在C#中实现这个功能?我正在使用Visual Studio 2010。


你是如何安装的?推荐的安装方式是手动编写注册表项。 - David Heffernan
真的吗?那怎么做呢?我以为推荐的方法是使用regasm!?!? - Ventsyslav Raikov
@David!但问题是仅更改ProgID。 - Omer
@Bond!我尝试了regasm,但它无法注册用C#编写的COM程序集。至少对我来说不起作用。但这不是问题的关键。 - Omer
@Omer,你可以向注册表中写入任何你喜欢的内容。 - David Heffernan
3个回答

4

微软宣称:

通过将命名空间和类型名称用点号分隔组合在一起,自动生成类的ProgIds。

根据我的经验,这不是完全正确的。实际上,类的ProgIds是从项目名称和类名组合而成的。由于默认命名空间是项目名称,微软的说法似乎是正确的。但是,如果更改命名空间的名称,则相应更改的ProgId不会发生变化。

微软继续说:

然而,这可能会产生一个无效的ProgId,因为ProgId被限制在39个字符内,并且除了句点外不能包含任何标点符号[我认为:只能有一个句点]。在这种情况下,可以使用ProgId属性手动为类分配一个ProgId。

因此,看起来只有在这种情况下才能更改ProgId,在正常情况下设置ProgId是无用的,它始终为ProjectName.ClassName。

在以下示例中,我尝试选择Dietrich.Math作为项目名称并使用Dietrich.Math.ClassName作为ProgId,但没有成功:Dietrich.Math被更改为Dietrich_Math。与预期的一样,.NET忽略了ProgId属性,并将ProgId设置为Dietrich_Math.Arithmetic。

using System;
using System.Runtime.InteropServices;

namespace Dietrich.Math
{
  [ComVisible(true), Guid("B452A43E-7D62-4F11-907A-E2132655BF97")]
  [InterfaceType(ComInterfaceType.InterfaceIsDual)]
  public interface IArithmetic
  {
    int Add(int a, int b);
  }

  [ComVisible(true), Guid("17A76BDC-55B7-4647-9465-3D7D088FA932")]
  [ProgId("SimpleMath.Whatever")]
  [ClassInterface(ClassInterfaceType.None)]
  public class Arithmetic : IArithmetic
  {
    public int Add(int a, int b) { return a + b; }
  }
}

2

我认为用户@Bond提出的想法是正确的,但遗憾的是,@Bond没有留下示例。这里是使用ProgId的示例...

using System;
using System.Runtime.InteropServices;

namespace EncryptionCOMTool
{
    [ComVisible(visibility:true)]
    [Guid(guid: "4a69e3ce-7cf8-4985-9b1a-def7977a95e7")]
    [ProgId(progId: "EncryptionCOMTool.EncryptDecrypt")]
    [ClassInterface(classInterfaceType: ClassInterfaceType.None)]
    public class EncryptDecrypt
    {
        public EncryptDecrypt()
        {

        }

        public string Encrypt(string input)
        {
            return "some encrypted value";
        }

        public string Decrypt(string input)
        {
            return "some decrypted value";
        }
    }
}

由于属性ProgId需要一个字符串作为输入,您可以在其中放置任何您喜欢的内容,包括供应商名称。 为了代码维护,您可以选择将ProgId与命名空间.类名保持相同。要做到这一点,但使用供应商名称,您需要更改类的命名空间以包含供应商名称,并为完整性还需在项目属性中更改默认命名空间。


哎呀,我只是在现有答案中添加了一个代码示例,结果就被莫名其妙地踩了一下,没有任何解释。也许@Bond不喜欢我指出缺乏努力 - 哈哈。 - barrypicker

1

您是否尝试将ProgId属性应用于该类?


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