C#如何通过api获取其他程序listview控件各列的标题

时间:2022-06-01 14:38:10
C#如何通过api获取其他程序listview控件各列的标题?网上搜索到C++的代码,但我不会改写,谁有现成的C#代码发给我一份?
万分感激!

C/C++ code

void GetListViewInfo(HWND h)
{    
    if(h==NULL)
    {
        return;
    }

    //目标进程ID与句柄
    DWORD PID;
    HANDLE hProcess;
    int nBufferLength=50; //缓冲区大小
    
    int nColCount=0;        //列数
    HWND hHeader = (HWND)::SendMessage(h,LVM_GETHEADER, 0,0);//获得标题头句柄
    if(hHeader==NULL)
    {
        return;
    }

    nColCount =(int)::SendMessage(hHeader,HDM_GETITEMCOUNT,0,0);      //获取ListView列数
    if(nColCount<=0)
        return;

    //远程虚拟空间地址
    HDITEM  *pVirtualItem;
    wchar_t *pVirtualBuffer;

    GetWindowThreadProcessId(h,&PID);
    hProcess=OpenProcess(PROCESS_ALL_ACCESS,false,PID);              //获取目标进程句柄失败
    if(!hProcess)
        return;

    //在目标进程地址空间分配内存
    pVirtualItem  =(HDITEM  *)VirtualAllocEx(hProcess, NULL, sizeof(HDITEM) , MEM_COMMIT, PAGE_READWRITE);
    pVirtualBuffer=(wchar_t *)VirtualAllocEx(hProcess, NULL, nBufferLength, MEM_COMMIT, PAGE_READWRITE);
    if ((!pVirtualItem)||(!pVirtualBuffer))
    {
        return;
    }
 
    CString strInfo = L"";
    for(int j=0;j<nColCount;j++)
    {
        wchar_t *buffer  =new wchar_t[nBufferLength];
        wmemset(buffer,0,nBufferLength);

        HDITEM hdItem;

        hdItem.mask=HDI_TEXT;
        hdItem.fmt=0;
        hdItem.cchTextMax=nBufferLength;
        hdItem.pszText=pVirtualBuffer; 
        WriteProcessMemory(hProcess, pVirtualItem, &hdItem, sizeof(HDITEM), NULL);
        ::SendMessage(hHeader, HDM_GETITEM, (WPARAM)j, (LPARAM)(LPHDITEM)pVirtualItem);
        ReadProcessMemory(hProcess, pVirtualBuffer, buffer, nBufferLength,NULL);
        ReadProcessMemory(hProcess,pVirtualItem,(LPVOID)&hdItem,sizeof(HDITEM),NULL); 

        CString strTemp(buffer);

        strInfo+=strTemp+ L" ";
             
        delete []b
}

4 个解决方案

#1


ReadProcessMemory是一种Hack的办法,并不能得到任何担保,它只能在当前的机器上工作。

#2


请问还有其它方法获取其他程序listview控件各列的标题吗?

#3


我尝试修改了一下,但获取不到数据,不知问题在什么地方?


const Int32 HDM_FIRST = 0x1200;
const Int32 HDM_GETITEM = HDM_FIRST + 11;
const uint MEM_COMMIT = 0x1000;
const uint PAGE_READWRITE = 4;
const uint PROCESS_VM_OPERATION = 0x0008;//允许函数VirtualProtectEx使用此句柄修改进程的虚拟内存
const uint PROCESS_VM_READ = 0x0010;//允许函数访问权限
const uint PROCESS_VM_WRITE = 0x0020;//允许函数写入权限

/// <summary>
        /// HDITEM结构体,listview标题的数据结构
        /// 占空间:4(int)x7=28个byte
        /// </summary>
        private struct HDITEM  //listview标题结构体
        {
            public int mask;//说明此结构中哪些成员是有效的
            public int cxy;
            public IntPtr pszText;//主项或子项的名称
            public int cchTextMax;//pszText所指向的缓冲区大小
            public int fmt;//Flags that specify the item's format
            public int state;//子项的状态
            public int lParam;
            public int iImage;
            public int iOrder;
        }
int handle;
string[,] tempStr = null;
            if (handle > 0)
            {
                int hHeader = SendMessage_GETHEADER(handle);//获得标题头句柄
                if (hHeader > 0)
                {
                    cols = ListView_GetItemCols(hHeader);//标题栏列数
                    if (cols > 0)
                    {
                        int dwProcessId;
                        int hProcess;
                        int plvItem;
                        tempStr = new string[1, cols];
                        GetWindowThreadProcessId(handle, out dwProcessId);//获取与指定窗口关联在一起的一个进程和线程标识符
                        hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, false, dwProcessId);//打开一个现有进程的句柄
                        if (hProcess > 0)
                        {
                            #region ""
                            int nBufferLength = 50; //缓冲区大小
                                plvItem = VirtualAllocEx(hProcess, IntPtr.Zero, 4096, MEM_COMMIT, PAGE_READWRITE);//分配内存(uint)Marshal.SizeOf(typeof(HDITEM))
                            if (plvItem > 0)
                            {
                                for (int j = 0; j < cols; j++)
                                {
                                    byte[] vBuffer = new byte[nBufferLength];//256定义一个临时缓冲区
                                    HDITEM[] hdItem = new HDITEM[1];
                                    hdItem[0].mask = HDI_TEXT;//说明pszText是有效的
                                          hdItem[0].fmt = 0;
                                    hdItem[0].cchTextMax = vBuffer.Length;//所能存储的最大的文本为50字节
                                    hdItem[0].pszText = (IntPtr)((int)plvItem + Marshal.SizeOf(typeof(HDITEM)));//


                                    uint vNumberOfBytesRead = 0;
                                    //把数据写到vItem中//plvItem为申请到的内存的首地址//UnsafeAddrOfPinnedArrayElement:获取指定数组中指定索引处的元素的地址
                                    IntPtr lpbf = Marshal.UnsafeAddrOfPinnedArrayElement(hdItem, 0);
                                    WriteProcessMemory(hProcess, plvItem, lpbf, Marshal.SizeOf(typeof(HDITEM)), ref vNumberOfBytesRead);

                                    //发送HDM_GETITEM消息给hwnd,将返回的结果写入pointer指向的内存空间
                                    SendMessage(hHeader, HDM_GETITEM
, j, plvItem);// 
                                    //从plvItem 指向的内存地址开始读取数据,写入缓冲区vBuffer中
                                    ReadProcessMemory(hProcess, ((int)plvItem + Marshal.SizeOf(typeof(HDITEM))), Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0), nBufferLength, ref vNumberOfBytesRead);

                                    string vText = Encoding.Unicode.GetString(vBuffer, 0, (int)vNumberOfBytesRead); ;
                                    tempStr[0, j] = vText;
                                }


                            }
                            #endregion
                            VirtualFreeEx(hProcess, plvItem, 0, MEM_RELEASE);//在其它进程中释放申请的虚拟内存空间,MEM_RELEASE方式很彻底,完全回收
                        }


                        
                        CloseHandle(hProcess);//关闭打开的进程对象
                    }
                }
            }


把表头结构体HDITEM换成LVITEM结构体,能取到列表的数据,不知问题在什么地方?

#4


没人帮忙看看吗?

#1


ReadProcessMemory是一种Hack的办法,并不能得到任何担保,它只能在当前的机器上工作。

#2


请问还有其它方法获取其他程序listview控件各列的标题吗?

#3


我尝试修改了一下,但获取不到数据,不知问题在什么地方?


const Int32 HDM_FIRST = 0x1200;
const Int32 HDM_GETITEM = HDM_FIRST + 11;
const uint MEM_COMMIT = 0x1000;
const uint PAGE_READWRITE = 4;
const uint PROCESS_VM_OPERATION = 0x0008;//允许函数VirtualProtectEx使用此句柄修改进程的虚拟内存
const uint PROCESS_VM_READ = 0x0010;//允许函数访问权限
const uint PROCESS_VM_WRITE = 0x0020;//允许函数写入权限

/// <summary>
        /// HDITEM结构体,listview标题的数据结构
        /// 占空间:4(int)x7=28个byte
        /// </summary>
        private struct HDITEM  //listview标题结构体
        {
            public int mask;//说明此结构中哪些成员是有效的
            public int cxy;
            public IntPtr pszText;//主项或子项的名称
            public int cchTextMax;//pszText所指向的缓冲区大小
            public int fmt;//Flags that specify the item's format
            public int state;//子项的状态
            public int lParam;
            public int iImage;
            public int iOrder;
        }
