Я использую Process.GetProcesses(), чтобы запустить весь процесс на локальном компьютере, но, полагаю, у меня проблема с утечкой памяти.
Это код, который получает мой список процессов:
List<Process> allProcess = Process.GetProcesses().Where((process) =>
{
try
{
return process.GetMainModuleFileName().Contains("NAME") && !Native.IsResponding(process);
}
catch
{
return false;
}
}).ToList();
Расширение GetModuleFileName (возвращает путь к файлу независимо от архитектуры)
public static string GetMainModuleFileName(this Process process, int buffer = 1024)
{
var fileNameBuilder = new StringBuilder(buffer);
uint bufferLength = (uint)fileNameBuilder.Capacity + 1;
return QueryFullProcessImageName(process.Handle, 0, fileNameBuilder, ref bufferLength) ?
fileNameBuilder.ToString() :
null;
}
Функция IsResponding
public static bool IsResponding(Process process)
{
HandleRef handleRef = new HandleRef(process, process.MainWindowHandle);
int timeout = 2000;
IntPtr lResult = SendMessageTimeout(
handleRef,
0,
IntPtr.Zero,
IntPtr.Zero,
SMTO_ABORTIFHUNG,
timeout,
out IntPtr lpdwResult);
return lResult != IntPtr.Zero;
}
[DllImport("user32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr SendMessageTimeout(
HandleRef hWnd,
int msg,
IntPtr wParam,
IntPtr lParam,
int flags,
int timeout,
out IntPtr pdwResult);
[DllImport("Kernel32.dll")]
private static extern bool QueryFullProcessImageName([In] IntPtr hProcess, [In] uint dwFlags, [Out] StringBuilder lpExeName, [In, Out] ref uint lpdwSize);
Когда мой allProcess наполняется каким-либо результатом, моя память приложения немного увеличивается и никогда не уменьшается. Я уже пробовал:
for(int i = allProcess.Count - 1; i >= 0; i--)
{
allProcess[i].Dispose();
allProcess[i] = null;
}
allProcess = null;
GC.Collect();
Native.CloseSharedResources();
public static void CloseSharedResources()
{
PerformanceCounterPermission performanceCounterPermission = new PerformanceCounterPermission(PerformanceCounterPermissionAccess.Read, ".", "*");
performanceCounterPermission.Demand();
}
Просто для теста, когда я извлекаю Process.GetProcesses(), память остается стабильной.
Почему память никогда не уменьшается?
Что делает Native.IsResponding?
@rene отлично работает. Никакой ошибки в этой функции. Буду редактировать на Native.IsResponding
Значит, QueryFullProcessImageName никогда не возвращает false?
Вместо HandleRef используйте SafeHandle
@rene SafeHandle - это абстрактный класс. Посмотрю, как реализовать. QueryFullProcessImageName выдает, когда у меня нет доступа из-за безопасности, давая мне доступ,
@KevinKouketsu есть ли шансы поделиться всем кодом, который можно собрать и запустить? дело кажется интересным, хочу проверить в Deleaker.





Не работает ли QueryFullProcessImageName, и если да, можете ли вы вызвать GetLastError и включить коды ошибок?