A way in .NET Framework 4.8 with System.Reflection.Metadata Nuget Package (must be compiled in x64 to read both 32 and 64-bit processes):
(could be improved because EnumProcessModulesEx does not display a Shell Extension DLL that Process Explorer displays...) :
//string sProcessName = "CSharp_Test5";
string sProcessName = "Explorer";
Process[] procs = Process.GetProcessesByName(sProcessName);
if (procs.Count() > 0)
{
Console.WriteLine("Process : " + procs[0].ProcessName);
int nPID = procs[0].Id;
IntPtr hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, nPID);
if (hProcess != IntPtr.Zero)
{
IntPtr[] modulesHandles = new IntPtr[1024];
int nSize = 0;
bool bRet = EnumProcessModulesEx(hProcess, modulesHandles, Marshal.SizeOf(typeof(IntPtr)) * modulesHandles.Length,
out nSize, MODULEFILTERFLAGS.LIST_MODULES_ALL);
int nErr = Marshal.GetLastWin32Error();
if (bRet)
{
for (int i = 0; i < nSize / Marshal.SizeOf(typeof(IntPtr)); i++)
{
StringBuilder sbModuleName = new StringBuilder(1024);
uint nLength = GetModuleFileNameEx(hProcess, modulesHandles[i], sbModuleName,(uint)sbModuleName.Capacity);
try
{
using (FileStream fs = new FileStream(sbModuleName.ToString(), FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (PEReader peReader = new PEReader(fs))
{
if (peReader.HasMetadata)
{
MetadataReader mr = peReader.GetMetadataReader();
if (mr.IsAssembly)
Console.WriteLine("\tAssembly : " + sbModuleName.ToString());
}
}
}
}
catch (System.Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
CloseHandle(hProcess);
}
}
with :
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId);
public const int PROCESS_VM_READ = (0x0010);
public const int PROCESS_QUERY_INFORMATION = (0x0400);
public const int PROCESS_QUERY_LIMITED_INFORMATION = (0x1000);
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool QueryFullProcessImageName(IntPtr hProcess, int dwFlags, StringBuilder lpExeName, ref uint lpdwSize);
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool CloseHandle(IntPtr hObject);
[DllImport("psapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumProcessModulesEx([In] IntPtr hProcess,[Out] IntPtr[] lphModule, [In] int cb,
[Out] out int lpcbNeeded,[In] MODULEFILTERFLAGS dwFilterFlag);
[Flags]
public enum MODULEFILTERFLAGS
{
LIST_MODULES_DEFAULT = 0x0,
LIST_MODULES_32BIT = 0x01,
LIST_MODULES_64BIT = 0x02,
LIST_MODULES_ALL = 0x03,
}
[DllImport("psapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint GetModuleFileNameEx([In] IntPtr hProcess, [In] IntPtr hModule,
[Out][MarshalAs(UnmanagedType.LPTStr)] System.Text.StringBuilder lpFilename, uint nSize);