c#读取 Window系统 指定进程的相关信息,内存,线程数等

发布于:2025-08-05 ⋅ 阅读:(12) ⋅ 点赞:(0)
using NLog;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace PerformanceMonitoring
{
    class ProcessMonitor
    {
        /// <summary>
        /// 进程Name
        /// </summary>
        private readonly string _processName;
        private bool _isRunning;
        private readonly string _logFolder;
        private readonly Dictionary<int, DateTime> _lastCpuTime = new Dictionary<int, DateTime>();
        private readonly Dictionary<int, TimeSpan> _lastCpuUsage = new Dictionary<int, TimeSpan>();
        private readonly Dictionary<int, long> _lastPrivateBytes = new Dictionary<int, long>();
        private string MonitorTime= ConfigurationManager.AppSettings["MonitorTime"];
        public ProcessMonitor(string processName)
        {
            _processName = processName;
            _logFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");

            // 确保日志目录存在
            Directory.CreateDirectory(_logFolder);
        }

        /// <summary>
        /// 开启监控
        /// </summary>
        public void Start()
        {
            if (_isRunning)
            {
                return;
            }
            _isRunning = true;
            WriteLog("INFO", $"开始监控进程: {_processName}");
            WriteLog("DATA", "时间,进程ID,CPU使用率(%),线程数,内存使用(MB)");

            // 启动监控线程
            new Thread(MonitorLoop) { IsBackground = true }.Start();
        }


        private void MonitorLoop()
        {
            while (_isRunning)
            {
                try
                {
                    // 获取所有目标进程
                    //var ss=Process.GetProcesses();
                    var process = Process.GetProcessesByName(_processName).FirstOrDefault();
                    if (process == null)
                    {
                        //WriteLog("WARN", $"未找到进程: {_processName}");
                    }
                    else
                    {
                        MonitorProcess(process);
                    }
                }
                catch (Exception ex)
                {
                    WriteLog("ERROR", $"监控错误: {ex.Message}");
                }

                // 等待下一次监控
                Thread.Sleep(Convert.ToInt32( MonitorTime));
            }
        }

        private void MonitorProcess(Process process)
        {
            try
            {
                // 刷新进程信息
                process.Refresh();

                // 计算CPU使用率
                double cpuUsage = CalculateCpuUsage(process);

                // 获取多种内存指标
                double privateWorkingSetMB = GetPrivateWorkingSet(process.Id) / (1024.0 * 1024.0);



                double workingSetMB = process.WorkingSet64 / (1024.0 * 1024.0);
                double privateBytesMB = GetPrivateBytes(process.Id) / (1024.0 * 1024.0);
                double virtualMemoryMB = process.VirtualMemorySize64 / (1024.0 * 1024.0);

                // 记录数据
                WriteLog("DATA", $"{DateTime.Now:yyyy-MM-dd HH:mm:ss}," +
                                 $"-----【进程ID】:{process.Id}," +
                                 $"-----【内存占用率】:{cpuUsage:F1}," +
                                 $"-----【线程数量】:{process.Threads.Count}," +
                                 $"-----【工作内存】:{workingSetMB:F2}," +
                                 $"-----【私有内存】:{privateBytesMB:F2}," +
                                 $"-----【共享内存】:{virtualMemoryMB:F2}" +
                                 $"-----【显示】:{privateWorkingSetMB:F2}");

            }
            catch (InvalidOperationException)
            {
                // 进程已退出
                WriteLog("INFO", $"进程已退出: {process.Id}");
            }
            catch (Exception ex)
            {
                WriteLog("ERROR", $"进程监控错误: {ex.Message}");
            }
        }


        private long GetPrivateWorkingSet(int processId)
        {
            try
            {
                string instanceName = GetProcessInstanceName(processId);
                if (string.IsNullOrEmpty(instanceName))
                    return 0;

                using (var pc = new PerformanceCounter("Process", "Working Set - Private", instanceName))
                {
                    return (long)pc.NextValue();
                }
            }
            catch
            {
                // 回退到标准工作集
                try
                {
                    var process = Process.GetProcessById(processId);
                    return process.WorkingSet64;
                }
                catch
                {
                    return 0;
                }
            }
        }



        private long GetPrivateBytes(int processId)
        {
            // 使用性能计数器获取更准确的私有内存
            try
            {
                if (!_lastPrivateBytes.ContainsKey(processId))
                {
                    _lastPrivateBytes[processId] = 0;
                }

                using (var pc = new PerformanceCounter("Process", "Private Bytes", GetProcessInstanceName(processId)))
                {
                    long bytes = (long)pc.NextValue();
                    _lastPrivateBytes[processId] = bytes;
                    return bytes;
                }
            }
            catch
            {
                // 回退到上次记录的值
                return _lastPrivateBytes.ContainsKey(processId) ? _lastPrivateBytes[processId] : 0;
            }
        }

        private string GetProcessInstanceName(int pid)
        {
            var process = Process.GetProcessById(pid);
            string processName = Path.GetFileNameWithoutExtension(process.ProcessName);

            PerformanceCounterCategory cat = new PerformanceCounterCategory("Process");
            string[] instances = cat.GetInstanceNames()
                .Where(inst => inst.StartsWith(processName))
                .ToArray();

            foreach (string instance in instances)
            {
                using (PerformanceCounter cnt = new PerformanceCounter("Process", "ID Process", instance, true))
                {
                    if ((int)cnt.RawValue == pid)
                    {
                        return instance;
                    }
                }
            }
            return "";
        }


        private double CalculateCpuUsage2(Process process)
        {
            // 获取进程的CPU时间
            TimeSpan userTime = TimeSpan.FromMilliseconds(process.UserProcessorTime.TotalMilliseconds);
            TimeSpan kernelTime = TimeSpan.FromMilliseconds(process.TotalProcessorTime.TotalMilliseconds - process.UserProcessorTime.TotalMilliseconds);
            double cpuUsage = (userTime.TotalSeconds + kernelTime.TotalSeconds) / process.PrivilegedProcessorTime.TotalSeconds * 100;
            return cpuUsage;
        }
      








        /// <summary>
        /// cpu使用率
        /// </summary>
        /// <param name="process"></param>
        /// <returns></returns>
        private double CalculateCpuUsage(Process process)
        {
            var now = DateTime.Now;
            var currentCpuTime = process.TotalProcessorTime;

            if (!_lastCpuTime.ContainsKey(process.Id) || !_lastCpuUsage.ContainsKey(process.Id))
            {
                // 首次记录
                _lastCpuTime[process.Id] = now;
                _lastCpuUsage[process.Id] = currentCpuTime;
                return 0;
            }

            // 计算时间差和CPU使用差
            var timeDiff = (now - _lastCpuTime[process.Id]).TotalSeconds;
            var cpuDiff = (currentCpuTime - _lastCpuUsage[process.Id]).TotalMilliseconds;

            // 更新记录
            _lastCpuTime[process.Id] = now;
            _lastCpuUsage[process.Id] = currentCpuTime;

            // 计算CPU使用率 (总CPU时间差 / 时间差 / 核心数 * 100)
            return (cpuDiff / (timeDiff * 1000) / Environment.ProcessorCount) * 100;
        }

        public void Stop()
        {
            _isRunning = false;
            WriteLog("INFO", "监控已停止");
        }



        private void WriteLog(string logType, string message)
        {
            try
            {
                string logFile = Path.Combine(_logFolder, $"{_processName}-{DateTime.Today:yyyyMMdd}.log");
                string logEntry = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] [{logType}] {message}";
                File.AppendAllText(logFile, logEntry + Environment.NewLine);
            }
            catch (Exception ex)
            {
                try
                {
                    string fallbackFile = Path.Combine(_logFolder, "monitor-fallback.log");
                    File.AppendAllText(fallbackFile, $"[{DateTime.Now}] 日志写入失败: {ex.Message}");
                }
                catch
                {
                }
            }
        }
    }
}

