C# - Raise event on PowerStatus change

只愿长相守 提交于 2019-12-08 16:23:24

问题


I've created an application that need to be in a safe state and so I want to follow the power status of the computer in background. If the battery level (if any) is low or critical, I wouldn't allow the user to continue using the application and quit all properly.

First of all, I'm astonished that no such event exists in order to detect the change. You need always to check the PowerStatus manually.

So, I've created a wrapper around it, something like this :

using System;
using System.Windows.Forms;

namespace MyApp
{
    internal static class BatteryManagement
    {
        //
        internal static event EventHandler<EventArgs> Changed;

        //
        private static bool _started;
        private static System.Threading.Timer _timer;
        private static PowerStatus _previousPowerStatus;

        internal static void Start()
        {
            if (!_started)
            {
                _started = true;
                ManageBatteryLevel();
            }
        }

        internal static void Stop()
        {
            if (_started)
            {
                if(_timer != null)
                {
                    _timer.Dispose();
                    _timer = null;
                }

                _started = false;
            }
        }

        private static void ManageBatteryLevel()
        {
            _previousPowerStatus = new PowerStatus();

            TimeSpan dueTime = new TimeSpan(0, 0, 0); // Start right now
            TimeSpan period = new TimeSpan(0, 1, 0); // Run every 1 minute

            // Setting a timer that launch every period the OnBatteryLevelChange method
            _timer = new System.Threading.Timer(OnBatteryLevelChange, null, dueTime, period);
        }

        private static void OnBatteryLevelChange(Object stateInfo)
        {
            PowerStatus powerStatus = new PowerStatus();

            if (!_previousPowerStatus.Equals(powerStatus))
            {
                // Ensure battery level is up to date before raising event
                _previousPowerStatus = powerStatus;

                if (Changed != null)
                {
                    Changed(null, EventArgs.Empty);
                }
            }
        }
    }
}

But doesn't work because PowerStatus hasn't any public constructor and I can't store the result of the previous status...

How can I manage this ?

Thanks ...


回答1:


Actually there is, its called the SystemEvents.PowerModeChanged

If the PowerModeChangedEventArgs has a Mode of StatusChange, it means the status of the battery has changed.

static void SystemEvents_PowerModeChanged(object sender, Microsoft.Win32.PowerModeChangedEventArgs e)
{
    if (e.Mode == Microsoft.Win32.PowerModes.StatusChange)
    {
         // Check what the status is and act accordingly
    }
}

This tutorial may also be of use:

http://netcode.ru/dotnet/?lang=&katID=30&skatID=277&artID=7643




回答2:


You need to call SystemInformation.PowerStatus instead of new PowerStatus() if you're trying to obtain the current power status.




回答3:


Here is some code that will return you all the values of the PowerStatus

Type t = typeof(System.Windows.Forms.PowerStatus);            
PropertyInfo[] pi = t.GetProperties();            
for( int i=0; i<pi.Length; i++ )
{
    Console.WriteLine("Property Name {0}", pi[i].Name);
    Console.WriteLine("Property Value {0}", pi[i].GetValue(SystemInformation.PowerStatus, null));
}

Hope this helps.




回答4:


you're rigth, the information at the MSDN is no usefull at all, you will find what you need for your task here:

http://www.blackwasp.co.uk/PowerStatus.aspx

I hope it helps!



来源:https://stackoverflow.com/questions/5378449/c-sharp-raise-event-on-powerstatus-change

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!