9.8.2018.0630
大石头 编写于 2018-06-30 11:15:32
X
using System;
using System.Collections.Generic;
using System.IO;
using System.Management;
using System.Text;
using Microsoft.VisualBasic.Devices;
using NewLife.Xml;

namespace NewLife.Common
{
    /// <summary>硬件信息</summary>
    public class HardInfo
    {
        #region 获取信息
        /// <summary>内部获取</summary>
        public class _
        {
            private static String _BaseBoard;
            /// <summary>主板序列号</summary>
            public static String BaseBoard
            {
                get
                {
                    if (_BaseBoard == null)
                    {
                        _BaseBoard = GetInfo("Win32_BaseBoard", "SerialNumber");
                        if (String.IsNullOrEmpty(_BaseBoard)) _BaseBoard = GetInfo("Win32_BaseBoard", "Product");
                        _BaseBoard = GetInfo("Win32_BaseBoard", "Product") + ";" + _BaseBoard;
                    }
                    return _BaseBoard;
                }
            }

            private static String _Processors;
            /// <summary>处理器序列号</summary>
            public static String Processors
            {
                get
                {
                    if (_Processors == null)
                    {
                        var name = GetInfo("Win32_Processor", "Name");
                        var MaxClockSpeed = GetInfo("Win32_Processor", "MaxClockSpeed").ToDouble() / 1000;
                        var ProcessorId = GetInfo("Win32_Processor", "ProcessorId");

                        while (name.Contains("  ")) name = name.Replace("  ", " ");
                        var speed = MaxClockSpeed.ToString("n2") + "GHz";
                        if (name.Contains(speed))
                            speed = null;
                        else
                            speed += " ";

                        _Processors = name + " " + speed + ProcessorId;
                    }
                    return _Processors;
                }
            }

            private static Int64? _Memory;
            /// <summary>内存总量</summary>
            public static Int64 Memory
            {
                get
                {
                    if (_Memory == null)
                    {
                        _Memory = (Int64)new ComputerInfo().TotalPhysicalMemory;
                        //_Memory = Convert.ToInt64(GetInfo("Win32_LogicalMemoryConfiguration", "TotalPhysicalMemory"));
                    }
                    return _Memory.Value;
                }
            }

            private static String _Disk;
            /// <summary>磁盘名称</summary>
            public static String Disk
            {
                get
                {
                    if (_Disk == null) _Disk = GetInfo("Win32_DiskDrive", "Model");
                    return _Disk;
                    //上面的方式取驱动器序列号会取得包括U盘和网络映射驱动器的序列号,实际只要当前所在盘就可以了
                    //return Volume;
                }
            }

            private static String _DiskSerial = String.Empty;
            /// <summary>磁盘序列号</summary>
            public static String DiskSerial
            {
                get
                {
                    if (String.IsNullOrEmpty(_DiskSerial)) _DiskSerial = GetInfo("Win32_DiskDrive", "SerialNumber");
                    return _DiskSerial;
                }
            }

            private static String _Volume;
            /// <summary>驱动器序列号</summary>
            public static String Volume
            {
                get
                {
                    //if (String.IsNullOrEmpty(_Volume)) _Volume = GetInfo("Win32_DiskDrive", "Model");
                    //磁盘序列号不够明显,故使用驱动器序列号代替
                    var id = AppDomain.CurrentDomain.BaseDirectory.Substring(0, 2);
                    if (_Volume == null) _Volume = GetInfo("Win32_LogicalDisk Where DeviceID=\"" + id + "\"", "VolumeSerialNumber");
                    return _Volume;
                }
            }

