C#在Process.Kill()期间只完成了ReadProcessMemory或WriteProcessMemory请求的一部分
我一直在广泛研究这个问题,似乎无法找到答案。
我知道Only part of a ReadProcessMemory or WriteProcessMemory request was completed
的Only part of a ReadProcessMemory or WriteProcessMemory request was completed
exception在32位进程尝试访问64位进程时引发exception,而对于64位修改32位进程则相同。
该问题的解决方案是将平台目标更改为“任何CPU”。 我试过这个,不幸的是这并没有解决我的问题。
下一个代码块是不断抛出exception的原因。 运行此代码的程序用于在远程计算机上打开应用程序,并保留程序本身打开的所有进程的列表,这样我就不必遍历所有进程。
Process processToRemove = null; lock (_runningProcesses) { foreach (Process p in _runningProcesses) { foreach (ProcessModule module in p.Modules) { string[] strs = text.Split('\'); if (module.ModuleName.Equals(strs[strs.Length - 1])) { processToRemove = p; break; } } if (processToRemove != null) { break; } } if (processToRemove != null) { processToRemove.Kill(); _runningProcesses.Remove(processToRemove); } }
这些进程可以并且很可能是32位和64位混合在一起。
我有什么我不应该做的事情,还是有更好的方法来做所有这些?
正如Process.Modules和此线程 的MSDN页面的注释中所详述的那样,当从64位进程枚举32位进程时, Process.Modules
存在一个已知问题,反之亦然:
.NET内部的Process.Modules使用PSAPI.dll中的EnumProcessModules函数。 此函数有一个已知问题,它无法跨32/64位进程边界工作。 因此,从32位进程枚举另一个64位进程(反之亦然)无法正常工作。
解决方案似乎是使用EnumProcessModulesEx
函数(必须通过P / Invoke调用),但此function仅适用于更高版本的Windows。
我们通过向PSAPI.dll(https://msdn2.microsoft.com/en-us/library/ms682633.aspx)添加一个名为EnumProcessModulesEx的新函数来修复此问题,但我们目前无法在这种情况下使用它:
关于进程的处理和我将改变的锁定只有一些问题:
object lockObject = new object(); List processesToRemove = new List (); foreach (Process p in _runningProcesses) { foreach (ProcessModule module in p.Modules) { string[] strs = text.Split('\'); if (module.ModuleName.Equals(strs[strs.Length - 1])) { processesToRemove.Add(p); break; } } } lock (lockObject) { foreach (Process p in processesToRemove) { p.Kill(); _runningProcesses.Remove(p); } }
我不是在回答赏金,只是想提出一些想法。 此代码未经过测试,因为我并不确切知道您要在那里做什么。
只考虑不要锁定进程列表并尽可能缩短锁定。
我同意@ sprinter252, _runningProcesses
不应该在这里用作你的同步对象。
//Somewhere that is accessible to both the thread getting the process list and the thread the //code below will be running, declare your sync, lock while adjusting _runningProcesses public static readonly object Sync = new object(); IList runningProcesses; lock(Sync) { runningProcesses = _runningProcesses.ToList(); } Process processToRemove = null; foreach (Process p in _runningProcesses) { foreach (ProcessModule module in p.Modules) { string[] strs = text.Split('\'); if (module.ModuleName.Equals(strs[strs.Length - 1])) { processToRemove = p; break; } } if (processToRemove != null) { break; } } if (processToRemove != null) { //If we've got a process that needs killing, re-lock on Sync so that we may //safely modify the shared collection lock(Sync) { processToRemove.Kill(); _runningProcesses.Remove(processToRemove); } }
如果此代码包含在循环中以继续检查_runningProcesses
以查找要杀死的进程,请考虑将processToRemove
更改为processesToRemove
并将其类型更改为集合,在检查非零后迭代底部块中的该列表计数并锁定该循环外部,以减少获取和释放每个进程锁定的开销。
上述就是C#学习教程:C#在Process.Kill()期间只完成了ReadProcessMemory或WriteProcessMemory请求的一部分分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1013872.html