C# 如何以托管方式获取.NET中的父进程
我一直在寻找在.NET中获取父进程的方法,但只找到了p/Invoke方式。这段代码为查找父进程对象提供了一个很好的界面,并考虑了多个进程使用相同名称的可能性: 用法:C# 如何以托管方式获取.NET中的父进程,c#,process,pinvoke,parent,managed,C#,Process,Pinvoke,Parent,Managed,我一直在寻找在.NET中获取父进程的方法,但只找到了p/Invoke方式。这段代码为查找父进程对象提供了一个很好的界面,并考虑了多个进程使用相同名称的可能性: 用法: Console.WriteLine("ParentPid: " + Process.GetProcessById(6972).Parent().Id); 代码: 公共静态类ProcessExtensions{ 私有静态字符串FindIndexedProcessName(int-pid){ var processName=Proc
Console.WriteLine("ParentPid: " + Process.GetProcessById(6972).Parent().Id);
代码:
公共静态类ProcessExtensions{
私有静态字符串FindIndexedProcessName(int-pid){
var processName=Process.GetProcessById(pid).processName;
var processesByName=Process.GetProcessesByName(processName);
字符串processIndexdName=null;
for(var index=0;index
此代码为查找父进程对象提供了一个良好的界面,并考虑了多个进程同名的可能性:
用法:
Console.WriteLine("ParentPid: " + Process.GetProcessById(6972).Parent().Id);
代码:
公共静态类ProcessExtensions{
私有静态字符串FindIndexedProcessName(int-pid){
var processName=Process.GetProcessById(pid).processName;
var processesByName=Process.GetProcessesByName(processName);
字符串processIndexdName=null;
for(var index=0;index
这里有一个解决方案。它使用p/invoke,但在32或64 cpu的情况下似乎运行良好:
/// <summary>
/// A utility class to determine a process parent.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct ParentProcessUtilities
{
// These members must match PROCESS_BASIC_INFORMATION
internal IntPtr Reserved1;
internal IntPtr PebBaseAddress;
internal IntPtr Reserved2_0;
internal IntPtr Reserved2_1;
internal IntPtr UniqueProcessId;
internal IntPtr InheritedFromUniqueProcessId;
[DllImport("ntdll.dll")]
private static extern int NtQueryInformationProcess(IntPtr processHandle, int processInformationClass, ref ParentProcessUtilities processInformation, int processInformationLength, out int returnLength);
/// <summary>
/// Gets the parent process of the current process.
/// </summary>
/// <returns>An instance of the Process class.</returns>
public static Process GetParentProcess()
{
return GetParentProcess(Process.GetCurrentProcess().Handle);
}
/// <summary>
/// Gets the parent process of specified process.
/// </summary>
/// <param name="id">The process id.</param>
/// <returns>An instance of the Process class.</returns>
public static Process GetParentProcess(int id)
{
Process process = Process.GetProcessById(id);
return GetParentProcess(process.Handle);
}
/// <summary>
/// Gets the parent process of a specified process.
/// </summary>
/// <param name="handle">The process handle.</param>
/// <returns>An instance of the Process class.</returns>
public static Process GetParentProcess(IntPtr handle)
{
ParentProcessUtilities pbi = new ParentProcessUtilities();
int returnLength;
int status = NtQueryInformationProcess(handle, 0, ref pbi, Marshal.SizeOf(pbi), out returnLength);
if (status != 0)
throw new Win32Exception(status);
try
{
return Process.GetProcessById(pbi.InheritedFromUniqueProcessId.ToInt32());
}
catch (ArgumentException)
{
// not found
return null;
}
}
}
//
///用于确定进程父级的实用程序类。
///
[StructLayout(LayoutKind.Sequential)]
公共结构ParentProcessUtilities
{
//这些成员必须与流程基本信息匹配
内部IntPtr储备1;
内部IntPtr PebBaseAddress;
内部IntPtr预留2_0;
内部IntPtr储备2_1;
内部IntPtr UniqueProcessId;
从UniqueProcessId继承的内部IntPtr;
[DllImport(“ntdll.dll”)]
私有静态外部int NtQueryInformationProcess(IntPtr processHandle、int processInformationClass、ref ParentProcessUtilities processInformation、int processInformationLength、out int returnLength);
///
///获取当前进程的父进程。
///
///进程类的实例。
公共静态进程GetParentProcess()
{
返回GetParentProcess(Process.GetCurrentProcess().Handle);
}
///
///获取指定进程的父进程。
///
///进程id。
///进程类的实例。
公共静态进程GetParentProcess(int id)
{
Process=Process.GetProcessById(id);
返回GetParentProcess(process.Handle);
}
///
///获取指定进程的父进程。
///
///这个过程需要处理。
///进程类的实例。
公共静态进程GetParentProcess(IntPtr句柄)
{
ParentProcessUtilities pbi=新的ParentProcessUtilities();
返回长度;
int status=NtQueryInformationProcess(句柄,0,ref-pbi,Marshal.SizeOf(pbi),out-returnLength);
如果(状态!=0)
抛出新的Win32Exception(状态);
尝试
{
返回Process.GetProcessById(pbi.InheritedFromUniqueProcessId.ToInt32());
}
捕获(异常)
{
//找不到
返回null;
}
}
}
这里有一个解决方案。它使用p/invoke,但在32或64 cpu的情况下似乎运行良好:
/// <summary>
/// A utility class to determine a process parent.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct ParentProcessUtilities
{
// These members must match PROCESS_BASIC_INFORMATION
internal IntPtr Reserved1;
internal IntPtr PebBaseAddress;
internal IntPtr Reserved2_0;
internal IntPtr Reserved2_1;
internal IntPtr UniqueProcessId;
internal IntPtr InheritedFromUniqueProcessId;
[DllImport("ntdll.dll")]
private static extern int NtQueryInformationProcess(IntPtr processHandle, int processInformationClass, ref ParentProcessUtilities processInformation, int processInformationLength, out int returnLength);
/// <summary>
/// Gets the parent process of the current process.
/// </summary>
/// <returns>An instance of the Process class.</returns>
public static Process GetParentProcess()
{
return GetParentProcess(Process.GetCurrentProcess().Handle);
}
/// <summary>
/// Gets the parent process of specified process.
/// </summary>
/// <param name="id">The process id.</param>
/// <returns>An instance of the Process class.</returns>
public static Process GetParentProcess(int id)
{
Process process = Process.GetProcessById(id);
return GetParentProcess(process.Handle);
}
/// <summary>
/// Gets the parent process of a specified process.
/// </summary>
/// <param name="handle">The process handle.</param>
/// <returns>An instance of the Process class.</returns>
public static Process GetParentProcess(IntPtr handle)
{
ParentProcessUtilities pbi = new ParentProcessUtilities();
int returnLength;
int status = NtQueryInformationProcess(handle, 0, ref pbi, Marshal.SizeOf(pbi), out returnLength);
if (status != 0)
throw new Win32Exception(status);
try
{
return Process.GetProcessById(pbi.InheritedFromUniqueProcessId.ToInt32());
}
catch (ArgumentException)
{
// not found
return null;
}
}
}
//
///用于确定进程父级的实用程序类。
///
[StructLayout(LayoutKind.Sequential)]
公共结构ParentProcessUtilities
{
//这些成员必须与流程基本信息匹配
内部IntPtr储备1;
内部IntPtr PebBaseAddress;
内部IntPtr预留2_0;
内部IntPtr储备2_1;
内部IntPtr UniqueProcessId;
从UniqueProcessId继承的内部IntPtr;
[DllImport(“ntdll.dll”)]
私有静态外部int NtQueryInformationProcess(IntPtr processHandle、int processInformationClass、ref ParentProcessUtilities processInformation、int processInformationLength、out int returnLength);
///
///获取当前进程的父进程。
///
///进程类的实例。
公共静态进程GetParentProcess()
{
返回GetParentProcess(Process.GetCurrentProcess().Handle);
}
///
///获取指定进程的父进程。
///
///进程id。
///进程类的实例。
公共静态进程GetParentProcess(int id)
{
Process=Process.GetProcessById(id);
返回
public static Process GetParent(this Process process)
{
try
{
using (var query = new ManagementObjectSearcher(
"SELECT * " +
"FROM Win32_Process " +
"WHERE ProcessId=" + process.Id))
{
return query
.Get()
.OfType<ManagementObject>()
.Select(p => Process.GetProcessById((int)(uint)p["ParentProcessId"]))
.FirstOrDefault();
}
}
catch
{
return null;
}
}
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Linq;
using System;
public static class Toolhelp32 {
public const uint Inherit = 0x80000000;
public const uint SnapModule32 = 0x00000010;
public const uint SnapAll = SnapHeapList|SnapModule|SnapProcess|SnapThread;
public const uint SnapHeapList = 0x00000001;
public const uint SnapProcess = 0x00000002;
public const uint SnapThread = 0x00000004;
public const uint SnapModule = 0x00000008;
[DllImport("kernel32.dll")]
static extern bool CloseHandle(IntPtr handle);
[DllImport("kernel32.dll")]
static extern IntPtr CreateToolhelp32Snapshot(uint flags, int processId);
public static IEnumerable<T> TakeSnapshot<T>(uint flags, int id) where T : IEntry, new() {
using(var snap = new Snapshot(flags, id))
for(IEntry entry = new T { }; entry.TryMoveNext(snap, out entry);)
yield return (T)entry;
}
public interface IEntry {
bool TryMoveNext(Toolhelp32.Snapshot snap, out IEntry entry);
}
public struct Snapshot:IDisposable {
void IDisposable.Dispose() {
Toolhelp32.CloseHandle(m_handle);
}
public Snapshot(uint flags, int processId) {
m_handle=Toolhelp32.CreateToolhelp32Snapshot(flags, processId);
}
IntPtr m_handle;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct WinProcessEntry:Toolhelp32.IEntry {
[DllImport("kernel32.dll")]
public static extern bool Process32Next(Toolhelp32.Snapshot snap, ref WinProcessEntry entry);
public bool TryMoveNext(Toolhelp32.Snapshot snap, out Toolhelp32.IEntry entry) {
var x = new WinProcessEntry { dwSize=Marshal.SizeOf(typeof(WinProcessEntry)) };
var b = Process32Next(snap, ref x);
entry=x;
return b;
}
public int dwSize;
public int cntUsage;
public int th32ProcessID;
public IntPtr th32DefaultHeapID;
public int th32ModuleID;
public int cntThreads;
public int th32ParentProcessID;
public int pcPriClassBase;
public int dwFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public String fileName;
//byte fileName[260];
//public const int sizeofFileName = 260;
}
public static class Extensions {
public static Process Parent(this Process p) {
var entries = Toolhelp32.TakeSnapshot<WinProcessEntry>(Toolhelp32.SnapAll, 0);
var parentid = entries.First(x => x.th32ProcessID==p.Id).th32ParentProcessID;
return Process.GetProcessById(parentid);
}
}
public class TestClass {
public static void TestMethod() {
var p = Process.GetCurrentProcess().Parent();
Console.WriteLine("{0}", p.Id);
}
}
[StructLayout(LayoutKind.Sequential)]
public struct WinModuleEntry:Toolhelp32.IEntry { // MODULEENTRY32
[DllImport("kernel32.dll")]
public static extern bool Module32Next(Toolhelp32.Snapshot snap, ref WinModuleEntry entry);
public bool TryMoveNext(Toolhelp32.Snapshot snap, out Toolhelp32.IEntry entry) {
var x = new WinModuleEntry { dwSize=Marshal.SizeOf(typeof(WinModuleEntry)) };
var b = Module32Next(snap, ref x);
entry=x;
return b;
}
public int dwSize;
public int th32ModuleID;
public int th32ProcessID;
public int GlblcntUsage;
public int ProccntUsage;
public IntPtr modBaseAddr;
public int modBaseSize;
public IntPtr hModule;
//byte moduleName[256];
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string moduleName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string fileName;
//byte fileName[260];
//public const int sizeofModuleName = 256;
//public const int sizeofFileName = 260;
}
public class TestClass {
public static void TestMethod() {
var p = Process.GetCurrentProcess().Parent();
Console.WriteLine("{0}", p.Id);
var formatter = new CustomFormatter { };
foreach(var x in Toolhelp32.TakeSnapshot<WinModuleEntry>(Toolhelp32.SnapModule, p.Id)) {
Console.WriteLine(String.Format(formatter, "{0}", x));
}
}
}
public class CustomFormatter:IFormatProvider, ICustomFormatter {
String ICustomFormatter.Format(String format, object arg, IFormatProvider formatProvider) {
var type = arg.GetType();
var fields = type.GetFields();
var q = fields.Select(x => String.Format("{0}:{1}", x.Name, x.GetValue(arg)));
return String.Format("{{{0}}}", String.Join(", ", q.ToArray()));
}
object IFormatProvider.GetFormat(Type formatType) {
return typeof(ICustomFormatter)!=formatType ? null : this;
}
}