笔者的九篇反射系统文章已经完结,但是笔者会持续更新反射在日常撸码中的应用。

本篇内容主要是 .NET Core 获取运行环境信息、利用反射更加方便地处理数据。

本篇内容有:RuntimeInformation、Environment、反射、特性等。

本篇代码下载地址 https://gitee.com/whuanle/reflection_and_properties/blob/master/反射特性应用场景1.cs

获取示例:

笔者的九篇反射系列文章阅读地址如下:

C# 反射与特性(一):反射基础

C# 反射与特性(二):探究反射

C# 反射与特性(三):反射类型的成员

C# 反射与特性(四):实例化类型

C# 反射与特性(五):类型成员操作

C# 反射与特性(六):实现 ASP.NET Core 依赖注入 Web

C# 反射与特性(七):自定义特性以及应用

C# 反射与特性(八):反射操作实例大全

C# 反射与特性(九):解析反射实例大全

RuntimeInformation、Environment

RuntimeInformation 类提供有关 .NET 运行时安装的信息。主要获取平台以及 版本,API较少。

文档地址 https://docs.microsoft.com/zh-cn/dotnet/api/system.runtime.interopservices.runtimeinformation?view=netcore-3.1

Environment 提供有关当前环境和平台的信息以及操作它们的方法。API比较多。

文档地址 https://docs.microsoft.com/zh-cn/dotnet/api/system.environment?view=netcore-3.1

以上两个类已经提供了文档地址,这里不再赘述。

需要注意的是,Windows、Linux 之间有差异,因此有些 API 是无法跨平台的。另外 .NET Core 相对 .NET Framework ,对获取系统资源信息等的 API 十分少。

.NET Core 是无有 API 获取系统 CPU 情况和 内存使用情况,倒是可以获取当前进程的 CPU 和 内存使用情况。

可以查看 stackoverflow 了解。

https://stackoverflow.com/questions/54215334/how-to-measure-cpu-usage-and-memory-for-a-process-in-net-core-linux

获取信息

下面获取的属于进程使用的内存已经使用 CPU 时间。

CPU 时间不像直接获取到的 使用百分比,可以很直观地看到。

CPU 时间地公式如下。

CPU时间 = 执行程序所需的时钟周期数 * 时钟周期时间

CPU 有多核多线程,因此不能按照运行多长时间去计算。同时进程存在休眠、上下文切换等情况。

程序运行了几小时,有可能CPU时间只有几十分钟。

对 CPU 性能计算方法有兴趣,请参考 https://www.cnblogs.com/whuanle/p/12260224.html

对 Linux CPU 使用率计算有兴趣,请查看 https://www.cnblogs.com/aresxin/p/9152127.html

我们在 C# 中使用地代码如下

    [Display(Name = "运行信息")]
public class ApplicationRunInfo
{
private double _UsedMem;
private double _UsedCPUTime;
public ApplicationRunInfo()
{
var proc = Process.GetCurrentProcess();
var mem = proc.WorkingSet64;
var cpu = proc.TotalProcessorTime;
_UsedMem = mem / 1024.0;
_UsedCPUTime = cpu.TotalMilliseconds;
}
[Display(Name = "进程已使用物理内存(kb)")]
public double UsedMem { get { return _UsedMem; } }
[Display(Name = "进程已占耗CPU时间(ms)")]
public double UsedCPUTime { get { return _UsedCPUTime; } }
}

这里只有两个属性。

我们使用 Display 特性来标记此属性地的含义,方便反射时获取信息。

另外还有两个获取不同类型信息的类如下


[Display(Name = "系统运行平台")]
public class SystemPlatformInfo
{
[Display(Name = "运行框架")]
public string FrameworkDescription { get { return RuntimeInformation.FrameworkDescription; } }
[Display(Name = "操作系统")]
public string OSDescription { get { return RuntimeInformation.OSDescription; } }
[Display(Name = "操作系统版本")]
public string OSVersion { get { return Environment.OSVersion.ToString(); } }
[Display(Name = "平台架构")]
public string OSArchitecture { get { return RuntimeInformation.OSArchitecture.ToString(); } }
} [Display(Name = "运行环境")]
public class SystemRunEvnInfo
{
[Display(Name = "机器名称")]
public string MachineName { get { return Environment.MachineName; } }
[Display(Name = "用户网络域名")]
public string UserDomainName { get { return Environment.UserDomainName; } }
[Display(Name = "分区磁盘")]
public string GetLogicalDrives { get { return string.Join(", ", Environment.GetLogicalDrives()); } }
[Display(Name = "系统目录")]
public string SystemDirectory { get { return Environment.SystemDirectory; } }
[Display(Name = "系统已运行时间(毫秒)")]
public int TickCount { get { return Environment.TickCount; } } [Display(Name = "是否在交互模式中运行")]
public bool UserInteractive { get { return Environment.UserInteractive; } }
[Display(Name = "当前关联用户名")]
public string UserName { get { return Environment.UserName; } }
[Display(Name = "Web程序核心框架版本")]
public string Version { get { return Environment.Version.ToString(); } } //对Linux无效
[Display(Name = "磁盘分区")]
public string SystemDrive { get { return Environment.ExpandEnvironmentVariables("%SystemDrive%"); } }
//对Linux无效
[Display(Name = "系统目录")]
public string SystemRoot { get { return Environment.ExpandEnvironmentVariables("%SystemRoot%"); } }
}

