【问题标题】:Change ProgID of a COM class更改 COM 类的 ProgID
【发布时间】:2014-07-22 09:11:45
【问题描述】:

我正在用 C# 创建一个 COM 组件。安装后,其 ProgID 表示为 <Namespace>.<Classname>。但是我想改成<Vendor>.<ClassName>.<VersionNumber>

如何在 C# 中做到这一点。我正在使用 Visual Studio 2010。

【问题讨论】:

  • 你是怎么安装的?推荐的安装方式是手动写入注册表项。
  • 真的吗?怎么样?我认为推荐的方法是使用 regasm!?!?
  • @大卫!但问题是只更改 ProgID。
  • @Bond!我尝试了 regasm,但它无法注册用 C# 编写的 COM 程序集。至少它对我不起作用。但这不是问题所在。
  • @Omer 你可以写任何你喜欢的东西到注册表

标签: c# com progid


【解决方案1】:

MS 声明:

ProgId 是通过结合 namespace 带有类型名称,以点分隔。

这不是真的,因为根据我的经验,ProgIds 是由 项目名称 和类组合而成的。由于默认命名空间是项目的名称,MS的说法似乎是对的,但如果你改变命名空间的名称,ProgId不会随之改变。

MS 继续:

但是,这可能会产生无效的 ProgId,因为 ProgId 仅限于 39 个字符,不能包含除句点以外的标点符号 [I 认为:只有一个时期]。在这种情况下,可以手动设置 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 与 namespace.class 名称相同。要做到这一点,但使用供应商名称,您需要更改类的命名空间以包含供应商名称,并且为了完整起见,还要更改项目属性中的默认命名空间。

    【讨论】:

    • 嗯,我所做的只是在现有答案中添加了一个代码示例,但我收到了没有任何解释的反对票。也许@Bond 不喜欢我说自己不够努力——哈哈。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2015-07-22
      • 2010-11-18
      • 2012-08-08
      • 2020-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-31
      相关资源
      最近更新 更多