3

私は一晩中これと戦ってきました。何が悪いのかさっぱりわかりません。デスクトップ アイコン + キャプション サイズを取得しようとしています。デスクトップ ハンドルを見つけて SysListView32_hwnd という変数に入れる関数がいくつかあります。Windowsスパイプログラムで正しいことを確認しました。ここが私が悩んでいる部分です。

Rectangle rct = new Rectangle();
IntPtr pRct = Marshal.AllocHGlobal(Marshal.SizeOf(rct));
Marshal.StructureToPtr(rct, pRct, true);

SendMessage(SysListView32_hwnd, LVM_GETITEMRECT, (IntPtr)0, pRct);

Rectangle Rect = (Rectangle)Marshal.PtrToStructure(pRct, typeof(Rectangle));
Marshal.FreeHGlobal(pRct);
Debug.WriteLine(Rect.Height + "    " + Rect.Width);

毎回エクスプローラーがクラッシュします。C# Visual Studio 2010 Windows 7 x64 で、64 ビット プログラムとしてコンパイルしています

必要に応じて、ここに私の完全なアプリがあります

4

2 に答える 2

2

これは、質問の広範な編集で尋ねられる追加の質問に対処します。

作業しているように見えますLVITEMsが、をVirtualAllocEx指定しますsizeof(uint)

MSDNのdwSizeパラメータのドキュメントには、次のように記載されています。VirtualAllocEx()

割り当てるメモリ領域のサイズ(バイト単位)。

lpAddressがNULLの場合、関数はdwSizeを次のページ境界に切り上げます。

lpAddressがNULLでない場合、関数はlpAddressからlpAddress+dwSizeまでの範囲の1つ以上のバイトを含むすべてのページを割り当てます。これは、たとえば、ページ境界にまたがる2バイトの範囲により、関数が両方のページを割り当てることを意味します。

つまり、ページ全体を割り当てます。1ページが4KBなので、運がいいです。dwSize必要なバッファに対して十分な大きさであることを確認する必要があります。

pszText =(IntPtr)((int)lpBaseAddress + Marshal.SizeOf(typeof(LVITEM)))なのはなぜですか?それは単に構造の終わりを指しているのではないでしょうか。

はい、それは構造の終わりを指しています。ポイントは、のpszTextフィールドがLVITEM呼び出し元によって割り当てられたバッファーを指している必要があるということです。このコードを書いた人は誰でも、構造体の最後に予備のバッファースペースを使用することを選択しました。構造体は256バイトを含むと宣言しているのでpszText、4KBページの残りの部分に簡単に収まります。だからそれは動作しますが、それは少し不透明です。

于 2011-09-17T07:16:25.210 に答える
1

これは、広範な編集の前の元の質問に対処します。

あなたが書いた方法は、ターゲットウィンドウハンドルを所有するプロセスから呼び出す場合にのみ機能するため、失敗します。これは、ポインターを渡すためですが、それはプロセスでのみ有効です。他のプロセスに到達するとすぐに、意味のないアドレスを参照します。そして、それが何らかの意味を持っていたとしても、プロセスはシステムの助けを借りて別のプロセスのメモリを読み取ることはできません。当然探索爆弾。

VirtualAllocEx()解決策は、エクスプローラ プロセスでメモリを割り当てるために使用することです。次に、メッセージを送信します。次にReadProcessMemory()、Rect の内容をプロセスにマーシャリングするために使用します。これについて最もよく引用されるコード サンプルは、このCode Project articleです。その例は使用してLVM_GETITEMTEXTいますが、原則は同じです。

于 2011-09-16T16:55:08.883 に答える