【问题标题】:Connect to multiple running instances of an application连接到应用程序的多个运行实例
【发布时间】:2015-11-06 09:04:46
【问题描述】:

我正在尝试创建与打开的应用程序的多个实例的连接(WRQ 反射)。使用这个连接到打开的第一个实例就可以了:

Session appInstance = (Marshal.GetActiveObject("Reflection4.Session.8") as Session);

但我希望能够连接到多个实例。我一直在做大量研究,发现了一些有用的链接,例如this,但该解决方案在这种情况下不起作用,因为所有打开的实例都具有相同的 progId。

我还尝试查看窗口句柄,每个实例显然不同。使用这个:

Process[] processes = Process.GetProcessesByName("r4win");
foreach (Process p in processes)
{
    IntPtr windowHandle = p.MainWindowHandle;
    string handle = windowHandle.ToString();

    MessageBox.Show(handle);
}

但我一直无法弄清楚如何通过窗口句柄创建到窗口的连接。

感谢任何帮助。

附加代码:

void TestROT()
{
    // Look for open instances
    string[] progIds = {"Reflection4.Session.8"};

    List<object> instances = GetRunningInstances(progIds);

    foreach (object refleObjs in instances)
    {
        Session session = refleObjs as Session;
        session.Transmit("12345");
    }
}

对于这种情况,我有 2 个目标应用程序实例正在运行。在上面的代码中,它会将字符串 12345 发送到应用程序的同一个实例,两次。

我需要它将 12345 发送到第一个实例,然后将 12345 发送到第二个实例。

【问题讨论】:

  • 连接是什么意思?做什么?您发布的代码是关于 COM 自动化的,而不是任何类型的连接。这是关于例如。使用 Interop 驱动 Word。你想做什么?连接意味着诸如套接字、服务、WCF 等之类的东西,而不是自动化
  • PS 即使在 COM 中,CreateObject 会创建一个新对象或使用现有对象,而 GetActiveObject 会创建一个新对象。在 .NET 中,尽管人们使用 COM Interop 而不是原始 COM 方法
  • 抱歉,不确定术语是否正确。连接是指向应用程序发送文本和命令以及从屏幕读取信息的能力。
  • 你想做什么?甚至自动化也会暴露应用程序想要暴露的内容。可访问性实用程序使用读取屏幕并使用可访问性 SDK。测试实用程序和库实际上使用辅助功能 API 来驱动 UI

标签: c# winforms


【解决方案1】:

您可以使用System.IO.Pipes-命名空间中的NamedPipeClientStreamNamedPipeServerStream 类将数据从您的应用程序发送到另一个应用程序。 在您的第一个应用程序中,像这样实现NamedPipeServerStream

NamedPipeServerStream pipeServer = new NamedPipeServerStream("MyApp1");
pipeServer.WaitForConnection();//wait for connection of client

在您的第二个应用程序中放置NamedPipeClientStream 的实例:

NamedPipeClientStream clientStream = new NamedPipeClientStream("MyApp1");
clientStream.Connect();

client连接到server后,可以使用Write的方法发送数据:

从您的服务器发送数据:

byte[] test = Encoding.UTF8.GetBytes("Hello World");
pipeServer.Write(test, 0, test.Length);

从客户端发送数据:

byte[] test = Encoding.UTF8.GetBytes("Hello World");
clientStream.Write(test, 0, test.Length);

您可以使用Read 来获取接收到的字节。该方法存在于两个类中。

您还可以同时使用多个服务器和一个客户端与更多应用程序进行通信。

【讨论】:

  • 我不熟悉命名管道,但听起来我需要能够将代码添加到我试图自动化的应用程序中,这在这种情况下是不可能的。
【解决方案2】:

根据您问题中的描述,您可能想要做的是get all instances of a running COM object

【讨论】:

  • 好的,因此在回答该问题时使用博客文章,代码需要进行一些修改并且缺少列表类型,但它确实返回了 ROT 中的项目列表。我将它们返回为List&lt;RunningObject&gt;,它工作正常,但我无法将我想要的项目从列表中转换为我正在使用的应用程序类型 - Session。获取无法通过引用转换等将类型“Form2.RunningObject”转换为“Reflection4.Session”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-19
  • 2020-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-13
相关资源
最近更新 更多