2つのアプリケーション間でメッセージを渡そうとしています。1つはプラグインで、もう1つはスタンドアロンの構成ユーティリティです。プラグインがイベントを検出したら、ユーティリティにメッセージを送信して、ユーザーに再構成を促したいと思います。
私が使用しているコードは次のとおりです。
[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);
}
デバッガーですでに確認したこと:
- メッセージが送信されています。SendMessage呼び出しを含む、Senderのすべてのコードが実行されています。
- メッセージは(明らかに)受信されていません。
- メッセージの送信時にWndProc()関数がまったく呼び出されていません。ただし、構成ユーティリティが起動されると、何度も呼び出されます(これはWindowsの動作だと思います)。
私は点眼薬を必要とするのに十分なオンラインチュートリアルを経験しました、そして私が知る限り、ここのすべては構文が正しく「適切」ですが、何らかの理由で、私がメッセージを送信してから受信者のWndProc()がと呼ばれる、黒魔術が起こっています。
任意のアイデアをいただければ幸いです。
更新:Marshal.GetLastWin32Error()を使用すると、エラー#1400が発生します。これは、無効なウィンドウハンドルに対応しているようです。ただし、プロセスが見つかり、for eachループに正常に入力したため、なぜそうなるのかわかりません。私が考えることができる1つの注意点は、構成ユーティリティがタスクバーアイコンとして表示され、必ずしも常にウィンドウが表示されるとは限らないことです。これにより、p.MainWindowHandleが有効になりませんか?もしそうなら、どうすればこれを回避して、ウィンドウではなくプロセスにメッセージを渡すことができますか?
更新:Process.MainWindowHandleは0なので、実際に問題があるようです。構成ユーティリティのフォームが表示されていない場合、ユーティリティアイコンが通知バーに表示されていても、有効なウィンドウハンドラーは返されません。プロセス、またはタスクバーアイコンにメッセージを送信する方法はありますか?