C#程序中获取当前进程的父进程Pid

在大多数情况下,直接获取父进程并不是可行的,因为.NET框架本身并不直接提供获取父进程的内置方法。通常,父进程的概念更多地是在操作系统层面上定义的(如在Windows中通过创建进程的方式来关联父子关系),而不是在.NET环境中直接暴露的,需要调用Windows的API来实现。

然而,对于某些特殊情况(例如,在某些类型的进程中,如某些服务或特定的应用程序框架中),你可以尝试以下替代方法:

方法1: 使用WMI (Windows Management Instrumentation)

如果你确实需要获取父进程信息,特别是在Windows环境下,你可以使用WMI来查询。这通常涉及查询Windows事件日志或使用特定的系统API。例如,使用WMI查询父进程ID:

using System;
using System.Management;
 
public static int? GetParentProcessId(int processId)
{
    string query = $"SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {processId}";
    using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
    {
        foreach (ManagementObject obj in searcher.Get())
        {
            return (int)obj["ParentProcessId"];
        }
    }
    return null; // 如果没有找到或者不支持,返回null
}

方法2: 使用第三方库或工具(例如 PsGetParentProcessId)

对于某些特定的场景,你可能需要使用第三方库或者调用特定的系统API(如Windows API)来获取父进程信息。例如,可以使用一些第三方库如SharpShell或者通过P/Invoke调用Windows API如NtQueryInformationProcess。这些方法比较复杂且依赖于特定的环境和权限设置。

结论

在标准的.NET环境中,直接通过Process类获取父进程的ID并不直接支持。通常需要通过WMI查询或使用特定的系统调用/第三方库来实现。选择哪种方法取决于你的具体需求和环境限制。如果你的需求是普通的桌面应用程序,并且不需要深入到操作系统级别,那么直接使用WMI查询通常是最简单的方法。对于更复杂或特殊的需求,考虑使用P/Invoke等技术调用底层API。

 

出处:百度AI搜索

=======================================================================================

WinForm--使用C#制做进程监视器

总览

1)可以查看进程的各项基本信息,如 cpu ,内存,父进程,执行路径,创建者等
2 )可以中止进程,创建新进程
3 )可以配置目标进程,配置刷新速度
最终效果图:

(以下给出部分代码,其余像进程的创建、中止等,使用process类将很容易实现)

1)使用wmi获取父进程id,进程创建者

(注意,使用wmi获得的内容,不宜循环刷新,这样代价比较大)
添加命名空间:
using System.Management;
        /// <summary>
        /// 使用Wmi获取指定进程的创建者等信息
        /// </summary>
        /// <param name="pID">进程ID</param>
        private void FillDetailUseWmi(int pID)
        {
            ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * From Win32_Process Where ProcessID="
+ pID);
            ManagementObjectCollection moc = searcher.Get();

            ManagementOperationObserver observer = new ManagementOperationObserver();
            HandleObjectReady hor = new HandleObjectReady();
            //监测异步方法是否已成功返回
            observer.ObjectReady += new ObjectReadyEventHandler(hor.Done);

            foreach (ManagementObject mo in moc)
            {
                //异步调用该对象的GetOwner方法,获取进程创建者
                mo.InvokeMethod(observer, "GetOwner", null);
                //等待异步调用返回
                while (!hor.Complete)
                {
                    System.Threading.Thread.Sleep(500);
                }

                string user = "";
                //判断获取用户名的操作是否成功
                if (hor.Obj["returnValue"].ToString() == "0")
                {
                    user = hor.Obj.Properties["User"].Value.ToString();
                }
                //判断字典中是否已移除该项
                if (!this.mDict.ContainsKey(pID))
                {
                    return;
                }
                if (mo["ParentProcessID"] != null && this.mDict.ContainsKey(Convert.ToInt32(mo["ParentProcessID"])))
                {
                    //根据父进程ID获取父进程名称
                    this.mDict[pID].ParentProce = this.mDict[Convert.ToInt32(mo["ParentProcessID"])].ProceName;
                }
                this.mDict[pID].Creator = user;

                //触发刷新进程详细信息事件
                if (this.HandleDetailList != null)
                {
                    this.HandleDetailList(this.mDict[pID]);
                }
            }

            //释放资源
            searcher.Dispose();
            searcher = null;
            moc.Dispose();
            moc = null;
            observer = null;
            hor = null;
        }


    /// <summary>
    /// 该类用于监测Wmi异步调用方法是否已经返回
    /// </summary>
    public class HandleObjectReady
    {
        private bool complete = false;
        private ManagementBaseObject obj;

        public void Done(object sender, ObjectReadyEventArgs e)
        {
            complete = true;
            obj = e.NewObject;
        }

        public bool Complete
        {
            get
            {
                return complete;
            }
        }

        public ManagementBaseObject Obj
        {
            get
            {
                return obj;
            }
        }
    }

 

