2

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);
}

デバッガーですでに確認したこと:

  1. メッセージが送信されています。SendMessage呼び出しを含む、Senderのすべてのコードが実行されています。
  2. メッセージは(明らかに)受信されていません。
  3. メッセージの送信時にWndProc()関数がまったく呼び出されていません。ただし、構成ユーティリティが起動されると、何度も呼び出されます(これはWindowsの動作だと思います)。

私は点眼薬を必要とするのに十分なオンラインチュートリアルを経験しました、そして私が知る限り、ここのすべては構文が正しく「適切」ですが、何らかの理由で、私がメッセージを送信してから受信者のWndProc()がと呼ばれる、黒魔術が起こっています。

任意のアイデアをいただければ幸いです。


更新:Marshal.GetLastWin32Error()を使用すると、エラー#1400が発生します。これは、無効なウィンドウハンドルに対応しているようです。ただし、プロセスが見つかり、for eachループに正常に入力したため、なぜそうなるのかわかりません。私が考えることができる1つの注意点は、構成ユーティリティがタスクバーアイコンとして表示され、必ずしも常にウィンドウが表示されるとは限らないことです。これにより、p.MainWindowHandleが有効になりませんか?もしそうなら、どうすればこれを回避して、ウィンドウではなくプロセスにメッセージを渡すことができますか?


更新:Process.MainWindowHandleは0なので、実際に問題があるようです。構成ユーティリティのフォームが表示されていない場合、ユーティリティアイコンが通知バーに表示されていても、有効なウィンドウハンドラーは返されません。プロセス、またはタスクバーアイコンにメッセージを送信する方法はありますか?

4

5 に答える 5

1

プロセスに関連付けられているすべてのウィンドウを列挙してみることができます。.NETを使用して特定のプロセスに属するすべてのウィンドウを列挙する方法を参照してください。

于 2012-06-27T22:16:00.780 に答える
1

使用している.NETFrameworkによっては、これは問題の解決に役立ちます。古い.NETFramework(2.0だと思います)にProcess.MainWindowHandleは、プロセスの起動時に呼び出すと0が返されるというバグがありました。それ以降の呼び出しも0になります。これは、メインウィンドウハンドルをキャッシュするためです。 .NET3.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 に答える
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

送信側と受信側の両方でWindowsRegistermessageを使用すると、問題が解決します

于 2012-07-25T10:21:15.647 に答える
0

問題は、メッセージを送信するプロセスがツールチップアイコンとしてのみ存在し、アクティブな開いているウィンドウとしては存在しないことでした。Windowsメッセージ機能は、プロセス間メッセージではなく、ウィンドウ間メッセージ用に設計されていることがわかりました。

解決策は、前述のファイルIOハンドラーの厄介なシステムでした。

于 2012-07-30T15:00:56.293 に答える