            private static String _Macs;
            /// <summary>网卡地址序列号</summary>
            public static String Macs
            {
                get
                {
                    if (_Macs != null) return _Macs;
                    //return GetInfo("Win32_NetworkAdapterConfiguration", "MacAddress");
                    var cimobject = new ManagementClass("Win32_NetworkAdapterConfiguration");
                    var moc = cimobject.GetInstances();
                    var bbs = new List<String>();
                    foreach (var mo in moc)
                    {
                        if (mo != null &&
                            mo.Properties != null &&
                            mo.Properties["MacAddress"] != null &&
                            mo.Properties["MacAddress"].Value != null &&
                            mo.Properties["IPEnabled"] != null &&
                            (Boolean)mo.Properties["IPEnabled"].Value)
                        {
                            //bbs.Add(mo.Properties["MacAddress"].Value.ToString());
                            var s = mo.Properties["MacAddress"].Value.ToString();
                            if (!bbs.Contains(s)) bbs.Add(s);
                        }
                    }
                    bbs.Sort();
                    var sb = new StringBuilder(bbs.Count * 15);
                    foreach (var s in bbs)
                    {
                        if (sb.Length > 0) sb.Append(",");
                        sb.Append(s);
                    }
                    _Macs = sb.ToString().Trim();
                    return _Macs;
                }
            }

            private static String _IPs;
            /// <summary>IP地址</summary>
            public static String IPs
            {
                get
                {
                    if (_IPs != null) return _IPs;
                    //return null;
                    var cimobject = new ManagementClass("Win32_NetworkAdapterConfiguration");
                    var moc = cimobject.GetInstances();
                    var bbs = new List<String>();
                    foreach (var mo in moc)
                    {
                        if (mo != null &&
                            mo.Properties != null &&
                            mo.Properties["IPAddress"] != null &&
                            mo.Properties["IPAddress"].Value != null &&
                            mo.Properties["IPEnabled"] != null &&
                            (Boolean)mo.Properties["IPEnabled"].Value)
                        {
                            var ss = (String[])mo.Properties["IPAddress"].Value;
                            if (ss != null)
                            {
                                foreach (var s in ss)
                                    if (!bbs.Contains(s)) bbs.Add(s);
                            }
                            //bbs.Add(mo.Properties["IPAddress"].Value.ToString());
                        }
                    }
                    bbs.Sort();
                    var sb = new StringBuilder(bbs.Count * 15);
                    foreach (var s in bbs)
                    {
                        if (sb.Length > 0) sb.Append(",");
                        sb.Append(s);
                    }
                    _IPs = sb.ToString().Trim();
                    return _IPs;
                }
            }
        }
        #endregion

        #region 属性
        private String _MachineName;
        /// <summary>机器名</summary>
        public String MachineName
        {
            get { return _MachineName; }
            set { _MachineName = value; }
        }

        private String _BaseBoard;
        /// <summary>主板</summary>
        public String BaseBoard
        {
            get { return _BaseBoard; }
            set { _BaseBoard = value; }
        }

        private String _Processors;
        /// <summary>处理器</summary>
        public String Processors
        {
            get { return _Processors; }
            set { _Processors = value; }
        }

        private String _Disk;
        /// <summary>磁盘</summary>
        public String Disk
        {
            get { return _Disk; }
            set { _Disk = value; }
        }

        private String _DiskSerial;
        /// <summary>磁盘序列号</summary>
        public String DiskSerial
        {
            get { return _DiskSerial; }
            set { _DiskSerial = value; }
        }

        private String _Volume;
        /// <summary>驱动器序列号</summary>
        public String Volume
        {
            get { return _Volume; }
            set { _Volume = value; }
        }

        private String _Macs;
        /// <summary>网卡</summary>
        public String Macs
        {
            get { return _Macs; }
            set { _Macs = value; }
        }

        private String _IPs;
        /// <summary>IP地址</summary>
        public String IPs
        {
            get { return _IPs; }
            set { _IPs = value; }
        }

        private String _OSVersion;
        /// <summary>系统版本</summary>
        public String OSVersion
        {
            get { return _OSVersion; }
            set { _OSVersion = value; }
        }

