我借用别人的代码,5秒循环读取其它程序内存数据,程序运行后5分钟左右死了,提示尝试读取或写入受保护的内存,这通常指示其他内存已损坏,我加了两句代码for和buffer = null;后,程序多运行了15分钟,还是死了,提示相同错误,请问如何改?从其它程序读取内存数据有的代码如下: public static int ReadMemoryValue(int baseAddress, string processName)
{
try
{
byte[] buffer = new byte[4];
IntPtr byteAddress = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0); //获取缓冲区地址
IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPidByProcessName(processName));
ReadProcessMemory(hProcess, (IntPtr)baseAddress, byteAddress, 4, IntPtr.Zero); //将制定内存中的值读入缓冲区
CloseHandle(hProcess); for (int i = 0; i < buffer.Length; i++)
buffer[i] = 0;//我自已加的代码 buffer = null;//我自已加的代码 return Marshal.ReadInt32(byteAddress);//在运行时提示在运行时提示尝试读取或写入受保护的内存,这通常指示其他内存已损坏。。
}
catch
{
return 0;
}
}
{
try
{
byte[] buffer = new byte[4];
IntPtr byteAddress = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0); //获取缓冲区地址
IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPidByProcessName(processName));
ReadProcessMemory(hProcess, (IntPtr)baseAddress, byteAddress, 4, IntPtr.Zero); //将制定内存中的值读入缓冲区
CloseHandle(hProcess); for (int i = 0; i < buffer.Length; i++)
buffer[i] = 0;//我自已加的代码 buffer = null;//我自已加的代码 return Marshal.ReadInt32(byteAddress);//在运行时提示在运行时提示尝试读取或写入受保护的内存,这通常指示其他内存已损坏。。
}
catch
{
return 0;
}
}
(
int dwDesiredAccess,
bool bInheritHandle,
int dwProcessId
); public static void WriteMemoryValue(int baseAddress, string processName, int value)
{
IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPidByProcessName(processName)); //0x1F0FFF 最高权限
WriteProcessMemory(hProcess, (IntPtr)baseAddress, new int[] { value }, 4, IntPtr.Zero);
CloseHandle(hProcess);
}
借用的源码地址http://www.cnblogs.com/gleamy_ming/archive/2011/03/16/1985656.html
这里不是已经将资源回收了么?你在读取byteAddress自然不对了 把CloseHandle(hProcess);
放在代码的最后。
Marshal.UnsafeAddrOfPinnedArrayElement这个方法是获得托管内存块地址,托管内存地址会被GC移动,就有可能在被移动后,IntPtr byteAddress不再指向buffer。
你需要在调用Marshal.UnsafeAddrOfPinnedArrayElement前通过GcHandle将buffer固定,然后再循环操作。或者使用Marshal.AllocCoTaskMem在非托管内存分配四个字节,这样不会被GC移动,完事后调用Marshal.FreeCoTaskMem释放该非托管内存。
自己会释放的可以用System.GC.Collect(); 强制释放
读取内存时有个释放的方法 flush() 你看看用没用...
一定要读一段就要释放一段...
自己会释放的可以用System.GC.Collect(); 强制释放
CloseHandle(hProcess);GC.KeepAlive(buffer);//让内存不被回收return Marshal.ReadInt32(byteAddress);
这样可能行