首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >跨进程.net COM IPC抛出E_NOINTERFACE

跨进程.net COM IPC抛出E_NOINTERFACE
EN

Stack Overflow用户
提问于 2014-02-05 06:21:13
回答 1查看 260关注 0票数 1

为了实现UI自动化,我试图使用IRunningObjectTable来允许客户端调用方访问另一个进程中的对象。

代码语言:javascript
复制
+----------------+                 +-----------+
| Client Process |---------------->| UI server |
| .Net WPF       |                 | .Net WPF  |
+----------------+                 +-----------+

我用下面的实现实现了一个示例接口,并在运行的对象表中看到注册的对象,但是在转换到类型化接口时获取E_NOINTERFACE

服务器

Interface.cs:

代码语言:javascript
复制
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(IChatTarget))]
[ComVisible(true), Guid("FEF67638-6654-47DB-A40D-F11FE72795A9")]
public class ChatInterface : IChatTarget
{
    public void PrintString(string text)
    {
        Console.WriteLine(text);
    }
}

[ComVisible(true)]
[Guid("9A3164C9-F800-4B7D-9AB0-29E9F5D325B2")]
public interface IChatTarget
{
    void PrintString(string text);
}

Program.cs:

代码语言:javascript
复制
class Program
{
    static void Main(string[] args)
    {
        var ct = new ChatInterface();

        var rot = NativeMethods.GetRunningObjectTable(0);
        IMoniker moniker = NativeMethods.CreateItemMoniker("!", "TestMoniker");

        var hRotEntry = rot.Register(NativeMethods.ROTFLAGS_REGISTRATIONKEEPSALIVE, (IChatTarget)ct, moniker);

        MSG msg;
        while (NativeMethod.GetMessage(out msg, IntPtr.Zero, 0, 0))
        {
            NativeMethod.TranslateMessage(ref msg);
            NativeMethod.DispatchMessage(ref msg);
        }

        rot.Revoke(hRotEntry);
    }
}

客户端

Proxy.cs:

代码语言:javascript
复制
public class ChatProxy : IChatTarget
{
    IChatTarget target;

    public ChatProxy()
    {
        var rot = NativeMethods.GetRunningObjectTable(0);
        var moniker = NativeMethods.CreateItemMoniker("!", "TestMoniker");

        object utobj;
        if (rot.GetObject(moniker, out utobj) != 0 /* S_OK */)
        {
            throw new InvalidOperationException("Moniker not in table");
        }
        // This throws ComException(E_NOINTERFACE)
        target = (IChatTarget)utobj;
    }

    public void PrintString(string text)
    {
        target.PrintString(text);
    }
}

Program.cs:

代码语言:javascript
复制
class Program
{
    static void Main(string[] args)
    {
        var cp = new ChatProxy();
        while (true)
            cp.PrintString(Console.ReadLine());
    }
}

我正在使用regasm注册服务器程序集。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-05 06:21:13

为了获得类型化代理,必须对包含接口的程序集进行强命名。

使用强名称键对程序集进行签名,所有这些都应该是正确的。

其他陷阱:

  • 必须使用regasm标志调用/tlb来注册OLE编组,否则您可以获得E_NOINTERFACE。您可以通过查找 key进行检查。完整的命令应该是regasm assembly.dll /tlbregasm assembly.dll /tlb /u来注销。
  • 对于进程内服务器,程序集必须位于GAC中,或者必须将/codebase标志传递给regasm
  • 注册应该使用与客户端(Wow6432Node)相同的位数。
  • 对于标记为CPU的程序集,必须同时向32位和64位版本的regasm注册。
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21570008

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档