using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Intelix.Helper; public static class ProcessWindows { public class ProcInfo { public string Name { get; set; } public string Pid { get; set; } public string Path { get; set; } public string Memory { get; set; } } private static readonly Lazy> _procInfos = new Lazy>(BuildCache, isThreadSafe: true); public static List GetProcInfos() { return new List(_procInfos.Value); } public static List FindFolder(string folderName) { if (string.IsNullOrWhiteSpace(folderName)) { return new List(); } ConcurrentDictionary concurrentDictionary = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); SearchNearby(folderName, isDirectory: true, concurrentDictionary); return new List(concurrentDictionary.Keys); } public static List FindFile(string fileName) { if (string.IsNullOrWhiteSpace(fileName)) { return new List(); } ConcurrentDictionary concurrentDictionary = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); SearchNearby(fileName, isDirectory: false, concurrentDictionary); return new List(concurrentDictionary.Keys); } private static void SearchNearby(string target, bool isDirectory, ConcurrentDictionary found, int maxUp = 3) { if (string.IsNullOrEmpty(target)) { return; } List value = _procInfos.Value; if (value == null || value.Count == 0) { return; } string t = target.Trim(); Parallel.ForEach(value, delegate(ProcInfo proc) { try { string path = proc.Path; if (!string.IsNullOrEmpty(path)) { string directoryName = Path.GetDirectoryName(path); if (!string.IsNullOrEmpty(directoryName)) { for (int i = 0; i < maxUp; i++) { if (string.IsNullOrEmpty(directoryName)) { break; } string path2 = Path.Combine(directoryName, t); if (isDirectory) { if (Directory.Exists(path2)) { try { found.TryAdd(Path.GetFullPath(path2), 0); } catch { } } } else if (File.Exists(path2)) { try { found.TryAdd(Path.GetFullPath(path2), 0); } catch { } } directoryName = Path.GetDirectoryName(directoryName); } } } } catch { } }); } private static List BuildCache() { ConcurrentDictionary result = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); uint num = 4096u; uint[] pids = new uint[num]; if (!NativeMethods.EnumProcesses(pids, num * 4, out var lpcbNeeded)) { num = 65536u; pids = new uint[num]; if (!NativeMethods.EnumProcesses(pids, num * 4, out lpcbNeeded)) { return new List(); } } int num2 = (int)(lpcbNeeded / 4); if (num2 <= 0) { return new List(); } ThreadLocal sbLocal = new ThreadLocal(() => new StringBuilder(1024)); Parallel.For(0, num2, delegate(int i) { uint num3 = pids[i]; if (num3 == 0 || num3 == 4) { return; } IntPtr intPtr = IntPtr.Zero; try { intPtr = NativeMethods.OpenProcess(5136u, bInheritHandle: false, (int)num3); if (!(intPtr == IntPtr.Zero)) { string text = null; try { StringBuilder value = sbLocal.Value; value.Clear(); uint lpdwSize = (uint)value.Capacity; if (NativeMethods.QueryFullProcessImageName(intPtr, 0, value, ref lpdwSize)) { text = value.ToString(0, (int)lpdwSize); } } catch { } string text2 = null; if (!string.IsNullOrEmpty(text)) { try { text2 = Path.GetFileNameWithoutExtension(text); } catch { text2 = text; } } else { text2 = ""; } string text3 = ""; try { NativeMethods.PROCESS_MEMORY_COUNTERS_EX ppsmemCounters = default(NativeMethods.PROCESS_MEMORY_COUNTERS_EX); ppsmemCounters.cb = (uint)Marshal.SizeOf(typeof(NativeMethods.PROCESS_MEMORY_COUNTERS_EX)); if (NativeMethods.GetProcessMemoryInfo(intPtr, out ppsmemCounters, ppsmemCounters.cb)) { text3 = FormatBytes((long)ppsmemCounters.WorkingSetSize.ToUInt64()); } } catch { } ProcInfo procInfo = new ProcInfo { Name = SafeString(text2), Pid = num3.ToString(), Path = SafeString(text), Memory = (text3 ?? "") }; string key = procInfo.Path + "|" + procInfo.Pid; result.TryAdd(key, procInfo); } } catch { } finally { try { if (intPtr != IntPtr.Zero) { NativeMethods.CloseHandle(intPtr); } } catch { } } }); sbLocal.Dispose(); return new List(result.Values); } private static string SafeString(string s) { if (!string.IsNullOrEmpty(s)) { return s; } return ""; } private static string FormatBytes(long bytes) { if (bytes >= 1073741824) { return ((double)bytes / 1073741824.0).ToString("0.##") + " GB"; } if (bytes >= 1048576) { return ((double)bytes / 1048576.0).ToString("0.##") + " MB"; } if (bytes >= 1024) { return ((double)bytes / 1024.0).ToString("0.##") + " KB"; } return bytes + " B"; } }