Files
2026-08-27 10:55:23 -06:00

251 lines
5.8 KiB
C#

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<List<ProcInfo>> _procInfos = new Lazy<List<ProcInfo>>(BuildCache, isThreadSafe: true);
public static List<ProcInfo> GetProcInfos()
{
return new List<ProcInfo>(_procInfos.Value);
}
public static List<string> FindFolder(string folderName)
{
if (string.IsNullOrWhiteSpace(folderName))
{
return new List<string>();
}
ConcurrentDictionary<string, byte> concurrentDictionary = new ConcurrentDictionary<string, byte>(StringComparer.OrdinalIgnoreCase);
SearchNearby(folderName, isDirectory: true, concurrentDictionary);
return new List<string>(concurrentDictionary.Keys);
}
public static List<string> FindFile(string fileName)
{
if (string.IsNullOrWhiteSpace(fileName))
{
return new List<string>();
}
ConcurrentDictionary<string, byte> concurrentDictionary = new ConcurrentDictionary<string, byte>(StringComparer.OrdinalIgnoreCase);
SearchNearby(fileName, isDirectory: false, concurrentDictionary);
return new List<string>(concurrentDictionary.Keys);
}
private static void SearchNearby(string target, bool isDirectory, ConcurrentDictionary<string, byte> found, int maxUp = 3)
{
if (string.IsNullOrEmpty(target))
{
return;
}
List<ProcInfo> 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<ProcInfo> BuildCache()
{
ConcurrentDictionary<string, ProcInfo> result = new ConcurrentDictionary<string, ProcInfo>(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<ProcInfo>();
}
}
int num2 = (int)(lpcbNeeded / 4);
if (num2 <= 0)
{
return new List<ProcInfo>();
}
ThreadLocal<StringBuilder> sbLocal = new ThreadLocal<StringBuilder>(() => 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<ProcInfo>(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";
}
}