[译]c# 获取桌面图标的位置和名称

在外国一个博客中看到的  转载过来  翻译了一下  并封装在一个类中  

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 查看评论
原文地址:https://www.cnblogs.com/SpeakHero/p/2431311.html