C# 更改用C编写的Active-X插件的用户类型名称#

C# 更改用C编写的Active-X插件的用户类型名称#,c#,user-controls,activex,ole,C#,User Controls,Activex,Ole,我目前的任务是为我们的一个客户创建一个Active-X插件。现在,我已经成功地在C#/.NET中创建了Active-X插件(一个从System.Windows.Forms.UserControl类继承的Windows窗体控件),但是托管该插件的应用程序在显示Active-X插件的对话框窗口的标题中显示了该控件的类名 经过大量的搜索和反汇编,我发现主机调用了方法IOleObject.GetUserType,并且主机使用该方法的返回值作为对话框窗口的标题。查看System.Windows.Forms

我目前的任务是为我们的一个客户创建一个Active-X插件。现在,我已经成功地在C#/.NET中创建了Active-X插件(一个从
System.Windows.Forms.UserControl
类继承的Windows窗体控件),但是托管该插件的应用程序在显示Active-X插件的对话框窗口的标题中显示了该控件的类名

经过大量的搜索和反汇编,我发现主机调用了方法
IOleObject.GetUserType
,并且主机使用该方法的返回值作为对话框窗口的标题。查看
System.Windows.Forms.UserControl
类,我发现该类继承自
System.Windows.Forms.Control
类,该类又显式实现了
System.Windows.Forms.unsafentiveMethods.IOleObject
接口

我想知道的是,是否有某种方法可以覆盖
GetUserType
方法 在
UserControl
类中,或者如果有其他方法来实现我想要的(也许解决方案非常简单,但我到目前为止还没有看到)。到目前为止,我已经尝试了各种“可能”的解决方案:

  • 我试图重新实现
    IOleObject
    接口,但由于
    System.Windows.Forms.unsafentivemethods.IOleObject
    是内部接口,因此无法执行此操作(您必须使用完全相同的接口,并且重新定义接口不会产生完全相同的接口)

  • 我尝试使用Ziad Elmalki在上所描述的CLR注入

  • 我试着使用某种形式的AOP。由于
    控件
    类通过
    System.ComponentModel.Component
    继承自
    System.MarshalByRefObject
    ,因此我认为可以让我的用户控件返回某种代理,该代理将截获发送到
    GetUserType
    方法的调用

  • 不幸的是,我没能让它工作。有效的方法是更改类名,但由于类名不允许包含空格或其他特殊字符,因此这不是一个可接受的解决方案(下划线不一样)

    为了详细说明,这里有一个我想要完成的代码示例(请注意,它并不完整):

    希望这里有人能帮我


    提前谢谢

    您可以尝试实现ICustomQueryInterface(.Net 4.0):


    当系统查询IOleObject时,您可以返回实现IOleObject的自定义对象,将您不关心的方法转发给UserControl实现,并正确地将自定义对象上的QueryInterface调用委托回UserControl(聚合).

    尽管我能够实现ICustomQueryInterface并返回我自己的IOleObject接口实现,但将我不关心的方法转发给UserControl并不是件小事。问题仍然是一样的:控制类提供的IOleObject实现使用的某些接口/结构是私有/内部的,无法使用,因此您必须以某种方式复制这些接口/结构,并将它们转换为控制类使用的内部实现(据我所知,这是不可能的)。我希望Microsoft.VisualStudio.OLE.Interop程序集中提供的IOleObject以及相应的接口和结构在某种程度上与System.Windows.Forms程序集中提供的IOleObject兼容,但事实并非如此……不幸的是!
    using System.ComponentModel;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    
    [ ComVisible(true)
    , ClassInterface(ClassInterfaceType.AutoDual)
    , Description("My Active-X plug-in")
    , Guid("...")
    ]
    public partial class MyControl : UserControl
    {
        public override int GetUserType(int dwFromOfType, out string userType)
        {
            userType = "The caption to show in the host";
            // Return S_OK
            return 0;
        }
    }