欧美成人精品手机在线观看_69视频国产_动漫精品第一页_日韩中文字幕网 - 日本欧美一区二区

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

C#如何獲取其他程序窗口列表ListView控件中的內容

admin
2023年12月29日 23:1 本文熱度 858

需求:獲取其他程序中的ListView控件的文本內容

原理進程之間是相互隔離的,數據是不能共享的(有些特例)

   LVM_GETTITEMTEXT:將一個數據緩沖區提供給listview32控件,你不能把你的進程的數據緩沖提供給另外的程序,所以要用openprocess 打開“任務管理器”進程,然后在“任務管理器進程”中申請足夠長度的內存(VirualAllocEx),將這個內存地址提供給listview32,使用 sendmessage 發送LVM_GETTITEMTEXT消息,待sendmessage返回后,用readprocessmemory 讀取這段內存的數據,即listview控件的文本內容。

API函數

  • FindWindow                    //查找窗口

  • FindWindowEx                    ////在窗口列表中尋找與指定條件相符的第一個子窗口

  • SendMessage

  • GetWindowThreadProcessId//找出某個窗口的創建者(線程或進程),返回創建者的標志符

  • OpenProcess          //打開一個已存在的進程對象,并返回進程的句柄

  • VirtualAllocEx                    //為指定的進程分配內存地址:成功則返回分配內存的首地址

  • ReadProcessMemory          //從指定內存中讀取字節集數據

  • WriteProcessMemory         //將數據寫入內存中

  • CloseHandle

  • VirtualFreeEx                   //在其它進程中釋放申請的虛擬內存空間

 程序演示代碼

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

using System.Runtime.InteropServices;

namespace 讀取其他軟件listview控件的內容

{

    public partial class Form1 : Form

    {

        int hwnd;   //窗口句柄

        int process;//進程句柄

        int pointer;

        private const uint LVM_FIRST = 0x1000;

        private const uint LVM_GETHEADER = LVM_FIRST + 31;

        private const uint LVM_GETITEMCOUNT = LVM_FIRST + 4;//獲取列表行數

        private const uint LVM_GETITEMTEXT = LVM_FIRST + 45;//獲取列表內的內容

        private const uint LVM_GETITEMW = LVM_FIRST + 75;

 

        private const uint HDM_GETITEMCOUNT = 0x1200;//獲取列表列數

 

        private const uint PROCESS_VM_OPERATION = 0x0008;//允許函數VirtualProtectEx使用此句柄修改進程的虛擬內存

        private const uint PROCESS_VM_READ = 0x0010;//允許函數訪問權限

        private const uint PROCESS_VM_WRITE = 0x0020;//允許函數寫入權限

 

        private const uint MEM_COMMIT = 0x1000;//為特定的頁面區域分配內存中或磁盤的頁面文件中的物理存儲

        private const uint MEM_RELEASE = 0x8000;

        private const uint MEM_RESERVE = 0x2000;//保留進程的虛擬地址空間,而不分配任何物理存儲

 

        private const uint PAGE_READWRITE = 4;

 

        private int LVIF_TEXT = 0x0001

 

        [DllImport("user32.dll")]//查找窗口

        private static extern int FindWindow(

                                            string strClassName,    //窗口類名

                                            string strWindowName    //窗口標題

        );

       

        [DllImport("user32.dll")]//在窗口列表中尋找與指定條件相符的第一個子窗口

        private static extern int FindWindowEx(

                                              int hwndParent, // handle to parent window

                                            int hwndChildAfter, // handle to child window

                                              string className, //窗口類名           

                                              string windowName // 窗口標題

        );

        [DllImport("user32.DLL")]

        private static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);

        [DllImport("user32.dll")]//找出某個窗口的創建者(線程或進程),返回創建者的標志符

        private static extern int GetWindowThreadProcessId(int hwnd,out int processId);

        [DllImport("kernel32.dll")]//打開一個已存在的進程對象,并返回進程的句柄

        private static extern int OpenProcess(uint dwDesiredAccess, bool bInheritHandle,int processId);

        [DllImport("kernel32.dll")]//為指定的進程分配內存地址:成功則返回分配內存的首地址

        private static extern int VirtualAllocEx(int hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);

        [DllImport("kernel32.dll")]//從指定內存中讀取字節集數據

        private static extern bool ReadProcessMemory(

                                            int hProcess, //被讀取者的進程句柄

                                            int lpBaseAddress,//開始讀取的內存地址

                                            IntPtr lpBuffer, //數據存儲變量

                                            int nSize, //要寫入多少字節

                                            ref uint vNumberOfBytesRead//讀取長度

        );

        [DllImport("kernel32.dll")]//將數據寫入內存中

        private static extern bool WriteProcessMemory(

                                            int hProcess,//OpenProcess返回的進程句柄

                                            int lpBaseAddress, //要寫的內存首地址,再寫入之前,此函數將先檢查目標地址是否可用,并能容納待寫入的數據

                                            IntPtr lpBuffer, //指向要寫的數據的指針

                                            int nSize, //要寫入的字節數

                                            ref uint vNumberOfBytesRead

        );

        [DllImport("kernel32.dll")]

        private static extern bool CloseHandle(int handle);

        [DllImport("kernel32.dll")]//在其它進程中釋放申請的虛擬內存空間

        private static extern bool VirtualFreeEx(

                                    int hProcess,//目標進程的句柄,該句柄必須擁有PROCESS_VM_OPERATION的權限

                                    int lpAddress,//指向要釋放的虛擬內存空間首地址的指針

                                    uint dwSize,

                                    uint dwFreeType//釋放類型

        );