namespace PerformanceMonitoring
{
    using System;
    using System.Configuration;

    public static class ConfigHelper
    {
        public static string GetString(string key, string defaultValue = "")
        {
            try
            {
                var value = ConfigurationManager.AppSettings[key];
                return string.IsNullOrWhiteSpace(value) ? defaultValue : value;
            }
            catch (Exception ex)
            {
                // 记录错误(实际应用中应使用日志库)
                Console.WriteLine($"读取配置错误 [{key}]: {ex.Message}");
                return defaultValue;
            }
        }

        public static int GetInt(string key, int defaultValue = 0)
        {
            var value = GetString(key);
            if (int.TryParse(value, out int result))
            {
                return result;
            }
            return defaultValue;
        }

        public static bool GetBool(string key, bool defaultValue = false)
        {
            var value = GetString(key).ToLower();
            if (value == "true" || value == "1" || value == "yes")
            {
                return true;
            }
            if (value == "false" || value == "0" || value == "no")
            {
                return false;
            }
            return defaultValue;
        }
        public static double GetDouble(string key, double defaultValue = 0.0)
        {
            var value = GetString(key);
            if (double.TryParse(value, out double result))
            {
                return result;
            }
            return defaultValue;
        }


        public static TimeSpan GetTimeSpan(string key, TimeSpan defaultValue)
        {
            var value = GetString(key);
            if (TimeSpan.TryParse(value, out TimeSpan result))
            {
                return result;
            }
            return defaultValue;
        }


        public static T GetEnum<T>(string key, T defaultValue) where T : struct
        {
            var value = GetString(key);
            if (Enum.TryParse(value, true, out T result))
            {
                return result;
            }
            return defaultValue;
        }

        public static string GetConnectionString(string name)
        {
            try
            {
                var connectionString = ConfigurationManager.ConnectionStrings[name];
                return connectionString?.ConnectionString ?? string.Empty;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"读取连接字符串错误 [{name}]: {ex.Message}");
                return string.Empty;
            }
        }
    }
}

using NLog;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace PerformanceMonitoring
{
    internal class Program
    {

   

        static void Main(string[] args)
        {
            string processName = ConfigurationManager.AppSettings["ProcessName"];
            // string processName = "ConsoleApp3"; 
            
            var monitor = new ProcessMonitor(processName);
            monitor.Start();
            var exitEvent = new ManualResetEvent(false);
            Console.CancelKeyPress += (sender, e) => {
                e.Cancel = true; // 防止立即退出
                exitEvent.Set();
            };
            exitEvent.WaitOne();
            monitor.Stop();
        }

    }
}

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
    </startup>
	<appSettings>
		<add key="ProcessName" value="ConsoleApp3"/>
		<add key="MonitorTime" value="1000"/>
	</appSettings>
</configuration>

网站公告

今日签到

点亮在社区的每一天
去签到