Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#-无法将IntPtr正确封送到字符串_C#_Pinvoke_32bit 64bit - Fatal编程技术网

C#-无法将IntPtr正确封送到字符串

C#-无法将IntPtr正确封送到字符串,c#,pinvoke,32bit-64bit,C#,Pinvoke,32bit 64bit,这一行代码一直困扰着我 string s = Marshal.PtrToStringAnsi((IntPtr)((Int32)Buffer + Marshal.SizeOf(typeof(Struct)))); 下面是函数的其余部分 Api.LvItem lvItem = new Api.LvItem(); IntPtr lpLocalBuffer = Marshal.AllocHGlobal(1024);

这一行代码一直困扰着我

string s = Marshal.PtrToStringAnsi((IntPtr)((Int32)Buffer + 
            Marshal.SizeOf(typeof(Struct))));
下面是函数的其余部分

            Api.LvItem lvItem = new Api.LvItem();
            IntPtr lpLocalBuffer = Marshal.AllocHGlobal(1024);
            uint pid;
            uint thread = Api.GetWindowThreadProcessId(hWnd, out pid);
            IntPtr hProcess = Api.OpenProcess(0x001f0fff, false, (int)pid);
            IntPtr lpRemoteBuffer = Api.VirtualAllocEx(hProcess, IntPtr.Zero, 1024, 0x1000, 4);
            lvItem.mask = 1;
            lvItem.iItem = index;
            lvItem.iSubItem = subitem;
            lvItem.pszText = (IntPtr)((int)lpRemoteBuffer + Marshal.SizeOf(typeof(Api.LvItem)));
            lvItem.cchTextMax = 50;
            Api.WriteProcessMemory(hProcess, lpRemoteBuffer, ref lvItem, Marshal.SizeOf(typeof(Api.LvItem)), 0);
            Api.SendMessage(hWnd, 0x1005, IntPtr.Zero, lpRemoteBuffer);
            Api.ReadProcessMemory(hProcess, lpRemoteBuffer, lpLocalBuffer, 1024, 0);
            string ret = Marshal.PtrToStringAnsi((IntPtr)((int)lpLocalBuffer + Marshal.SizeOf(typeof(Api.LvItem))));
            Marshal.FreeHGlobal((IntPtr)lpLocalBuffer);
            Api.VirtualFreeEx(hProcess, lpRemoteBuffer, 0, 0x8000);
            Api.CloseHandle(hProcess);
            return ret;
此代码用于获取另一个进程的listview中每个项的文本。我从这里开始遵循代码(semi):

很抱歉使用了0x1005。这是
LV_GETITEM
消息的代码

我把范围缩小到与平台相关。它在x64和AnyCPU上工作,而在x86上不工作。我将如何改变内存分配等方面的大小差异

在控制台应用程序中使用时,它会正确返回值。但是,当我在通过反射调用的.DLL中使用此代码(及其其余部分)时,代码返回一个不正确的字符串。它看起来是空的,但实际上不是空的。也许只是空白

有没有人有过类似的处理编组问题的经验?这让我困惑了整整三个小时


非常感谢您的任何帮助、任何想法或任何事情

您似乎正在尝试读取另一进程的内存。您正在向列表视图控件发送一条
LV_GETITEM
消息。这需要在另一个进程的虚拟地址空间中分配内存。这是您通过调用
VirtualAllocEx
实现的

到目前为止还不错,但这是关键。您需要将分配的结构作为目标进程的正确布局。现在,让我们假设目标进程是一个64位进程。在这种情况下,结构包含64位指针。如果进程也是64位的,则定义的结构将具有64位指针。但当进程为32位时,结构中的任何指针都将为32位

因此,现在我们遇到了一种情况,流程中的结构与目标流程中的结构具有不同的布局。这种不匹配足以使所有这些努力失败。为了有机会实现这一点,您需要声明结构,使其布局与64位布局匹配。考虑到您只访问少数字段,分配适当大小的内存块(可能是字节数组)并手动读取/写入字段可能会更简单。并避免结构编组

即使如此,我仍然怀疑32位进程是否能够以这种方式戳到64位进程。您可以从另一个方向执行,从64位进程到32位进程。但我已经尝试过了,但在你尝试的方向上从未成功过

所有迹象都表明,对于此任务,您应该坚持使用64位进程。或者找到一种官方支持的方式来做你正在做的事情。例如,如果您只想读取资源管理器视图的内容,那么有一个shell API



另一方面,请停止使用魔法常量而不是消息标识符名称。没有人喜欢尝试理解
0x1005
的含义。声明一个名为
LV\u GETITEM
的常量。您似乎也没有执行任何错误检查。这也会让你的生活变得艰难。如果其中一个API调用失败,您将如何发现这一点?

可能是64位指针截断,但这很可能导致访问冲突。因此,结构末尾以外的内容可能真的是空的。你为什么不给我们一个完整的程序来说明故障呢。否则我们只能猜测。你有一个完整的计划。我们不这样做是不公平的,大卫,我把范围缩小到与平台相关。它在x64和AnyCPU上工作,而在x86上不工作。我想我现在可以接受了,但任何建议都是有帮助的。我正在运行x64位版本的Windows。另外,我将如何改变内存分配中的大小差异,等等,我不知道。您没有显示足够的代码。如果你坚持自己保存它,我帮不了你。这里是函数,太长了,无法发表评论。这有帮助吗,还是你在寻找更多?你明白我的意思吗?是的,我明白你的意思,但我需要32位的进程…没有例外。因此,在我的例子中,您是说我需要在64位结构中找到LVITEM结构的大小,并通过该大小的字节[]手动分配内存?是的,使用字节数组而不是使用结构和编组。或者使用结构并将指针替换为
long
,即64位整数。不管怎么说,即使你把所有的东西都匹配起来,我仍然不相信用32位进程就可以做到这一点。你在寻求更多的帮助吗?