2

我试图在两个应用程序之间传递消息 - 其中一个是插件,另一个是独立的配置实用程序。当我的插件检测到事件时,我想向我的实用程序发送一条消息并提示用户重新配置。

我正在使用的代码如下:

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SendMessage(IntPtr hwnd, uint Msg, IntPtr wParam, IntPtr lParam);
private const int MESSAGE_UNAUTH = 0x401;

[... misc logic here, function def, etc]

Process[] processes = Process.GetProcessesByName("MyConfigurationApplication");

if (processes.Length > 0)
{
    foreach (Process p in processes)
    {
        SendMessage(p.MainWindowHandle, MESSAGE_UNAUTH, IntPtr.Zero, IntPtr.Zero);
    }
}

然后在我的接收过程中,我有以下代码(我还在这个类中定义了 MESSAGE_UNAUTH ):

protected override void WndProc(ref Message message)
{
    if (message.Msg == MESSAGE_UNAUTH)
    {
        MessageBox.Show("Message received");
    }
    base.WndProc(ref message);
}

我已经用调试器验证过的事情:

  1. 消息正在发送。Sender 中的所有代码,包括 SendMessage 调用,都在执行。
  2. 没有收到消息(显然)。
  3. 发送消息时根本不会调用 WndProc() 函数。然而,当配置实用程序启动时,它会被调用很多次(我假设这是 Windows 的行为)。

我已经阅读了足够多的在线教程需要滴眼液,据我所知,这里的所有内容都是语法正确且“正确”的,但由于某种原因,在我发送消息和接收者的 WndProc() 应该是之间所谓,黑魔法正在发生。

任何想法将不胜感激。


更新:使用 Marshal.GetLastWin32Error(),我收到错误 #1400,它似乎对应于无效的窗口句柄。但是,我不明白为什么会这样,因为找到了该过程并且我们成功地进入了 for each 循环。我能想到的一个警告是,我的配置实用程序显示为任务栏图标,并且不一定始终具有可见窗口 - 这会阻止 p.MainWindowHandle 有效吗?如果是这样,我该如何解决这个问题以将消息传递给进程而不是窗口?


更新: Process.MainWindowHandle 是 0,所以看起来确实是问题所在 - 当我的配置实用程序中的表单不可见时,即使我的实用程序图标在通知栏中可见,也不会返回有效的窗口处理程序。有什么方法可以向进程发送消息,甚至向任务栏图标发送消息?

4

5 回答 5

1

根据您使用的 .NET 框架,将有助于解决您的问题。在旧的 .NET 框架(我认为是 2.0)中存在一个错误,Process.MainWindowHandle当进程启动时调用返回 0。任何后续调用也将导致 0。这是由于缓存主窗口句柄,这应该是在 .NET 3.0 及更高版本中修复。

您也可以尝试完全信任您WndProc,这可能会有所帮助。就像是:

[System.Security.Permissions.PermissionSet( System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
protected override void WndProc(ref Message m) 
{
    //...
}

附带说明一下,如果您可以更改您的实现,那么我强烈建议您使用更好的进程间通信方式,例如套接字、TCPChannel(我认为它已被 WCF 取代)、命名管道......

于 2012-06-27T22:22:43.257 回答
1

您可以尝试枚举与该进程关联的所有窗口。请参阅如何使用 .NET 枚举属于特定进程的所有窗口?

于 2012-06-27T22:16:00.780 回答
0

在发送方和接收方都使用 Windows Registermessage 将解决问题

于 2012-07-25T10:21:15.647 回答
0

消息可能未发送,可能被阻止。见这里When a message is blocked by UIPI the last error, retrieved with GetLastError, is set to 5 (access denied).

于 2012-06-27T21:45:47.980 回答
0

问题是我发送消息的过程仅作为工具提示图标存在,而不是作为活动的打开窗口存在。原来windows消息功能是为窗口到窗口的消息设计的,而不是进程到进程的消息。

解决方案是前面提到的文件 IO 处理程序的 kludgy 系统。

于 2012-07-30T15:00:56.293 回答