2)使用性能计数器计算cpu利用率

2.1)计算过程

//通过计数器获取idle空闲进程cpu占用率r1
//通过process类的TotalProcessorTime属性获取各进程的cpu时间,求和,得各进程(除空闲进程idle,该进程无法通过process类获得cpu时间)cpu时间和t1
//通过t1/(100-r1)得到总cpu时间t
//对各进程,通过TotalProcessorTime获得进程cpu时间tnew,计算:
(Tnew-told)/t,即得该进程的cpu占用率,其中told是程序中记录的该进程上一次的TotalProcessorTime

2.2)关于性能计数器

系统会为每个进程分配一个计数器,通过
new PerformanceCounter("Process", "% Processor Time", "进程名称")实例化该计数器,使用计数器对象的NextValue方法可以得到进程占用cpu的百分比(第一次调用NextValue获取的值都为0,之后就没问题了,这个要注意)。

2.3)Idle进程的含义

Idle意为懒散的、无所事事。事实上,idle不能算着一个进程,它用于表示cpu空闲资源,它所占的比率越高,表示你的机器越空闲。

2.4)多核CPU或使用超线程技术的CPU

对于多核或使用超线程技术的cpu,根据计数器求得的idle进程cpu占用比率将超过100%,此时应将idlecpu利用率/总的cpu利用率,所得作为真正的idlecpu利用率。
添加命名空间:
using System.Diagnostics;
        /// <summary>
        /// 性能计数器,用于获取CPU空闲百分比
        /// </summary>
        private static PerformanceCounter mIdle = new PerformanceCounter("Process", "% Processor Time", "Idle");
        /// <summary>
        /// 性能计数器,用于获取CPU总利用率
        /// </summary>
        private static PerformanceCounter mTotal = new PerformanceCounter("Process", "% Processor Time", "_Total");

        private void FillNeedRefreshInfo(params Process[] pCurrentAll)
        {
            …………
            //以下计算CPU利用率
            this.mCurrentTotalCpuTime = this.CalCurrentTotalCpuTime();
            for (int i = 0; i < pCurrentAll.Length; i++)
            {
                //空闲进程idle
                if (pCurrentAll.Id == 0)
                {
                    this.mDict[pCurrentAll.Id].CpuPercent = this.mIdleCpuPercent;
                }
                else
                {
                    try
                    {
                        //无法保证进程不会中途退出,此时无法获取其Cpu时间
                        long ms = (long)pCurrentAll.TotalProcessorTime.TotalMilliseconds;
                        double d = (ms - this.mDict[pCurrentAll.Id].OldCpuTime) * 1.0 / this.mCurrentTotalCpuTime;
                        this.mDict[pCurrentAll.Id].CpuPercent = d;
                        this.mDict[pCurrentAll.Id].OldCpuTime = ms;
                    }
                    catch
                    {
                    }
                }

                //调用刷新事件
                if (this.HandleProceRefresh != null)
                {
                    this.HandleProceRefresh(this.mDict[pCurrentAll.Id], 100 - this.mIdleCpuPercent);
                }
            }
        }


        private double CalCurrentTotalCpuTime()
        {
            double d = 0;
            //获取性能计数器值
            double idlePercent = mIdle.NextValue();
            double totalPercent = mTotal.NextValue();
            //避免除0异常
            if (totalPercent == 0)
            {
                this.mIdleCpuPercent = 0;
            }
            else
            {
                //可能遇到多核或超线程CPU,CPU空闲进程比率不能直接使用计数器的值
                this.mIdleCpuPercent = idlePercent * 100 / totalPercent;
            }

            //以下获取上一次计算至当前总的非空闲CPU时间
            foreach (Process p in this.mCurrentAll)
            {
                //对空闲进程及中途退出的进程不做处理
                if (p.Id == 0 || p.HasExited)
                {
                    continue;
                }

                if (this.mDict ==null || !this.mDict.ContainsKey(p.Id))
                {
                    d += p.TotalProcessorTime.TotalMilliseconds;
                }
                else
                {
                    d += p.TotalProcessorTime.TotalMilliseconds - this.mDict[p.Id].OldCpuTime;
                }
            }

            //当前非空闲CPU时间/当前非空闲时间所占比率=当前总CPU时间
            //return d / (totalPercent - idlePercent);
            return d / (100 - mIdleCpuPercent);
        }

 

2025-06-06 15:56:29【出处】:https://www.cnblogs.com/fwj380891124/p/16946725.html

=======================================================================================

posted on 2025-06-06 15:47  jack_Meng  阅读(138)  评论(0)    收藏  举报

导航