SendMessage消失在以太网中

时间:2012-06-27 21:40:35

标签: c# .net winforms winapi

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

我正在使用的代码如下:

[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. 邮件已发送。发件人中的所有代码,包括SendMessage调用,都在执行。
  2. 收到的消息(显然)。
  3. 发送邮件时,根本不会调用WndProc()函数。但是,当配置实用程序启动时,它会被调用一大堆(我假设这是Windows的行为)。
  4. 我已经经历了足够的在线教程需要滴眼液,据我所知,这里的一切都是语法正确和“正确的”,但出于某种原因,在我发送消息和接收者的WndProc之间(应该被称为,黑魔法正在发生。

    非常感谢任何想法。


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


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

5 个答案:

答案 0 :(得分:1)

您可以尝试枚举与该进程关联的所有窗口。见How to enumerate all windows belonging to a particular process using .NET?

答案 1 :(得分:1)

根据您使用的.NET框架,this将有助于解决您的问题。 旧的.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取代),命名管道......

答案 2 :(得分:0)

邮件可能未被发送,可能会被阻止。请参阅hereWhen a message is blocked by UIPI the last error, retrieved with GetLastError, is set to 5 (access denied).

答案 3 :(得分:0)

在发件人和收件人端使用Windows注册邮件将解决问题

答案 4 :(得分:0)

问题是我发送消息的过程只是作为工具提示图标而不是作为活动的打开窗口存在。结果是Windows消息功能是为窗口到窗口的消息而设计的,而不是针对进程到进程的消息。

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