在外国一个博客中看到的 转载过来 翻译了一下 并封装在一个类中
using System; namespace System.Windows.Forms { /// <summary> /// 获得桌面图标名称和位置 /// </summary> class GetIcoPointName { #region Api声明 private const uint LVM_FIRST = 0x1000; private const uint LVM_GETITEMCOUNT = LVM_FIRST + 4; private const uint LVM_GETITEMW = LVM_FIRST + 75; private const uint LVM_GETITEMPOSITION = LVM_FIRST + 16; [System.Runtime.InteropServices.DllImport("user32.DLL")] private static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam); [System.Runtime.InteropServices.DllImport("user32.DLL")] private static extern IntPtr FindWindow(string lpszClass, string lpszWindow); [System.Runtime.InteropServices.DllImport("user32.DLL")] private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint dwProcessId); private const uint PROCESS_VM_OPERATION = 0x0008; private const uint PROCESS_VM_READ = 0x0010; private const uint PROCESS_VM_WRITE = 0x0020; [System.Runtime.InteropServices.DllImport("kernel32.dll")] private static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId); private const uint MEM_COMMIT = 0x1000; private const uint MEM_RELEASE = 0x8000; private const uint MEM_RESERVE = 0x2000; private const uint PAGE_READWRITE = 4; [System.Runtime.InteropServices.DllImport("kernel32.dll")] private static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); [System.Runtime.InteropServices.DllImport("kernel32.dll")] private static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint dwFreeType); [System.Runtime.InteropServices.DllImport("kernel32.dll")] private static extern bool CloseHandle(IntPtr handle); [System.Runtime.InteropServices.DllImport("kernel32.dll")] private static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, ref uint vNumberOfBytesRead); [System.Runtime.InteropServices.DllImport("kernel32.dll")] private static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, ref uint vNumberOfBytesRead); private struct LVITEM //结构体 { public int mask; public int iItem; public int iSubItem; public int state; public int stateMask; public IntPtr pszText; // string public int cchTextMax; public int iImage; public IntPtr lParam; public int iIndent; public int iGroupId; public int cColumns; public IntPtr puColumns; } private int LVIF_TEXT = 0x0001; /// <summary> /// 节点个数,通过SendMessage 发送获取 /// </summary> /// <param name="AHandle"></param> /// <returns></returns> private int ListView_GetItemCount(IntPtr AHandle) { return SendMessage(AHandle, LVM_GETITEMCOUNT, 0, 0); } /// <summary> /// 图标位置 /// </summary> /// <param name="AHandle"></param> /// <param name="AIndex"></param> /// <param name="APoint"></param> /// <returns></returns> private bool ListView_GetItemPosition(IntPtr AHandle, int AIndex, IntPtr APoint) { return SendMessage(AHandle, LVM_GETITEMPOSITION, AIndex, APoint.ToInt32()) != 0; } #endregion public string GetSysVer() { string Ver = Environment.OSVersion.Version.ToString(); return Ver; } /// <summary> /// 获取桌面项目的名称 /// </summary> /// <returns></returns> public string[] GetIcoName() { //桌面上SysListView32的窗口句柄 IntPtr vHandle; //xp是Progman ; win7 网上说应该是 "WorkerW" 但是 spy++ 没找到 程序也不正常 vHandle = FindWindow("Progman", null); vHandle = FindWindowEx(vHandle, IntPtr.Zero, "SHELLDLL_DefView", null); vHandle = FindWindowEx(vHandle, IntPtr.Zero, "SysListView32", null); int vItemCount = ListView_GetItemCount(vHandle);//个数 uint vProcessId; //进程 pid GetWindowThreadProcessId(vHandle, 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); string[] tempStr = new string[vItemCount]; try { for (int i = 0; i < vItemCount; i++) { byte[] vBuffer = new byte[256]; LVITEM[] vItem = new LVITEM[1]; vItem[0].mask = LVIF_TEXT; vItem[0].iItem = i; vItem[0].iSubItem = 0; vItem[0].cchTextMax = vBuffer.Length; vItem[0].pszText = (IntPtr)((int)vPointer + System.Runtime.InteropServices.Marshal.SizeOf(typeof(LVITEM))); uint vNumberOfBytesRead = 0; /// 分配内存空间 WriteProcessMemory(vProcess, vPointer, System.Runtime.InteropServices.Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0), System.Runtime.InteropServices.Marshal.SizeOf(typeof(LVITEM)), ref vNumberOfBytesRead); //发送信息 获取响应 SendMessage(vHandle, LVM_GETITEMW, i, vPointer.ToInt32()); ReadProcessMemory(vProcess, (IntPtr)((int)vPointer + System.Runtime.InteropServices.Marshal.SizeOf(typeof(LVITEM))), System.Runtime.InteropServices.Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0), vBuffer.Length, ref vNumberOfBytesRead); string vText = System.Text.Encoding.Unicode.GetString(vBuffer, 0, (int)vNumberOfBytesRead).TrimEnd('\0'); tempStr[i] = vText; } } catch (Exception Ex) { throw Ex; } finally { VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE); CloseHandle(vProcess); } return tempStr; } public System.Drawing.Point GetIcoPoint(string icoName) { //桌面上SysListView32的窗口句柄 IntPtr vHandle; //xp是Progman ; win7 网上说应该是 "WorkerW" 但是 spy++ 没找到 程序也不正常 vHandle = FindWindow("Progman", null); vHandle = FindWindowEx(vHandle, IntPtr.Zero, "SHELLDLL_DefView", null); vHandle = FindWindowEx(vHandle, IntPtr.Zero, "SysListView32", null); int vItemCount = ListView_GetItemCount(vHandle);//个数 uint vProcessId; //进程 pid GetWindowThreadProcessId(vHandle, 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); System.Drawing.Point[] vPoint = new System.Drawing.Point[1]; try { for (int i = 0; i < vItemCount; i++) { byte[] vBuffer = new byte[256]; LVITEM[] vItem = new LVITEM[1]; vItem[0].mask = LVIF_TEXT; vItem[0].iItem = i; vItem[0].iSubItem = 0; vItem[0].cchTextMax = vBuffer.Length; vItem[0].pszText = (IntPtr)((int)vPointer + System.Runtime.InteropServices.Marshal.SizeOf(typeof(LVITEM))); uint vNumberOfBytesRead = 0; /// 分配内存空间 WriteProcessMemory(vProcess, vPointer, System.Runtime.InteropServices.Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0), System.Runtime.InteropServices.Marshal.SizeOf(typeof(LVITEM)), ref vNumberOfBytesRead); //发送信息 获取响应 SendMessage(vHandle, LVM_GETITEMW, i, vPointer.ToInt32()); ReadProcessMemory(vProcess, (IntPtr)((int)vPointer + System.Runtime.InteropServices.Marshal.SizeOf(typeof(LVITEM))), System.Runtime.InteropServices.Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0), vBuffer.Length, ref vNumberOfBytesRead); string vText = System.Text.Encoding.Unicode.GetString(vBuffer, 0, (int)vNumberOfBytesRead).TrimEnd('\0'); if (vText == icoName) { ListView_GetItemPosition(vHandle, i, vPointer); ReadProcessMemory(vProcess, vPointer, System.Runtime.InteropServices.Marshal.UnsafeAddrOfPinnedArrayElement(vPoint, 0), System.Runtime.InteropServices.Marshal.SizeOf(typeof(System.Drawing.Point)), ref vNumberOfBytesRead); } } } catch (Exception Ex) { throw Ex; } finally { VirtualFreeEx(vProcess, vPointer, 0, MEM_RELEASE); CloseHandle(vProcess); } return vPoint[0]; } } }
使用例子:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Management; using Shell32; namespace 获得桌面图标名称和位置 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } [DllImport("user32.dll", EntryPoint = "IsWindow")] public static extern bool IsWindow(IntPtr hWnd); GetIcoPointName getPn = new GetIcoPointName(); private void button1_Click(object sender, EventArgs e) { foreach (var i in getPn.GetIcoName()) { textBox1.Text = textBox1.Text+i; } ShwoDesk(); } /// <summary> /// 显示桌面 /// </summary> private void ShwoDesk() { Type shellType = Type.GetTypeFromProgID("Shell.Application"); object shellObject = System.Activator.CreateInstance(shellType); shellType.InvokeMember("ToggleDesktop", System.Reflection.BindingFlags.InvokeMethod, null, shellObject, null); } private void Form1_Click(object sender, EventArgs e) { } private void button2_Click(object sender, EventArgs e) { textBox2.Text = getPn.GetIcoPoint("计算机").ToString(); } private void Form1_Load(object sender, EventArgs e) { } private void Form1_Paint(object sender, PaintEventArgs e) { } } }
作者:qq283868910 发表于2011-12-5 21:26:17 原文链接
阅读:122 评论:0 查看评论