【发布时间】:2016-09-27 06:28:10
【问题描述】:
我正在尝试使用IRunningObjectTable 来允许客户端调用者访问另一个进程中的对象以实现 UI 自动化。
+----------------+ +-----------+
| Client Process |---------------->| UI server |
| .Net WPF | | .Net WPF |
+----------------+ +-----------+
我已经实现了一个示例接口,实现如下,我在运行对象表中看到了注册对象,但是在转换为类型化接口时得到E_NOINTERFACE。
服务器
Interface.cs:
[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);
}
程序.cs:
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:
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);
}
}
程序.cs:
class Program
{
static void Main(string[] args)
{
var cp = new ChatProxy();
while (true)
cp.PrintString(Console.ReadLine());
}
}
我正在使用 regasm 注册服务器程序集。
【问题讨论】: