当前位置: 首页 > 编程语言 > C#

从64位SysListView32获取文本共享

时间:2023-04-11 11:59:47 C#

从64位SysListView32获取文本这是我的代码:publicstaticstringReadListViewItem(IntPtrlstview,intitem){constintdwBufferSize=1024;intdw进程ID;LV_ITEMlvItem;字符串重排;布尔bSuccess;IntPtrhProcess=IntPtr.Zero;IntPtrlpRemoteBuffer=IntPtr.Zero;IntPtrlpLocalBuffer=IntPtr.Zero;IntPtrthreadId=IntPtr.Zero;(dwBufferSize);//获取拥有窗口的进程IDthreadId=GetWindowThreadProcessId(lstview,outdwProcessID);如果((threadId==IntPtr.Zero)||(dwProcessID==0))thrownewArgumentException("hWnd");//使用所有访问权限打开进程hProcess=OpenProcess(PROCESS_ALL_ACCESS,false,dwProcessID);if(hProcess==IntPtr.Zero)thrownewApplicationException("无法访问进程");//在远程进程中分配一个缓冲区lpRemoteBuffer=VirtualAllocEx(hProcess,IntPtr.Zero,dwBufferSize,MEM_COMMIT,PAGE_READWRITE);if(lpRemoteBuffer==IntPtr.Zero)thrownewSystemException("无法在远程进程中分配内存");//填写LVITEM结构,这是在你自己的进程中//将pszText成员设置到远程缓冲区中的某个位置,//例如,我在LVITEM结构后立即使用了地址lvItem.mask=LVIF_TEXT;lvItem.iItem=物品;lvItem.iSubItem=2;lvItem.pszText=(IntPtr)(lpRemoteBuffer.ToInt32()+Marshal.SizeOf(typeof(LV_ITEM)));lvItem.cchTextMax=50;//将本地LVITEM复制到远程缓冲区bSuccess=WriteProcessMemory(hProcess,lpRemoteBuffer,reflvItem,Marshal.SizeOf(typeof(LV_ITEM)),IntPtr.Zero);if(!bSuccess)thrownewSystemException("无法写入进程内存");//使用远程缓冲区的地址向远程窗口发送消息SendMessage(lstview,LVM_GETITEMText,0,lpRemoteBuffer);//将结构从远程进程读回本地缓冲区bSuccess=ReadProcessMemory(h进程,lpRemoteBuffer,lpLocalBuffer,dwBufferSize,IntPtr.Zero);if(!bSuccess)thrownewSystemException("无法从进程内存读取");//此时lpLocalBuffer包含返回的LV_ITEM结构//下一行将缓冲区中的文本提取到托管字符串中retval=Marshal.PtrToStringAnsi((IntPtr)(lpLocalBuffer+Marshal.SizeOf(typeof(LV_ITEM))));}finally{if(lpLocalBuffer!=IntPtr.Zero)Marshal.FreeHGlobal(lpLocalBuffer);如果(lpRemoteBuffer!=IntPtr.Zero)VirtualFreeEx(hProcess,lpRemoteBuffer,0,MEM_RELEASE);如果(hProcess!=IntPtr.Zero)CloseHandle(hProcess);}返回值;}无论我做什么retval返回空间,虽然lpLocalBuffer没有这是ListItem的定义:[StructLayout(LayoutKind.Sequential)]privatestructLV_ITEM{publicintmask;公共int项目;公共intiSubItem;公共诠释状态;公共int状态掩码;公共IntPtrpszText;公共intcchTextMax;公共intiImage;内部intlParam;内部intiIndent;我尝试为86x、64位、任何cpu编译,似乎没有任何效果!知道为什么会这样吗?C#+.net4,Windows764位。这是一种不同的方法-使用UI自动化。它为您执行跨进程、跨位工作,并且可以与列表视图、列表框或几乎任何其他标准WindowsUI一起使用。这是一个示例应用程序,它将从鼠标指针下的列表视图中获取HWND并将项目转储到其中。它只是转储每个项目的名称;使用Listviews,我想您可以根据需要递归到每个项目的字段中。//编译使用:cscReadListView.cs/r:UIAutomationClient.dllusingSystem;使用System.Windows.Automation;使用System.Runtime.InteropServices;classReadListView{publicstaticvoidMain(){Console.WriteLine("将指针放在列表视图上并点击返回...");控制台.ReadLine();//获取光标位置,然后获取该点的窗口句柄...POINTpt;GetCursorPos(出点);IntPtrhwnd=WindowFromPoint(pt);//获取表示窗口句柄的AutomationElement...AutomationElementel=AutomationElement.FromHandle(hwnd);//使用内容视图遍历自动化元素树,所以我们只能看到//列表项,看不到滚动条和标题。(如果您//也想遍历它们,请使用ControlViewWalker。)TreeWalkerwalker=TreeWalker.ContentViewWalker;诠释我=0;for(AutomationElementchild=walker.GetFirstChild(el);child!=null;child=walker.GetNextSibling(child)){//打印出项目的类型及其名称Console.WriteLine(“项目{0}是名称为“{2}”的“{1}”,i++,child.Current.LocalizedControlType,child.Current.Name);}}[StructLayout(LayoutKind.Sequential)]privatestructPOINT{publicintx;公共整数y;};[DllImport("user32.dll")]privatestaticexternIntPtrWindowFromPoint(POINTpt);[DllImport("user32.dll")]privatestaticexternintGetCursorPos(outPOINTpt);我知道这是旧的但我在尝试解决我的问题时发现它,希望这会帮助其他人我在这个问题中使用了C++的建议,并稍微修改了LV_ITEM结构,以便在VB.NET中使用64位(我没有在C#中测试,但我想解决方案非常相似。)公共结构LV_ITEM64公共掩码作为整数公共iItem作为整数公共iSubItem作为整数公共状态作为整数公共状态掩码作为整数公共占位符1作为整数公共pszText作为整数公共placeholder2AsIntegerPubliccchTextMaxAsIntegerPubliciImageAsIntegerEndStructure然后,在声明结构实例时,我使用以下代码在64位和32位结构之间进行选择:DimlviAsObjectIfIntPtr.Size=4Thenlvi=NewLV_ITEMElselvi=NewLV_ITEM64EndIf您已明确表示您正尝试将32位进程中的列表视图控件中的项目读取到另一个64位进程中。我在各种论坛上看到了很多关于这个主题的问题,但似乎都没有成功。我认为最好的办法是创建一个32位可执行文件来读取其他程序的列表视图。如果您的程序是32位的,而目标程序是64位的,则至少需要克服一个障碍。或者反过来。LVITEM声明错误,IntPtr的位数错误。这使得Marshal.SizeOf()返回错误的值。我认为对齐是可以的。将字段更改为int或long即可,具体取决于目标程序的位数。您可以通过查看Taskmgr.exe的“进程”选项卡找到它。如果进程名称是32位进程,则使用“*32”进行后固定。或者通过设置项目的目标平台设置来匹配目标进程(x86或AnyCPU)来避免麻烦。使用Debug+Windows+Memory+Memory1进行调试。将“lpLocalBuffer”放入“地址”框中,观察您看到的内容与您的代码读取的内容。如果您正确使用字符串,您绝对应该能够从十六进制视图中分辨出来。请注意,如果您在字符串字符之间看到零,则目标进程正在使用列表视图的Unicode版本。然后需要Marshal.PtrToStringUnicode来读取它。抱歉回复晚了,但我遇到了同样的问题。这是我用于VB.NET的结构,它适用于32位和64位系统。以上就是C#学习教程:从64位SysListView32获取文分享的全部内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多加关注——_PublicStructureLV_ITEMPublicMaskAsUIntegerPublicIndexAsIntegerPublicSubIndexAsIntegerPublicStateAsIntegerPublicStateMaskAsIntPtrPublicTextAsStringPublicTextLengthAsIntegerPublicImageIndexAsIntegerPublicLParamAsIntPtr结束结构。如需转载请注明出处:

最新推荐
猜你喜欢