public string GetReport()
        {
            lock (_lock)
            {
                using StringWriter w = new StringWriter(CultureInfo.InvariantCulture);

                w.WriteLine();
                w.WriteLine(nameof(LibreHardwareMonitor) + " Report");
                w.WriteLine();

                Version version = typeof(Computer).Assembly.GetName().Version;

                NewSection(w);
                w.Write("Version: ");
                w.WriteLine(version.ToString());
                w.WriteLine();

                NewSection(w);
                w.Write("Common Language Runtime: ");
                w.WriteLine(Environment.Version.ToString());
                w.Write("Operating System: ");
                w.WriteLine(Environment.OSVersion.ToString());
                w.Write("Process Type: ");
                w.WriteLine(IntPtr.Size == 4 ? "32-Bit" : "64-Bit");
                w.WriteLine();

                string r = Ring0.GetReport();
                if (r != null)
                {
                    NewSection(w);
                    w.Write(r);
                    w.WriteLine();
                }

                NewSection(w);
                w.WriteLine("Sensors");
                w.WriteLine();

                foreach (IGroup group in _groups)
                {
                    foreach (IHardware hardware in group.Hardware)
                    {
                        ReportHardwareSensorTree(hardware, w, string.Empty);
                    }
                }

                w.WriteLine();

                NewSection(w);
                w.WriteLine("Parameters");
                w.WriteLine();

                foreach (IGroup group in _groups)
                {
                    foreach (IHardware hardware in group.Hardware)
                    {
                        ReportHardwareParameterTree(hardware, w, string.Empty);
                    }
                }

                w.WriteLine();

                foreach (IGroup group in _groups)
                {
                    string report = group.GetReport();
                    if (!string.IsNullOrEmpty(report))
                    {
                        NewSection(w);
                        w.Write(report);
                    }

                    IEnumerable <IHardware> hardwareArray = group.Hardware;
                    foreach (IHardware hardware in hardwareArray)
                    {
                        ReportHardware(hardware, w);
                    }
                }

                return(w.ToString());
            }
        }
        public void Open()
        {
            if (_open)
            {
                return;
            }


            _smbios = new SMBios();

            Ring0.Open();
            OpCode.Open();

            if (_motherboardEnabled)
            {
                Add(new MotherboardGroup(_smbios, _settings));
            }

            if (_cpuEnabled)
            {
                Add(new CPU.CpuGroup(_settings));
            }

            if (_memoryEnabled)
            {
                Add(new MemoryGroup(_settings));
            }

            if (_gpuEnabled)
            {
                Add(new AmdGpuGroup(_settings));
                Add(new NvidiaGroup(_settings));
            }

            if (_controllerEnabled)
            {
                Add(new TBalancerGroup(_settings));
                Add(new HeatmasterGroup(_settings));
                Add(new AquaComputerGroup(_settings));
            }

            if (_storageEnabled)
            {
                Add(new StorageGroup(_settings));
            }

            if (_networkEnabled)
            {
                Add(new NetworkGroup(_settings));
            }

            HardwareAdded += delegate(IHardware hardware) {
                // Find all Control sensors and give all hardware
                NotifyNotifySoftwareCurveControllersAllHardware();
            };

            HardwareRemoved += delegate(IHardware removed) {
                // Find all Control sensors and notify removed hardware
                foreach (var group in _groups)
                {
                    foreach (var hardware in group.Hardware)
                    {
                        NotifySoftwareCurveControllersHardwareRemoved(hardware, removed);
                    }
                }
            };

            _open = true;
        }