/// <summary>
        /// Suspends the system by shutting power down.
        /// </summary>
        /// <param name="hibernate">If this parameter is TRUE, the system hibernates. If the parameter is FALSE, the system is suspended.</param>
        /// <param name="forceCritical">don't take an attantion on this parameter. He does nothing.</param>
        /// <param name="disableWakeEvent">If this parameter is TRUE, the system disables all wake events. If the parameter is FALSE, any system wake events remain enabled.</param>
        public void SuspendState(bool hibernate, bool forceCritical, bool disableWakeEvent)
        {
            uint result = PowerManagementConfiguration.SetSuspendState(hibernate, forceCritical, disableWakeEvent);

            if (result == 0)
            {
                throw new Win32Exception();
            }
        }
        /// <summary>
        /// https://docs.microsoft.com/en-us/windows/win32/api/powrprof/nf-powrprof-setsuspendstate
        /// If the function succeeds, the return value is nonzero.
        /// If the function fails, the return value is zero.To get extended error information, call GetLastError.
        /// </summary>
        /// <param name="hibernate">If this parameter is TRUE, the system hibernates. If the parameter is FALSE, the system is suspended.</param>
        /// <param name="force">This parameter has no effect.</param>
        /// <param name="wakeupEventsDisabled">If this parameter is TRUE, the system disables all wake events. If the parameter is FALSE, any system wake events remain enabled.</param>
        public void SuspendState(bool hibernate, bool force, bool wakeupEventsDisabled)
        {
            var result = PowerManagementConfiguration.SetSuspendState(hibernate, force, wakeupEventsDisabled);

            if (result == 0)
            {
                throw new Win32Exception("Something went wrong.");
            }
        }
        public SystemPowerInformation GetSystemPowerInformation()
        {
            var result = PowerManagementConfiguration.CallNtPowerInformation(PowerInformationLevel.SystemPowerInformation,
                                                                             IntPtr.Zero, 0, out SystemPowerInformation info, Marshal.SizeOf <SystemPowerInformation>());

            return(result == PowerInformationStatus.Success
                ? info
                : throw new Win32Exception("Something went wrong."));
        }
        private int GetSleepOrWakeTime(PowerInformationLevel informationLevel)
        {
            var result = PowerManagementConfiguration.CallNtPowerInformation(informationLevel, IntPtr.Zero, 0,
                                                                             out long time, Marshal.SizeOf <long>());

            var dateTime = new DateTime(2020, 4, 13, 0, 0, 0);

            return(result == PowerInformationStatus.Success
                ? dateTime.AddTicks(time / 100).Second
                : throw new Win32Exception("Something went wrong."));
        }
        /// <summary>
        /// Returns system battery state information or null if data wasn't found
        /// </summary>
        /// <returns></returns>
        public SystemBatteryState GetSystemBatteryState()
        {
            SystemBatteryState info;

            var action = PowerManagementConfiguration.CallNtPowerInformation(
                InformationLevelConstants.SYSTEM_BATTERY_STATE,
                IntPtr.Zero,
                0,
                out info,
                Marshal.SizeOf(typeof(SystemBatteryState)));

            return(action == InformationLevelConstants.STATUS_SUCCESS ? info : throw new Win32Exception("oi oi oi !!!! bedaaaaaa ! "));
        }
        /// <summary>
        /// Returns system power information data or null if data wasn't found
        /// </summary>
        /// <returns></returns>
        public SystemPowerInformation GetSystemPowerInformation()
        {
            SystemPowerInformation info;

            var action = PowerManagementConfiguration.CallNtPowerInformation(
                InformationLevelConstants.SYSTEM_POWER_INFORMATION,
                IntPtr.Zero,
                0,
                out info,
                Marshal.SizeOf(typeof(SystemPowerInformation)));

            return(action == InformationLevelConstants.STATUS_SUCCESS ? info : throw new Win32Exception("oi oi oi !!!! bedaaaaaa ! "));
        }
        private int GetSleepOrWakeTime(int informationLevel)
        {
            long time = 0;

            var action = PowerManagementConfiguration.CallNtPowerInformation(
                informationLevel,
                IntPtr.Zero,
                0,
                out time,
                (uint)Marshal.SizeOf(typeof(long)));

            var epochTime = new DateTime(2019, 1, 1, 0, 0, 0, DateTimeKind.Utc);

            return(action == InformationLevelConstants.STATUS_SUCCESS ? epochTime.AddTicks(time / 100).Second : throw new Win32Exception("oi oi oi !!!! bedaaaaaa ! "));
        }
        private bool HibernateFile(HibernateFileActions action)
        {
            var    boolSize = Marshal.SizeOf <bool>();
            IntPtr intPtr   = Marshal.AllocCoTaskMem(boolSize);

            Marshal.WriteByte(intPtr, (byte)action);

            var result = PowerManagementConfiguration.CallNtPowerInformation(PowerInformationLevel.SystemReserveHiberFile,
                                                                             intPtr,
                                                                             boolSize,
                                                                             IntPtr.Zero,
                                                                             0);

            return(result == PowerInformationStatus.Success);
        }
        private bool HibernateFileAction(HibernateFileActions fileActions)
        {
            var    intSize = Marshal.SizeOf <bool>();
            IntPtr intPtr  = Marshal.AllocCoTaskMem(intSize);

            Marshal.WriteByte(intPtr, (byte)fileActions);

            var retval = PowerManagementConfiguration.CallNtPowerInformation(
                InformationLevelConstants.SYSTEM_RESERVE_HIBER_FILE,
                fileActions == HibernateFileActions.Reserve,
                Marshal.SizeOf <bool>(),
                IntPtr.Zero,
                0);

            return(retval == InformationLevelConstants.STATUS_SUCCESS);
        }