        private Int64 _Memory;
        /// <summary>内存</summary>
        public Int64 Memory
        {
            get { return _Memory; }
            set { _Memory = value; }
        }

        private Int32 _ScreenWidth;
        /// <summary>屏幕宽</summary>
        public Int32 ScreenWidth
        {
            get { return _ScreenWidth; }
            set { _ScreenWidth = value; }
        }

        private Int32 _ScreenHeight;
        /// <summary>屏幕高</summary>
        public Int32 ScreenHeight
        {
            get { return _ScreenHeight; }
            set { _ScreenHeight = value; }
        }

        private Int64 _DiskSize;
        /// <summary>磁盘大小</summary>
        public Int64 DiskSize
        {
            get { return _DiskSize; }
            set { _DiskSize = value; }
        }
        #endregion

        #region 构造
        private HardInfo() { }

        private void GetLocal()
        {
            MachineName = Environment.MachineName;
            BaseBoard = _.BaseBoard;
            Processors = _.Processors;
            Disk = _.Disk;
            DiskSerial = _.DiskSerial;
            Volume = _.Volume;
            Macs = _.Macs;
            IPs = _.IPs;
            OSVersion = Environment.OSVersion.ToString();
            Memory = _.Memory;
            ScreenWidth = GetInfo("Win32_DesktopMonitor", "ScreenWidth").ToInt();
            ScreenHeight = GetInfo("Win32_DesktopMonitor", "ScreenHeight").ToInt();

            var str = GetInfo("Win32_DiskDrive", "Size");
            Int64 n = 0;
            if (Int64.TryParse(str, out n)) DiskSize = n;
            if (DiskSize <= 0)
            {
                var drives = DriveInfo.GetDrives();
                if (drives != null && drives.Length > 0)
                {
                    foreach (var item in drives)
                    {
                        // 不统计未准备好的磁盘,否则会异常
                        if (!item.IsReady) continue;
                        if (item.DriveType == DriveType.CDRom ||
                            item.DriveType == DriveType.Network ||
                            item.DriveType == DriveType.NoRootDirectory) continue;

                        DiskSize += item.TotalSize;
                    }
                }
            }
        }

        private static HardInfo _Current;
        /// <summary>当前机器硬件信息</summary>
        public static HardInfo Current
        {
            get
            {
                if (_Current != null) return _Current;
                lock (typeof(HardInfo))
                {
                    if (_Current != null) return _Current;

                    try
                    {
                        _Current = new HardInfo();
                        _Current.GetLocal();
                    }
                    catch //(Exception ex)
                    {
                        //XTrace.WriteException(ex);
                    }

                    return _Current;
                }
            }
        }
        #endregion

        #region WMI辅助
        /// <summary>获取WMI信息</summary>
        /// <param name="path"></param>
        /// <param name="property"></param>
        /// <returns></returns>
        public static String GetInfo(String path, String property)
        {
            // Linux Mono不支持WMI
            if (Runtime.Mono) return "";

            var bbs = new List<String>();
            try
            {
                var wql = String.Format("Select {0} From {1}", property, path);
                var cimobject = new ManagementObjectSearcher(wql);
                var moc = cimobject.Get();
                foreach (var mo in moc)
                {
                    if (mo != null &&
                        mo.Properties != null &&
                        mo.Properties[property] != null &&
                        mo.Properties[property].Value != null)
                        bbs.Add(mo.Properties[property].Value.ToString());
                }
            }
            catch //(Exception ex)
            {
                //if (XTrace.Debug)
                //{
                //    XTrace.WriteLine("获取{0} {1}硬件信息失败\r\n{2}", path, property, ex);
                //}
                return "";
            }
            bbs.Sort();
            var sb = new StringBuilder(bbs.Count * 15);
            foreach (var s in bbs)
            {
                if (sb.Length > 0) sb.Append(",");
                sb.Append(s);
            }
            return sb.ToString().Trim();
        }
        #endregion
    }
}