2

C ++アプリケーションにメッセージを送信する必要があるC#のアプリケーションを使用しています。

インポートしました

[DllImport("user32.dll")]
        public static extern IntPtr SendMessage(
              int hWnd,      // handle to destination window
              uint Msg,       // message
              IntPtr wParam,  // first message parameter
              IntPtr lParam   // second message parameter
              );

しかし今、私の問題は、文字列をwParamとlParamに渡す必要があることです。安全でないコードを試しましたが、文字列が他の変数のように機能しないようです。どうすればそれを達成できますか?ありがとう。

4

3 に答える 3

11

宣言が間違っています。wParam および lParam 引数は IntPtr であり、長くはありません。

文字列を送信しようとしているため、複雑です。ターゲット ウィンドウが Unicode 対応かどうかは重要です。SendMessage には、SendMessageA() と SendMessageW() の 2 つのバージョンがあります。プログラムが古く、UTF-16 でエンコードされた文字列ではなく 8 ビットの文字列を使用している場合は、前者を使用する必要があります。

Spy++ を使用して調べることができます。ファインダ ツールを使用して、アプリケーションのウィンドウを選択します。[全般] プロパティ タブに、「ウィンドウ プロシージャ」が表示されます。ウィンドウが Unicode 対応の場合、(Unicode) と表示されます。表示されない場合は、文字列を 8 ビット文字に変換する必要があります。

渡す必要がある文字列ポインターを生成するには、Marshal.StringToHGlobalAnsi または StringToHGlobalUni (それぞれ 8 ビットおよび Unicode) を使用できます。ただし、P/Invoke マーシャラーに文字列を変換させるトリックを実行できます。呼び出し後に文字列を解放する手間が省けます。Ansi バージョンでは、次のように API 関数を宣言できます。

    [DllImport("user32.dll", CharSet = CharSet.Ansi, EntryPoint = "SendMessageA", ExactSpelling = true)]
    private static extern IntPtr SendMessageStrings(IntPtr hWnd, int msg, string wParam, string lParam);

そして、このようなUnicodeバージョン:

    [DllImport("user32.dll", CharSet = CharSet.Unicode, EntryPoint = "SendMessageW", ExactSpelling = true)]
    private static extern IntPtr SendMessageStrings(IntPtr hWnd, int msg, string wParam, string lParam);

最後の注意: ウィンドウが別のアプリケーションに属している場合、これはそのままでは機能せず、クラッシュします。渡すポインター値は、C++ プロセスではなく、独自のプロセスでのみ有効です。これを回避するには、ポインタが有効になるようにターゲット プロセスにメモリを割り当てる必要があります。そのためには、プロセスへのハンドルを取得する OpenProcess、文字列を格納するのに十分な大きさのメモリをターゲット プロセスに割り当てる VirtualAllocEx()、文字列を書き込む WriteProcessMemory が必要です。これで、SendMessage() を呼び出し、wParam および lParam 引数に IntPtr で宣言されたバージョンを使用し、VirtualAllocEx から取得した値を渡すことができます。次に、VirtualFreeEx() を使用してメモリを解放し、CloseHandle を使用してクリーンアップします。または、これを頻繁に行う場合は、次回のために記憶を保持してください。

P/Invoke が非常に多く、間違っています。セキュリティの問題は言うまでもなく、WriteProcessMemory には管理者権限が必要であり、UAC の昇格が必要です。

于 2010-06-22T15:42:47.350 に答える
0

Win32 API 呼び出しは (C/C++ ネイティブ環境で) アドレスを想定しているため、文字列のアドレスを渡すと安全でないコードが含まれます。wParam または lParam に文字列を必要とする、どのような Windows メッセージを送信していますか?

于 2010-06-22T15:13:15.843 に答える
-2

最終的には「WmCpyDta_d.dll」を使用してすべてを処理しました。

于 2010-06-25T14:49:16.450 に答える