可能你会觉得,为什么不写成方法,为啥要写得这么奇怪。不急,慢慢看下去~

反射获取信息

我们来定义一个静态类型,作为获取各种信息的入口。

public static class EnvironmentInfo
{ }
}

获取属性值

反射获取属性值的方法,用于获取上述几个类的属性值。

        /// <summary>
/// 获取属性的值
/// </summary>
/// <param name="info"></param>
/// <param name="obj">实例</param>
/// <returns></returns>
private static object GetPropertyInfoValue(PropertyInfo info, object obj)
{
return info.GetValue(obj);
}

反射获取特性值

我们使用了特性 [Display(Name = "当前关联用户名")] 来存储别名。

我们要通过反射获取 Dispaly 特性的 Name 属性值。

        /// <summary>
/// 获取 [Display] 特性的属性 Name 的值
/// </summary>
/// <param name="attrs"></param>
/// <returns></returns>
private static string GetDisplayNameValue(IList<CustomAttributeData> attrs)
{
var argument = attrs.FirstOrDefault(x => x.AttributeType.Name == nameof(DisplayAttribute)).NamedArguments;
return argument.FirstOrDefault(x => x.MemberName == nameof(DisplayAttribute.Name)).TypedValue.Value.ToString();
}

获取某个属性的值以及别名

我们使用了这样的方式去设置获取一项信息

        [Display(Name = "操作系统")]
public string OSDescription { get { return RuntimeInformation.OSDescription; } }

因此我们要获取到一个类型所有的属性值和属性的特性值。

        /// <summary>
/// 获取某个类型的值以及名称
/// </summary>
/// <typeparam name="TInfo"></typeparam>
/// <param name="info"></param>
/// <returns></returns>
private static (string, List<KeyValuePair<string, object>>) GetValues<TInfo>(TInfo info)
{
List<KeyValuePair<string, object>> list = new List<KeyValuePair<string, object>>();
Type type = info.GetType();
PropertyInfo[] pros = type.GetProperties();
foreach (var item in pros)
{
var name = GetDisplayNameValue(item.GetCustomAttributesData());
var value = GetPropertyInfoValue(item, info);
list.Add(new KeyValuePair<string, object>(name, value));
}
return
(GetDisplayNameValue(info.GetType().GetCustomAttributesData()),
list);
}

反射获取信息

上面的工具方法定义后,我们来设置不同的方法获取不同的信息。

        /// <summary>
/// 获取程序运行资源信息
/// </summary>
/// <returns></returns>
public static (string, List<KeyValuePair<string, object>>) GetApplicationRunInfo()
{
ApplicationRunInfo info = new ApplicationRunInfo();
return GetValues(info);
} /// <summary>
/// 获取系统运行平台信息
/// </summary>
/// <returns></returns>
public static (string, List<KeyValuePair<string, object>>) GetSystemPlatformInfo()
{
SystemPlatformInfo info = new SystemPlatformInfo();
return GetValues(info);
} /// <summary>
/// 获取系统运行环境信息
/// </summary>
/// <returns></returns>
public static (string, List<KeyValuePair<string, object>>) GetSystemRunEvnInfo()
{
SystemRunEvnInfo info = new SystemRunEvnInfo();
return GetValues(info);
}

还有一个方法获取环境变量的,不需要利用上面的类型-属性来操作,可以直接封装到方法中。

        /// <summary>
/// 获取系统全部环境变量
/// </summary>
/// <returns></returns>
public static (string, List<KeyValuePair<string, object>>) GetEnvironmentVariables()
{
List<KeyValuePair<string, object>> list = new List<KeyValuePair<string, object>>();
IDictionary environmentVariables = Environment.GetEnvironmentVariables();
foreach (DictionaryEntry de in environmentVariables)
{
list.Add(new KeyValuePair<string, object>(de.Key.ToString(), de.Value));
}
return ("系统环境变量", list);
}

使用

我们在 Program 中,这些写就可以输出所有信息了

        static void Main(string[] args)
{
var a = EnvironmentInfo.GetApplicationRunInfo();
var b = EnvironmentInfo.GetSystemPlatformInfo();
var c = EnvironmentInfo.GetSystemRunEvnInfo();
var d = EnvironmentInfo.GetEnvironmentVariables();
ConsoleInfo(a.Item1, a.Item2);
ConsoleInfo(b.Item1, b.Item2);
ConsoleInfo(c.Item1, c.Item2);
ConsoleInfo(d.Item1, d.Item2);
Console.ReadKey();
}
public static void ConsoleInfo(string title, List<KeyValuePair<string, object>> list)
{
Console.WriteLine("\n***********" + title + "***********");
foreach (var item in list)
{
Console.WriteLine(item.Key + ":" + item.Value);
}
}

在 Linux 中显示

总结

