After a long absence I'm back for a short while. The main problem is we're still lacking some furniture in our home (ahhm… table… ahhm) so I don't really have a place to sit and write things.
Anyway the current code is due to the most annoying yet simple things that happen. The laptop is on, you're in the kitchen / on the phone / watching TV / etc… It wasn't a long time, yet suddenly you hear that annoying sound windows closing and (hopefully) saving your data. In my wife's case it means that everything got trashed due to a bug somewhere in the M$ windows.
The solution is most simple, add a warning, something like "You have got 180 of seconds of battery time left" squeaking it's way through the speakers. Easy said, and can be achieved almost as easily.
First thing to do is get the battery status:
System.Windows.Forms.SystemInformation.PowerStatus.BatteryLifeRemaining gives the required value. There are also other values available, but for the most basic thing it's enough. There's only one pothole: "what happens when the battery is being charged?" The answer is almost as simple System.Windows.Forms.SystemInformation.PowerStatus.BatteryChargeStatus gives the charging status, note it's a bitwise data. Or use the easy way, the life remaining returns -1 when connected to the power supply.
Second thing to do is the speech. For this I've used the "M$ SpeechLib", it's a COM object. If you need the full SDK it's available in this link http://www.microsoft.com/downloads/details.aspx?FamilyId=5E86EC97-40A7-453F-B0EE-6583171B4530&displaylang=en
SpeechLib.SpVoice oVoice = new SpeechLib.SpVoice();
SpeechLib.SpFileStream cpFileStream = new SpeechLib.SpFileStream();
string Line = "Battery has " + System.Windows.Forms.SystemInformation.PowerStatus.BatteryLifeRemaining.ToString() + " seconds.";
oVoice.Speak(Line, SpeechLib.SpeechVoiceSpeakFlags.SVSFDefault);
oVoice = null;
Third thing to do is surround everything in a "nice to have" service:
private static System.Threading.Thread th;
private static void RunningThread()
{
int MainLoop = 60000;
int CriticalLoop = 5000;
int ThreshHold = 300;
while (true)
{
if ((System.Windows.Forms.SystemInformation.PowerStatus.BatteryLifeRemaining > 0) && (System.Windows.Forms.SystemInformation.PowerStatus.BatteryLifeRemaining < ThreshHold))
{
SpeechLib.SpVoice oVoice = new SpeechLib.SpVoice();
SpeechLib.SpFileStream cpFileStream = new SpeechLib.SpFileStream();
string Line = "Battery has " + System.Windows.Forms.SystemInformation.PowerStatus.BatteryLifeRemaining.ToString() + " seconds.";
oVoice.Speak(Line, SpeechLib.SpeechVoiceSpeakFlags.SVSFDefault);
oVoice = null; System.Threading.Thread.Sleep(CriticalLoop);
}else{
System.Threading.Thread.Sleep(MainLoop);
}
}
}
protected override void OnStart(string[] args)
{
th = new System.Threading.Thread(RunningThread);
th.Start();
}
protected override void OnStop()
{
th.Abort();
}
Note the OnStart and OnStop, they are the methods the OS uses in order to start and stop the service. The actual working thread must be a different thread in order for the service to work. Otherwise the service might be declared as not working (or not starting/stopping).
Fourth thing to do is add an installer class to the service:
private System.ServiceProcess.ServiceProcessInstaller processInstaller;
private System.ServiceProcess.ServiceInstaller serviceInstaller;
public BatterySVC_inst()
{
InitializeComponent();
processInstaller = new System.ServiceProcess.ServiceProcessInstaller();
serviceInstaller = new System.ServiceProcess.ServiceInstaller();
processInstaller.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
serviceInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
serviceInstaller.ServiceName = "BatterySVC";
Installers.Add(serviceInstaller);
Installers.Add(processInstaller);
}
Just remember to run the "installutil" on the resulting EXE.
P.S. I used a post-build event in order to stop, unregister and re-register.
Thursday, October 30, 2008
Subscribe to:
Posts (Atom)