using System;
using System.Runtime.InteropServices;
using System.Text;
namespace Program
{
class Program
{
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hwnd, out uint processId);
[DllImport("user32.dll", SetLastError = true)]
static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, IntPtr lParam);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr OpenProcess(uint processAccess, bool bInheritHandle, int processId);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int dwSize, out int lpNumberOfBytesRead);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int dwSize, out int lpNumberOfBytesWritten);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, uint dwFreeType);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CloseHandle(IntPtr hObject);
const uint PROCESS_VM_OPERATION = 0x0008;
const uint PROCESS_VM_READ = 0x0010;
const uint PROCESS_VM_WRITE = 0x0020;
const uint MEM_COMMIT = 0x1000;
const uint MEM_RELEASE = 0x8000;
const uint PAGE_READWRITE = 0x04;
const uint LVIF_TEXT = 1;
const uint LVM_FIRST = 0x1000;
const uint LVM_GETITEMCOUNT = 0x1004;
const uint LVM_GETITEMTEXT = LVM_FIRST + 115;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct LVITEM
{
public uint mask;
public int iItem;
public int iSubItem;
public uint state;
public uint stateMask;
public IntPtr pszText;
public int cchTextMax;
public int iImage;
public IntPtr lParam;
public int iIndent;
public int iGroupId;
public uint cColumns;
public IntPtr puColumns;
public IntPtr piColFmt;
public int iGroup;
}
static string GetListViewItemText(IntPtr hWndListView, int itemIndex, int subItemIndex)
{
GetWindowThreadProcessId(hWndListView, out uint processId);
IntPtr hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, false, (int)processId);
if (hProcess == IntPtr.Zero)
{
Console.WriteLine("无法打开目标进程");
return string.Empty;
}
int textBufferSize = 4096;
int totalSize = Marshal.SizeOf(typeof(LVITEM)) + textBufferSize;
IntPtr memory = VirtualAllocEx(hProcess, IntPtr.Zero, totalSize, MEM_COMMIT, PAGE_READWRITE);
if (memory == IntPtr.Zero)
{
Console.WriteLine("无法分配内存");
CloseHandle(hProcess);
return string.Empty;
}
IntPtr textMemory = IntPtr.Add(memory, Marshal.SizeOf(typeof(LVITEM)));
LVITEM lvItem = new LVITEM
{
mask = LVIF_TEXT,
iItem = itemIndex,
iSubItem = subItemIndex,
pszText = textMemory,
cchTextMax = textBufferSize / 2
};
byte[] lvItemBytes = StructureToByteArray(lvItem);
if (!WriteProcessMemory(hProcess, memory, lvItemBytes, lvItemBytes.Length, out _))
{
Console.WriteLine("写入内存失败");
VirtualFreeEx(hProcess, memory, 0, MEM_RELEASE);
CloseHandle(hProcess);
return string.Empty;
}
SendMessage(hWndListView, LVM_GETITEMTEXT, itemIndex, memory);
byte[] buffer = new byte[textBufferSize];
if (!ReadProcessMemory(hProcess, textMemory, buffer, buffer.Length, out _))
{
Console.WriteLine("读取内存失败");
VirtualFreeEx(hProcess, memory, 0, MEM_RELEASE);
CloseHandle(hProcess);
return string.Empty;
}
string itemText = Encoding.Unicode.GetString(buffer).TrimEnd('\0');
VirtualFreeEx(hProcess, memory, 0, MEM_RELEASE);
CloseHandle(hProcess);
return itemText;
}
static void Main(string[] args)
{
IntPtr hWnd = FindWindow(null, "ListView示例");
if (hWnd == IntPtr.Zero)
{
Console.WriteLine("未找到目标窗口.");
return;
}
IntPtr hWndListView = FindWindowEx(hWnd, IntPtr.Zero, "SysListView32", null);
if (hWndListView == IntPtr.Zero)
{
Console.WriteLine("未找到ListView.");
return;
}
int itemCount = SendMessage(hWndListView, LVM_GETITEMCOUNT, 0, (IntPtr)0);
Console.WriteLine("Item count: " + itemCount);
for (int i = 0; i < itemCount; i++)
{
string sztext = GetListViewItemText(hWndListView, i, 0);
Console.WriteLine(sztext);
}
}
static byte[] StructureToByteArray(object obj)
{
int len = Marshal.SizeOf(obj);
byte[] arr = new byte[len];
IntPtr ptr = Marshal.AllocHGlobal(len);
Marshal.StructureToPtr(obj, ptr, true);
Marshal.Copy(ptr, arr, 0, len);
Marshal.FreeHGlobal(ptr);
return arr;
}
}
}