private NvFanCoolersStatus GetFanCoolersStatus()
        {
            var coolers = new NvFanCoolersStatus();

            coolers.Version = NVAPI.GPU_FAN_COOLERS_STATUS_VER;
            coolers.Items   =
                new NvFanCoolersStatusItem[NVAPI.MAX_FAN_COOLERS_STATUS_ITEMS];

            if (!(NVAPI.NvAPI_GPU_ClientFanCoolersGetStatus != null &&
                  NVAPI.NvAPI_GPU_ClientFanCoolersGetStatus(handle, ref coolers)
                  == NvStatus.OK))
            {
                coolers.Count = 0;
            }
            return(coolers);
        }
        public override string GetReport()
        {
            StringBuilder r = new StringBuilder();

            r.AppendLine("Nvidia GPU");
            r.AppendLine();

            r.AppendFormat("Name: {0}{1}", name, Environment.NewLine);
            r.AppendFormat("Index: {0}{1}", adapterIndex, Environment.NewLine);

            if (displayHandle.HasValue && NVAPI.NvAPI_GetDisplayDriverVersion != null)
            {
                NvDisplayDriverVersion driverVersion = new NvDisplayDriverVersion();
                driverVersion.Version = NVAPI.DISPLAY_DRIVER_VERSION_VER;
                if (NVAPI.NvAPI_GetDisplayDriverVersion(displayHandle.Value,
                                                        ref driverVersion) == NvStatus.OK)
                {
                    r.Append("Driver Version: ");
                    r.Append(driverVersion.DriverVersion / 100);
                    r.Append(".");
                    r.Append((driverVersion.DriverVersion % 100).ToString("00",
                                                                          CultureInfo.InvariantCulture));
                    r.AppendLine();
                    r.Append("Driver Branch: ");
                    r.AppendLine(driverVersion.BuildBranch);
                }
            }
            r.AppendLine();

            if (NVAPI.NvAPI_GPU_GetPCIIdentifiers != null)
            {
                uint deviceId, subSystemId, revisionId, extDeviceId;

                NvStatus status = NVAPI.NvAPI_GPU_GetPCIIdentifiers(handle,
                                                                    out deviceId, out subSystemId, out revisionId, out extDeviceId);

                if (status == NvStatus.OK)
                {
                    r.Append("DeviceID: 0x");
                    r.AppendLine(deviceId.ToString("X", CultureInfo.InvariantCulture));
                    r.Append("SubSystemID: 0x");
                    r.AppendLine(subSystemId.ToString("X", CultureInfo.InvariantCulture));
                    r.Append("RevisionID: 0x");
                    r.AppendLine(revisionId.ToString("X", CultureInfo.InvariantCulture));
                    r.Append("ExtDeviceID: 0x");
                    r.AppendLine(extDeviceId.ToString("X", CultureInfo.InvariantCulture));
                    r.AppendLine();
                }
            }

            if (NVAPI.NvAPI_GPU_GetThermalSettings != null)
            {
                NvGPUThermalSettings settings = new NvGPUThermalSettings();
                settings.Version = NVAPI.GPU_THERMAL_SETTINGS_VER;
                settings.Count   = NVAPI.MAX_THERMAL_SENSORS_PER_GPU;
                settings.Sensor  = new NvSensor[NVAPI.MAX_THERMAL_SENSORS_PER_GPU];

                NvStatus status = NVAPI.NvAPI_GPU_GetThermalSettings(handle,
                                                                     (int)NvThermalTarget.ALL, ref settings);

                r.AppendLine("Thermal Settings");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    for (int i = 0; i < settings.Count; i++)
                    {
                        r.AppendFormat(" Sensor[{0}].Controller: {1}{2}", i,
                                       settings.Sensor[i].Controller, Environment.NewLine);
                        r.AppendFormat(" Sensor[{0}].DefaultMinTemp: {1}{2}", i,
                                       settings.Sensor[i].DefaultMinTemp, Environment.NewLine);
                        r.AppendFormat(" Sensor[{0}].DefaultMaxTemp: {1}{2}", i,
                                       settings.Sensor[i].DefaultMaxTemp, Environment.NewLine);
                        r.AppendFormat(" Sensor[{0}].CurrentTemp: {1}{2}", i,
                                       settings.Sensor[i].CurrentTemp, Environment.NewLine);
                        r.AppendFormat(" Sensor[{0}].Target: {1}{2}", i,
                                       settings.Sensor[i].Target, Environment.NewLine);
                    }
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            if (NVAPI.NvAPI_GPU_GetAllClocks != null)
            {
                NvClocks allClocks = new NvClocks();
                allClocks.Version = NVAPI.GPU_CLOCKS_VER;
                allClocks.Clock   = new uint[NVAPI.MAX_CLOCKS_PER_GPU];
                NvStatus status = NVAPI.NvAPI_GPU_GetAllClocks(handle, ref allClocks);

                r.AppendLine("Clocks");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    for (int i = 0; i < allClocks.Clock.Length; i++)
                    {
                        if (allClocks.Clock[i] > 0)
                        {
                            r.AppendFormat(" Clock[{0}]: {1}{2}", i, allClocks.Clock[i],
                                           Environment.NewLine);
                        }
                    }
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            if (NVAPI.NvAPI_GPU_GetTachReading != null)
            {
                int      tachValue;
                NvStatus status = NVAPI.NvAPI_GPU_GetTachReading(handle, out tachValue);

                r.AppendLine("Tachometer");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    r.AppendFormat(" Value: {0}{1}", tachValue, Environment.NewLine);
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            if (NVAPI.NvAPI_GPU_GetDynamicPstatesInfoEx != null)
            {
                var info = new NvDynamicPstatesInfoEx();
                info.Version            = NVAPI.GPU_DYNAMIC_PSTATES_INFO_EX_VER;
                info.UtilizationDomains =
                    new NvUtilizationDomainEx[NVAPI.NVAPI_MAX_GPU_UTILIZATIONS];
                var status = NVAPI.NvAPI_GPU_GetDynamicPstatesInfoEx(handle, ref info);

                r.AppendLine("Utilization Domains Ex");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    for (int i = 0; i < info.UtilizationDomains.Length; i++)
                    {
                        if (info.UtilizationDomains[i].Present)
                        {
                            r.AppendFormat(" Percentage[{0}]: {1}{2}", i,
                                           info.UtilizationDomains[i].Percentage, Environment.NewLine);
                        }
                    }
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            if (NVAPI.NvAPI_GPU_GetDynamicPstatesInfo != null)
            {
                var info = new NvDynamicPstatesInfo();
                info.Version            = NVAPI.GPU_DYNAMIC_PSTATES_INFO_VER;
                info.UtilizationDomains =
                    new NvUtilizationDomain[NVAPI.NVAPI_MAX_GPU_UTILIZATIONS];
                var status = NVAPI.NvAPI_GPU_GetDynamicPstatesInfo(handle, ref info);

                r.AppendLine("Utilization Domains");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    for (int i = 0; i < info.UtilizationDomains.Length; i++)
                    {
                        if (info.UtilizationDomains[i].Present)
                        {
                            r.AppendFormat(" Percentage[{0}]: {1}{2}", i,
                                           info.UtilizationDomains[i].Percentage, Environment.NewLine);
                        }
                    }
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            if (NVAPI.NvAPI_GPU_GetCoolerSettings != null)
            {
                NvGPUCoolerSettings settings = new NvGPUCoolerSettings();
                settings.Version = NVAPI.GPU_COOLER_SETTINGS_VER;
                settings.Cooler  = new NvCooler[NVAPI.MAX_COOLER_PER_GPU];
                NvStatus status =
                    NVAPI.NvAPI_GPU_GetCoolerSettings(handle, 0, ref settings);

                r.AppendLine("Cooler Settings");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    for (int i = 0; i < settings.Count; i++)
                    {
                        r.AppendFormat(" Cooler[{0}].Type: {1}{2}", i,
                                       settings.Cooler[i].Type, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].Controller: {1}{2}", i,
                                       settings.Cooler[i].Controller, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].DefaultMin: {1}{2}", i,
                                       settings.Cooler[i].DefaultMin, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].DefaultMax: {1}{2}", i,
                                       settings.Cooler[i].DefaultMax, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].CurrentMin: {1}{2}", i,
                                       settings.Cooler[i].CurrentMin, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].CurrentMax: {1}{2}", i,
                                       settings.Cooler[i].CurrentMax, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].CurrentLevel: {1}{2}", i,
                                       settings.Cooler[i].CurrentLevel, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].DefaultPolicy: {1}{2}", i,
                                       settings.Cooler[i].DefaultPolicy, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].CurrentPolicy: {1}{2}", i,
                                       settings.Cooler[i].CurrentPolicy, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].Target: {1}{2}", i,
                                       settings.Cooler[i].Target, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].ControlType: {1}{2}", i,
                                       settings.Cooler[i].ControlType, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].Active: {1}{2}", i,
                                       settings.Cooler[i].Active, Environment.NewLine);
                    }
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            if (NVAPI.NvAPI_GetDisplayDriverMemoryInfo != null &&
                displayHandle.HasValue)
            {
                NvDisplayDriverMemoryInfo memoryInfo = new NvDisplayDriverMemoryInfo();
                memoryInfo.Version = NVAPI.DISPLAY_DRIVER_MEMORY_INFO_VER;
                memoryInfo.Values  = new uint[NVAPI.MAX_MEMORY_VALUES_PER_GPU];
                NvStatus status = NVAPI.NvAPI_GetDisplayDriverMemoryInfo(
                    displayHandle.Value, ref memoryInfo);

                r.AppendLine("Memory Info");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    for (int i = 0; i < memoryInfo.Values.Length; i++)
                    {
                        r.AppendFormat(" Value[{0}]: {1}{2}", i,
                                       memoryInfo.Values[i], Environment.NewLine);
                    }
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            if (NVAPI.NvAPI_GPU_ClientFanCoolersGetStatus != null)
            {
                var coolers = new NvFanCoolersStatus();
                coolers.Version = NVAPI.GPU_FAN_COOLERS_STATUS_VER;
                coolers.Items   =
                    new NvFanCoolersStatusItem[NVAPI.MAX_FAN_COOLERS_STATUS_ITEMS];

                var status = NVAPI.NvAPI_GPU_ClientFanCoolersGetStatus(handle, ref coolers);

                r.AppendLine("Fan Coolers Status");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    for (int i = 0; i < coolers.Count; i++)
                    {
                        r.AppendFormat(" Items[{0}].Type: {1}{2}", i,
                                       coolers.Items[i].Type, Environment.NewLine);
                        r.AppendFormat(" Items[{0}].CurrentRpm: {1}{2}", i,
                                       coolers.Items[i].CurrentRpm, Environment.NewLine);
                        r.AppendFormat(" Items[{0}].CurrentMinLevel: {1}{2}", i,
                                       coolers.Items[i].CurrentMinLevel, Environment.NewLine);
                        r.AppendFormat(" Items[{0}].CurrentMaxLevel: {1}{2}", i,
                                       coolers.Items[i].CurrentMaxLevel, Environment.NewLine);
                        r.AppendFormat(" Items[{0}].CurrentLevel: {1}{2}", i,
                                       coolers.Items[i].CurrentLevel, Environment.NewLine);
                    }
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            return(r.ToString());
        }