解決策は、64ビットプロセスを実行しており、32ビットプロセスからすべてのモジュールを収集しようとすると、不十分です。デフォルトでは、64ビットは64ビットプロセスでのみ動作し、32ビットは32ビットプロセスでのみ動作します。
「AnyCPU」、「x86」、および「x64」で動作するソリューションの場合は、ターゲットプロセスでCollectModules
関数を呼び出します(以下を参照)。注:32ビットプロセスから64ビットモジュールを収集することはできません。
public List<Module> CollectModules(Process process)
{
List<Module> collectedModules = new List<Module>();
IntPtr[] modulePointers = new IntPtr[0];
int bytesNeeded = 0;
// Determine number of modules
if (!Native.EnumProcessModulesEx(process.Handle, modulePointers, 0, out bytesNeeded, (uint)Native.ModuleFilter.ListModulesAll))
{
return collectedModules;
}
int totalNumberofModules = bytesNeeded/IntPtr.Size;
modulePointers = new IntPtr[totalNumberofModules];
// Collect modules from the process
if (Native.EnumProcessModulesEx(process.Handle, modulePointers, bytesNeeded, out bytesNeeded, (uint)Native.ModuleFilter.ListModulesAll))
{
for (int index = 0; index < totalNumberofModules; index++)
{
StringBuilder moduleFilePath = new StringBuilder(1024);
Native.GetModuleFileNameEx(process.Handle, modulePointers[index], moduleFilePath, (uint)(moduleFilePath.Capacity));
string moduleName = Path.GetFileName(moduleFilePath.ToString());
Native.ModuleInformation moduleInformation = new Native.ModuleInformation();
Native.GetModuleInformation(process.Handle, modulePointers[index], out moduleInformation, (uint)(IntPtr.Size * (modulePointers.Length)));
// Convert to a normalized module and add it to our list
Module module = new Module(moduleName, moduleInformation.lpBaseOfDll, moduleInformation.SizeOfImage);
collectedModules.Add(module);
}
}
return collectedModules;
}
}
public class Native
{
[StructLayout(LayoutKind.Sequential)]
public struct ModuleInformation
{
public IntPtr lpBaseOfDll;
public uint SizeOfImage;
public IntPtr EntryPoint;
}
internal enum ModuleFilter
{
ListModulesDefault = 0x0,
ListModules32Bit = 0x01,
ListModules64Bit = 0x02,
ListModulesAll = 0x03,
}
[DllImport("psapi.dll")]
public static extern bool EnumProcessModulesEx(IntPtr hProcess, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U4)] [In][Out] IntPtr[] lphModule, int cb, [MarshalAs(UnmanagedType.U4)] out int lpcbNeeded, uint dwFilterFlag);
[DllImport("psapi.dll")]
public static extern uint GetModuleFileNameEx(IntPtr hProcess, IntPtr hModule, [Out] StringBuilder lpBaseName, [In] [MarshalAs(UnmanagedType.U4)] uint nSize);
[DllImport("psapi.dll", SetLastError = true)]
public static extern bool GetModuleInformation(IntPtr hProcess, IntPtr hModule, out ModuleInformation lpmodinfo, uint cb);
}
public class Module
{
public Module(string moduleName, IntPtr baseAddress, uint size)
{
this.ModuleName = moduleName;
this.BaseAddress = baseAddress;
this.Size = size;
}
public string ModuleName { get; set; }
public IntPtr BaseAddress { get; set; }
public uint Size { get; set; }
}
この回答は部分的に正しいです。あなたのコードは、LoadLibrary()によってロードされたネイティブDLLのみをリストします。しかし、System.Windows.Forms.dllのような.NETフレームワークDLLは、Framework 4.7にリストされません。なぜなら、フレームワークはLoadLibrary()を使用してそれらをロードしないからです。 http://blogs.microsoft.co.il/sasha/2011/01/16/clr-4-does-not-use-loadlibrary-to-load-assembliesを参照してください。 – Elmue