我以上使用了 类-属性 来作为获取功能,这样可以不必写很多方法去调用获取环境信息,属性就是数据。既方便序列化,又方便反射。

同时,如果先拓展信息项,直接添加上去就行,反射直接全部拿到手。

另外有个 Display 特性,专业用来显示信息项的。这样设置,可以为属性灵活设置别名,便于显示信息以及说明。

笔者会继续带来更多反射的使用实例,融入到日常需求中。

.NET Core 获取程序运行环境信息与反射的应用的更多相关文章

  1. C# 获取程序运行时路径

    Ø  前言 开发中,很多时候都需要获取程序运行时路径,比如:反射.文件操作等..NET Framework 已经封装了这些功能,可以很方便的使用. C# 中有很多类都可以获取程序运行时路径,我们没必要 ...

  2. golang获取程序运行路径

    golang获取程序运行路径: /* 获取程序运行路径 */ func getCurrentDirectory() string { dir, err := filepath.Abs(filepath ...

  3. Python获取程序运行目录和脚本目录

    Python获取程序运行目录和脚本目录 import os import sys #获取脚本所在目录 print os.path.split( os.path.realpath( sys.argv[0 ...

  4. .NET Core 获取主机运行资源的库

    简介 CZGL.SystemInfo 是一个支持 Windows 和 Linux 的资源信息获取库,用于获取系统环境.机器资源信息.系统资源使用情况. Nuget 搜索 CZGL.SystemInfo ...

  5. [转] C# 获取程序运行目录

    来自 莫等闲也,原文 // 获取程序的基目录.  System.AppDomain.CurrentDomain.BaseDirectory // 获取模块的完整路径. System.Diagnosti ...

  6. Qt使用windows API获取程序运行时占用内存 good

    使用的是psapi.h中的GetProcessMemoryInfo函数,但是运行到该函数时就强制退出了. 后来,百度到原因是 原来Qt编译时加了-mthread,createprocess时要使的Ha ...

  7. unicode string和ansi string的转换函数及获取程序运行路径的代码

    #pragma once#include <string> namespace stds { class tool { public: std::string ws2s(const std ...

  8. iOS获取程序运行平台

    下面这个博客里面写的很清楚 http://blog.sina.com.cn/s/blog_890a737301014fim.html

  9. C# 获取程序运行目录

    string a = "BaseDirectory:" + AppDomain.CurrentDomain.BaseDirectory + "\r\n" + & ...

随机推荐

  1. 20199324《Linux内核原理与分析》第十一周作业

    SET-UID程序漏洞实验 一.实验简介 Set-UID 是 Unix 系统中的一个重要的安全机制.当一个 Set-UID 程序运行的时候,它被假设为具有拥有者的权限.例如,如果程序的拥有者是root ...

  2. [LC] 82. Remove Adjacent Repeated Characters IV

    Repeatedly remove all adjacent, repeated characters in a given string from left to right. No adjacen ...

  3. spark mllib lda 中文分词、主题聚合基本样例

    github https://github.com/cclient/spark-lda-example spark mllib lda example 官方示例较为精简 在官方lda示例的基础上,给合 ...

  4. RPC,基于消息,远程访问方式比较

    远程访问 1.RPC方式 客户端调用远程方法和客户端调用本地方法形式是一样的,当然了底层需要封装通讯协议及数据转换的过程,这个一般由框架完成,可以简化开发, 这种方式本质也是通过通讯协议发消息给对方的 ...

  5. python学习笔记(30)——ddt

    1.ddt模块包含类的装饰器ddt和两个方法装饰器data ddt.ddt:装饰类,也就是继承TestCase的类. ddt.data:装饰测试方法,参数是一系列的值,用来传递参数 ddt.file_ ...

  6. git 学习系列(一)

    目录 git 简介 git的升级 建立仓库 克隆仓库 查看主机名 查看仓库初始状态 将文件提交到暂存区 查看修改详情 提交修改 查看修改记录 查看个人配置信息(在 .gitconfig 文件中) 查看 ...

  7. Linux SSH 允许root用户远程登录和无密码登录

    1. 允许root用户远程登录 修改ssh服务配置文件 sudo vi /etc/ssh/sshd_config调整PermitRootLogin参数值为yes,如下图: 2. 允许无密码登录同上,修 ...

  8. 第一届“信安杯”部分WriteUp

    第一届"信安杯"部分WriteUp------OooooohLeeGay队! 小队成员(按姓氏):郭泽坤.李江川.赵乐祺 以下这部分是做出来的 2019.11.23-24 ++Re ...

  9. Pulsar、ZooKeeper、BookKeeper 作用简述

    Pulsar:采取了存储计算分离的技术ZooKeeper 集群的作用和在 Kafka 中是一样的,都是被用来存储元数据.BookKeeper 集群则被用来存储消息数据.BookKeeper 有点儿类似 ...

  10. CentOS 6.5 搭建DNS服务器

    1.安装bind yum install -y bind 2.修改named.conf主配置文件 vim /etc/named.conf 图中圈中的地方改为any 3.配置正向.反向解析 vim /e ...