Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何以托管方式获取.NET中的父进程_C#_Process_Pinvoke_Parent_Managed - Fatal编程技术网

C# 如何以托管方式获取.NET中的父进程

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

我一直在寻找在.NET中获取父进程的方法,但只找到了p/Invoke方式。

这段代码为查找父进程对象提供了一个很好的界面,并考虑了多个进程使用相同名称的可能性:

用法:

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;
    }
}