none
获取32位外部程序ListView Item失败

    问题

  • 1. win7x64 获取任务管理器没问题
    2. win7x64 & win2003x64 获取32位的程序不行
    3. 获取行数,列数 都没问题
    4. 编译成32位程序没问题, 但编译成anyCPU就有问题

    using System;
    
    using System.Collections.Generic;
    
    using System.ComponentModel;
    
    using System.Drawing;
    
    using System.Text;
    
    using System.Windows.Forms;
    
    using System.Runtime.InteropServices;
    
    
    
    
    
    namespace KillError
    
    {
    
     public partial class frmMain : Form
    
     {
    
      const uint LVM_FIRST = 0x1000;
    
      const uint WM_LBUTTONDBLCLK = 515;
    
      const uint BM_CLICK = 245;
    
      const uint HDM_FIRST = 0x1200;
    
      const uint LVM_GETITEMCOUNT = LVM_FIRST + 4;
    
      const uint LVM_GETITEMW = LVM_FIRST + 75;
    
      const uint LVM_GETHEADER = LVM_FIRST + 31;
    
      const uint HDM_GETITEMCOUNT = HDM_FIRST + 0;
    
      const uint LVM_SETITEMSTATE = LVM_FIRST + 43;
    
      const uint LVIS_SELECTED = 0X02;
    
    
    
    
    
      [DllImport("user32.DLL")]
    
      static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
    
      [DllImport("user32.DLL")]
    
      static extern IntPtr FindWindow(string lpszClass, string lpszWindow);
    
      [DllImport("user32.DLL")]
    
      static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
    
      [DllImport("user32.dll")]
    
      static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint dwProcessId);
    
    
    
      const uint PROCESS_VM_OPERATION = 0x0008;
    
      const uint PROCESS_VM_READ = 0x0010;
    
      const uint PROCESS_VM_WRITE = 0x0020;
    
    
    
      [DllImport("kernel32.dll")]
    
      static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);
    
      const uint MEM_COMMIT = 0x1000;
    
      const uint MEM_RELEASE = 0x8000;
    
    
    
      const uint MEM_RESERVE = 0x2000;
    
      const uint PAGE_READWRITE = 4;
    
    
    
      [DllImport("kernel32.dll")]
    
      static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
    
    
    
      [DllImport("kernel32.dll")]
    
      static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint dwFreeType);
    
    
    
      [DllImport("kernel32.dll")]
    
      static extern bool CloseHandle(IntPtr handle);
    
    
    
      [DllImport("kernel32.dll")]
    
      static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, ref uint vNumberOfBytesRead);
    
    
    
      [DllImport("kernel32.dll")]
    
      static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, ref uint vNumberOfBytesRead);
    
    
    
      public struct LVITEM
    
      {
    
       public int mask;
    
       public int iItem;
    
       public int iSubItem;
    
       public int state;
    
       public int stateMask;
    
       public IntPtr pszText;
    
       public int cchTextMax;
    
       public int iImage;
    
       public IntPtr lParam;
    
       public int iIndent;
    
       public int iGroupId;
    
       public int cColumns;
    
       public IntPtr puColumns;
    
      }
    
    
    
    
    
      int LVIF_TEXT = 0x0001;
    
    
    
      /// <summary>
    
      /// 获取 ListView 的行数
    
      /// </summary>
    
      /// <param name="hwnd"></param>
    
      /// <returns></returns>
    
      int ListView_GetItemCount(IntPtr hwnd)
    
      {
    
       return SendMessage(hwnd, LVM_GETITEMCOUNT, 0, 0);
    
      }
    
    
    
      /// <summary>
    
      /// 获取 ListView 的标题栏句柄
    
      /// </summary>
    
      /// <param name="hwnd"></param>
    
      /// <returns></returns>
    
      private IntPtr ListView_GetHeader(IntPtr hwnd)
    
      {
    
       return (IntPtr)SendMessage(hwnd, LVM_GETHEADER, 0, 0);
    
      }
    
    
    
      /// <summary>
    
      /// 获取 ListView 的标题栏的列数
    
      /// </summary>
    
      /// <param name="header"></param>
    
      /// <returns></returns>
    
      private int Header_GetItemCount(IntPtr header)
    
      {
    
       return SendMessage(header, HDM_GETITEMCOUNT, 0, 0);
    
      }
    
    
    
      /// <summary>
    
      /// 获取 ListView 的列数
    
      /// </summary>
    
      /// <param name="listViewHandle"></param>
    
      /// <returns></returns>
    
      int ListViewColumnCount(IntPtr listViewHandle)
    
      {
    
       return Header_GetItemCount(ListView_GetHeader(listViewHandle));
    
      }
    
    
    
      public frmMain()
    
      {
    
       InitializeComponent();
    
      }
    
    
    
      private void frmMain_Load(object sender, EventArgs e)
    
      {
    
       IntPtr hwndDH = FindWindow("TMainForm", null);
    
       if (hwndDH == IntPtr.Zero)
    
       {
    
        MessageBox.Show("没有开启DH!");
    
        return;
    
       }
    
    
    
       //IntPtr hwndProcesses = FindWindowEx(hwndTaskManager, IntPtr.Zero, null, "Processes");
    
       //IntPtr hwndProcesses = FindWindowEx(hwndDH, IntPtr.Zero, "TListView", null);
    
       //if (hwndProcesses == IntPtr.Zero)
    
       //{
    
       // MessageBox.Show("未能获取到 进程 列表的句柄");
    
       // return;
    
       //}
    
    
    
       //对于 delphi, bcb开发的程序,listview的classname是 TListView
    
       IntPtr hwndListView = FindWindowEx(hwndDH, IntPtr.Zero, "TListView", null);
    
       if (hwndListView == IntPtr.Zero)
    
       {
    
        MessageBox.Show("未能获取到ListView的句柄");
    
        return;
    
       }
    
    
    
       int vColumnCount = ListViewColumnCount(hwndListView);
    
       if (vColumnCount <= 0)
    
       {
    
        MessageBox.Show("没有获取到进程列数据");
    
        return;
    
       }
    
    
    
       int vItemCount = ListView_GetItemCount(hwndListView);
    
       if (vItemCount <= 0)
    
       {
    
        MessageBox.Show("没有获取到进程行数据");
    
        return;
    
       }
    
    
    
       uint vProcessId;
    
       GetWindowThreadProcessId(hwndListView, out vProcessId);
    
    
    
       IntPtr vProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, false, vProcessId);
    
       IntPtr vPointer = VirtualAllocEx(vProcess, IntPtr.Zero, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
    
       try
    
       {
    
        //listBox1.Items.Clear();
    
    
    
        for (int i = 0; i < vItemCount; i++)
    
        {
    
         string s = string.Empty;
    
    
    
         for (int j = 0; j < vColumnCount; j++)
    
         {
    
          byte[] vBuffer = new byte[256];
    
          LVITEM[] vItem = new LVITEM[1];
    
          vItem[0].mask = LVIF_TEXT;
    
          vItem[0].iItem = i;
    
          vItem[0].iSubItem = j;
    
          vItem[0].cchTextMax = vBuffer.Length;
    
          vItem[0].pszText = (IntPtr)((int)vPointer + Marshal.SizeOf(typeof(LVITEM)));
    
          uint vNumberOfBytesRead = 0;
    
    
    
          //  static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, ref uint vNumberOfBytesRead);
    
          //  static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, ref uint vNumberOfBytesRead);
    
    
    
          bool wpm = WriteProcessMemory(
    
           vProcess,
    
           vPointer,
    
           Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0),
    
           Marshal.SizeOf(typeof(LVITEM)),
    
           ref vNumberOfBytesRead
    
           );
    
    
    
          SendMessage(hwndListView, LVM_GETITEMW, 0, vPointer.ToInt32());
    
          //Message msg = Message.Create(hwndListView, Convert.ToInt32(LVM_GETITEMW), IntPtr.Zero, vPointer);
    
          
    
    
    
          bool rpm = ReadProcessMemory(
    
           vProcess,
    
           (IntPtr)((int)vPointer + Marshal.SizeOf(typeof(LVITEM))),
    
           Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0),
    
           vBuffer.Length,
    
           ref vNumberOfBytesRead
    
           );
    
    
    
          string vText = Marshal.PtrToStringUni(Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0));
    
    
    
          //s += vText + "\t";
    
          MessageBox.Show(vText);
    
         }
    
    
    
         //listBox1.Items.Add(s);
    
    
    
        }
    
       }
    
       catch (Exception ex)
    
       {
    
        MessageBox.Show(ex.Message);
    
       }
    
       finally
    
       {
    
        VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE);
    
        CloseHandle(vProcess);
    
       }
    
    
    
      }
    
     }
    
    }
    
    
    
    

    虚幻的美丽, 飘渺亦永恒。
    2010年5月4日 19:47

答案

  • 64位程序中不能调用32位的API或者任何其它32位的代码。

    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful.
    Visual C++ MVP
    2010年5月5日 19:54
    版主