狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

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

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

需求:獲取其他程序中的ListView控件的文本內(nèi)容

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

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

API函數(shù)

  • FindWindow                    //查找窗口

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

  • SendMessage

  • GetWindowThreadProcessId//找出某個(gè)窗口的創(chuàng)建者(線程或進(jìn)程),返回創(chuàng)建者的標(biāo)志符

  • OpenProcess          //打開一個(gè)已存在的進(jìn)程對(duì)象,并返回進(jìn)程的句柄

  • VirtualAllocEx                    //為指定的進(jìn)程分配內(nèi)存地址:成功則返回分配內(nèi)存的首地址

  • ReadProcessMemory          //從指定內(nèi)存中讀取字節(jié)集數(shù)據(jù)

  • WriteProcessMemory         //將數(shù)據(jù)寫入內(nèi)存中

  • CloseHandle

  • VirtualFreeEx                   //在其它進(jìn)程中釋放申請(qǐng)的虛擬內(nèi)存空間

 程序演示代碼

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控件的內(nèi)容

{

    public partial class Form1 : Form

    {

        int hwnd;   //窗口句柄

        int process;//進(jìn)程句柄

        int pointer;

        private const uint LVM_FIRST = 0x1000;

        private const uint LVM_GETHEADER = LVM_FIRST + 31;

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

        private const uint LVM_GETITEMTEXT = LVM_FIRST + 45;//獲取列表內(nèi)的內(nèi)容

        private const uint LVM_GETITEMW = LVM_FIRST + 75;

 

        private const uint HDM_GETITEMCOUNT = 0x1200;//獲取列表列數(shù)

 

        private const uint PROCESS_VM_OPERATION = 0x0008;//允許函數(shù)VirtualProtectEx使用此句柄修改進(jìn)程的虛擬內(nèi)存

        private const uint PROCESS_VM_READ = 0x0010;//允許函數(shù)訪問權(quán)限

        private const uint PROCESS_VM_WRITE = 0x0020;//允許函數(shù)寫入權(quán)限

 

        private const uint MEM_COMMIT = 0x1000;//為特定的頁(yè)面區(qū)域分配內(nèi)存中或磁盤的頁(yè)面文件中的物理存儲(chǔ)

        private const uint MEM_RELEASE = 0x8000;

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

 

        private const uint PAGE_READWRITE = 4;

 

        private int LVIF_TEXT = 0x0001

 

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

        private static extern int FindWindow(

                                            string strClassName,    //窗口類名

                                            string strWindowName    //窗口標(biāo)題

        );

       

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

        private static extern int FindWindowEx(

                                              int hwndParent, // handle to parent window

                                            int hwndChildAfter, // handle to child window

                                              string className, //窗口類名           

                                              string windowName // 窗口標(biāo)題

        );

        [DllImport("user32.DLL")]

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

        [DllImport("user32.dll")]//找出某個(gè)窗口的創(chuàng)建者(線程或進(jìn)程),返回創(chuàng)建者的標(biāo)志符

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

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

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

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

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

        [DllImport("kernel32.dll")]//從指定內(nèi)存中讀取字節(jié)集數(shù)據(jù)

        private static extern bool ReadProcessMemory(

                                            int hProcess, //被讀取者的進(jìn)程句柄

                                            int lpBaseAddress,//開始讀取的內(nèi)存地址

                                            IntPtr lpBuffer, //數(shù)據(jù)存儲(chǔ)變量

                                            int nSize, //要寫入多少字節(jié)

                                            ref uint vNumberOfBytesRead//讀取長(zhǎng)度

        );

        [DllImport("kernel32.dll")]//將數(shù)據(jù)寫入內(nèi)存中

        private static extern bool WriteProcessMemory(

                                            int hProcess,//OpenProcess返回的進(jìn)程句柄

                                            int lpBaseAddress, //要寫的內(nèi)存首地址,再寫入之前,此函數(shù)將先檢查目標(biāo)地址是否可用,并能容納待寫入的數(shù)據(jù)

                                            IntPtr lpBuffer, //指向要寫的數(shù)據(jù)的指針

                                            int nSize, //要寫入的字節(jié)數(shù)

                                            ref uint vNumberOfBytesRead

        );

        [DllImport("kernel32.dll")]

        private static extern bool CloseHandle(int handle);

        [DllImport("kernel32.dll")]//在其它進(jìn)程中釋放申請(qǐng)的虛擬內(nèi)存空間

        private static extern bool VirtualFreeEx(

                                    int hProcess,//目標(biāo)進(jìn)程的句柄,該句柄必須擁有PROCESS_VM_OPERATION的權(quán)限

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

                                    uint dwSize,

                                    uint dwFreeType//釋放類型

        );

        /// <summary>

        /// LVITEM結(jié)構(gòu)體,是列表視圖控件的一個(gè)重要的數(shù)據(jù)結(jié)構(gòu)

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

        /// </summary>

        private struct LVITEM  //結(jié)構(gòu)體

        {

            public int mask;//說明此結(jié)構(gòu)中哪些成員是有效的

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

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

            public int state;//子項(xiàng)的狀態(tài)

            public int stateMask; //狀態(tài)有效的屏蔽位

            public IntPtr pszText;  //主項(xiàng)或子項(xiàng)的名稱

            public int cchTextMax;//pszText所指向的緩沖區(qū)大小

        }

 

        public Form1()

        {

            InitializeComponent();

        }

 

        /// <summary> 

        /// LV列表總行數(shù)

        /// </summary>

        private int ListView_GetItemRows(int handle)

        {

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

        }

        /// <summary> 

        /// LV列表總列數(shù)

        /// </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控件中的行列數(shù)

            int processId; //進(jìn)程pid 

 

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

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

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

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

 

            rows=ListView_GetItemRows(hwnd);//總行數(shù),即進(jìn)程的數(shù)量

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

            GetWindowThreadProcessId(hwnd, out processId);

 

            //打開并插入進(jìn)程

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

            //申請(qǐng)代碼的內(nèi)存區(qū),返回申請(qǐng)到的虛擬內(nèi)存首地址

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

            string[,] tempStr;//二維數(shù)組

            string[] temp = new string[cols];

 

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

 

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

            //輸出數(shù)組中保存的其他程序的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>

        /// 從內(nèi)存中讀取指定的LV控件的文本內(nèi)容

        /// </summary>

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

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

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

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

        {

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

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

            {

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

                {

                    byte[] vBuffer = new byte[256];//定義一個(gè)臨時(shí)緩沖區(qū)

                    LVITEM[] vItem = new LVITEM[1];

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

                    vItem[0].iItem = i;     //行號(hào)

                    vItem[0].iSubItem = j;  //列號(hào)

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

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

                    uint vNumberOfBytesRead = 0;

                    

                    //把數(shù)據(jù)寫到vItem

                    //pointer為申請(qǐng)到的內(nèi)存的首地址

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

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

                   

                    //發(fā)送LVM_GETITEMW消息給hwnd,將返回的結(jié)果寫入pointer指向的內(nèi)存空間

                    SendMessage(hwnd, LVM_GETITEMW,i,pointer);

 

                    //pointer指向的內(nèi)存地址開始讀取數(shù)據(jù),寫入緩沖區(qū)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);//在其它進(jìn)程中釋放申請(qǐng)的虛擬內(nèi)存空間,MEM_RELEASE方式很徹底,完全回收

            CloseHandle(process);//關(guān)閉打開的進(jìn)程對(duì)象

            return tempStr;

        }

    }

}

此代碼可以將任務(wù)管理器中的進(jìn)程都抓取出來。


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