int handle;
string[,] tempStr = null;
            if (handle > 0)
            {
                int hHeader = SendMessage_GETHEADER(handle);//获得标题头句柄
                if (hHeader > 0)
                {
                    cols = ListView_GetItemCols(hHeader);//标题栏列数
                    if (cols > 0)
                    {
                        int dwProcessId;
                        int hProcess;
                        int plvItem;
                        tempStr = new string[1, cols];
                        GetWindowThreadProcessId(handle, out dwProcessId);//获取与指定窗口关联在一起的一个进程和线程标识符
                        hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, false, dwProcessId);//打开一个现有进程的句柄
                        if (hProcess > 0)
                        {
                            #region ""
                            int nBufferLength = 50; //缓冲区大小
                                plvItem = VirtualAllocEx(hProcess, IntPtr.Zero, 4096, MEM_COMMIT, PAGE_READWRITE);//分配内存(uint)Marshal.SizeOf(typeof(HDITEM))
                            if (plvItem > 0)
                            {
                                for (int j = 0; j < cols; j++)
                                {
                                    byte[] vBuffer = new byte[nBufferLength];//256定义一个临时缓冲区
                                    HDITEM[] hdItem = new HDITEM[1];
                                    hdItem[0].mask = HDI_TEXT;//说明pszText是有效的
                                          hdItem[0].fmt = 0;
                                    hdItem[0].cchTextMax = vBuffer.Length;//所能存储的最大的文本为50字节
                                    hdItem[0].pszText = (IntPtr)((int)plvItem + Marshal.SizeOf(typeof(HDITEM)));//


                                    uint vNumberOfBytesRead = 0;
                                    //把数据写到vItem中//plvItem为申请到的内存的首地址//UnsafeAddrOfPinnedArrayElement:获取指定数组中指定索引处的元素的地址
                                    IntPtr lpbf = Marshal.UnsafeAddrOfPinnedArrayElement(hdItem, 0);
                                    WriteProcessMemory(hProcess, plvItem, lpbf, Marshal.SizeOf(typeof(HDITEM)), ref vNumberOfBytesRead);

                                    //发送HDM_GETITEM消息给hwnd,将返回的结果写入pointer指向的内存空间
                                    SendMessage(hHeader, HDM_GETITEM
, j, plvItem);// 
                                    //从plvItem 指向的内存地址开始读取数据,写入缓冲区vBuffer中
                                    ReadProcessMemory(hProcess, ((int)plvItem + Marshal.SizeOf(typeof(HDITEM))), Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0), nBufferLength, ref vNumberOfBytesRead);

                                    string vText = Encoding.Unicode.GetString(vBuffer, 0, (int)vNumberOfBytesRead); ;
                                    tempStr[0, j] = vText;
                                }


                            }
                            #endregion
                            VirtualFreeEx(hProcess, plvItem, 0, MEM_RELEASE);//在其它进程中释放申请的虚拟内存空间,MEM_RELEASE方式很彻底,完全回收
                        }


                        
                        CloseHandle(hProcess);//关闭打开的进程对象
                    }
                }
            }


把表头结构体HDITEM换成LVITEM结构体,能取到列表的数据,不知问题在什么地方?

#4


没人帮忙看看吗?