2011-03-21 11 views
9

He creado una aplicación que necesita estar en un estado seguro, por lo que quiero seguir el estado de alimentación de la computadora en segundo plano. Si el nivel de la batería (si existe) es bajo o crítico, no permitiría que el usuario continúe usando la aplicación y salga todo correctamente.C# - Suceso de elevación en el cambio de PowerStatus

Antes que nada, estoy asombrado de que no exista tal evento para detectar el cambio. Siempre debe verificar el PowerStatus manualmente.

Por lo tanto, he creado una envoltura alrededor de ella, algo como esto:

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); 
       } 
      } 
     } 
    } 
} 

pero que no funciona porque no powerstatus tiene ningún constructor público y no puedo almacenar el resultado de la anterior estado ...

¿Cómo puedo gestionar esto?

Gracias ...

Respuesta

12

En realidad no hay, se llama la SystemEvents.PowerModeChanged

Si el PowerModeChangedEventArgs tiene un Mode de StatusChange, significa que el estado de la batería ha cambiado.

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 
    } 
} 

Este tutorial también puede ser de utilidad:

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

+0

¡Es por eso que estoy buscando! Gracias :) –

+0

@Arnaud: No hay problema;) – w69rdy

7

es necesario llamar a SystemInformation.PowerStatus en lugar de new PowerStatus() si usted está tratando de obtener el estado de alimentación actual.

+1

que te lleva una referencia, no es muy útil para almacenar y comparar en el siguiente pulso. –

+0

@Henk: Eso es lo que me pasa por responder a la parte técnica de la pregunta en lugar de la forma de resolver el problema real;) Si bien parece que @ w69rdy ha proporcionado la respuesta óptima, el PO habría que almacenar en caché los valores devueltos por la ' Clase PowerStatus' en lugar de la instancia en sí. Había asumido (incorrectamente) que 'PowerStatus' era una estructura simple en lugar de una clase real. –

2

Aquí hay un código que le devolverá todos los valores de la 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)); 
} 

Espero que esto ayude.