        /// <summary>

        /// LVITEM結構體,是列表視圖控件的一個重要的數據結構

        /// 占空間:4(int)x7=28byte

        /// </summary>

        private struct LVITEM  //結構體

        {

            public int mask;//說明此結構中哪些成員是有效的

            public int iItem;//項目的索引值(可以視為行號)0開始

            public int iSubItem; //子項的索引值(可以視為列號)0開始

            public int state;//子項的狀態

            public int stateMask; //狀態有效的屏蔽位

            public IntPtr pszText;  //主項或子項的名稱

            public int cchTextMax;//pszText所指向的緩沖區大小

        }

 

        public Form1()

        {

            InitializeComponent();

        }

 

        /// <summary> 

        /// LV列表總行數

        /// </summary>

        private int ListView_GetItemRows(int handle)

        {

            return SendMessage(handle,LVM_GETITEMCOUNT,0,0);

        }

        /// <summary> 

        /// LV列表總列數

        /// </summary>

        private int ListView_GetItemCols(int handle)

        {

            return SendMessage(handle, HDM_GETITEMCOUNT, 0, 0);

        }

 

        private void button1_Click(object sender, EventArgs e)

        {

            int headerhwnd; //listview控件的列頭句柄

            int rows,cols;  //listview控件中的行列數

            int processId; //進程pid 

 

            hwnd = FindWindow("#32770", "Windows 任務管理器");

            hwnd = FindWindowEx(hwnd, 0, "#32770",null);

            hwnd = FindWindowEx(hwnd, 0, "SysListView32",null);//進程界面窗口的句柄,通過SPY獲取

            headerhwnd = SendMessage(hwnd, LVM_GETHEADER, 0, 0);//listview的列頭句柄

 

            rows=ListView_GetItemRows(hwnd);//總行數,即進程的數量

            cols = ListView_GetItemCols(headerhwnd);//列表列數

            GetWindowThreadProcessId(hwnd, out processId);

 

            //打開并插入進程

            process = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, false,processId);

            //申請代碼的內存區,返回申請到的虛擬內存首地址

            pointer = VirtualAllocEx(process, IntPtr.Zero, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

            string[,] tempStr;//二維數組

            string[] temp = new string[cols];

 

            tempStr=GetListViewItmeValue(rows,cols);//將要讀取的其他程序中的ListView控件中的文本內容保存到二維數組中

 

            listView1.Items.Clear();//清空LV控件信息

            //輸出數組中保存的其他程序的LV控件信息

            for (int i = 0; i < rows; i++)

            {

                for (int j = 0; j < cols;j++ )

                {

                    temp[j]=tempStr[i,j];

                }

                ListViewItem lvi = new ListViewItem(temp);

                listView1.Items.Add(lvi);

            }

        }

           

        /// <summary>

        /// 從內存中讀取指定的LV控件的文本內容

        /// </summary>

        /// <param name="rows">要讀取的LV控件的行數</param>

        /// <param name="cols">要讀取的LV控件的列數</param>

        /// <returns>取得的LV控件信息</returns>

        private string[,] GetListViewItmeValue(int rows,int cols)

        {

            string[,] tempStr = new string[rows,cols];//二維數組:保存LV控件的文本信息

            for (int i = 0; i < rows;i++ )

            {

                for (int j = 0; j < cols;j++ )

                {

                    byte[] vBuffer = new byte[256];//定義一個臨時緩沖區

                    LVITEM[] vItem = new LVITEM[1];

                    vItem[0].mask = LVIF_TEXT;//說明pszText是有效的

                    vItem[0].iItem = i;     //行號

                    vItem[0].iSubItem = j;  //列號

                    vItem[0].cchTextMax = vBuffer.Length;//所能存儲的最大的文本為256字節

                    vItem[0].pszText = (IntPtr)((int)pointer + Marshal.SizeOf(typeof(LVITEM)));                   

                    uint vNumberOfBytesRead = 0;

                    

                    //把數據寫到vItem

                    //pointer為申請到的內存的首地址

                    //UnsafeAddrOfPinnedArrayElement:獲取指定數組中指定索引處的元素的地址

                    WriteProcessMemory(process,pointer,Marshal.UnsafeAddrOfPinnedArrayElement(vItem,0),Marshal.SizeOf(typeof(LVITEM)), ref vNumberOfBytesRead);

                   

                    //發送LVM_GETITEMW消息給hwnd,將返回的結果寫入pointer指向的內存空間

                    SendMessage(hwnd, LVM_GETITEMW,i,pointer);

 

                    //pointer指向的內存地址開始讀取數據,寫入緩沖區vBuffer

                    ReadProcessMemory(process,((int)pointer + Marshal.SizeOf(typeof(LVITEM))),Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer,0),vBuffer.Length, ref vNumberOfBytesRead);                   

                   

                    string vText = Encoding.Unicode.GetString(vBuffer, 0, (int)vNumberOfBytesRead); ;                   

                    tempStr[i,j] = vText;

                }

            }

            VirtualFreeEx(process, pointer, 0, MEM_RELEASE);//在其它進程中釋放申請的虛擬內存空間,MEM_RELEASE方式很徹底,完全回收

            CloseHandle(process);//關閉打開的進程對象

            return tempStr;

        }

    }

}

此代碼可以將任務管理器中的進程都抓取出來。


該文章在 2023/12/29 23:05:01 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved