views:

58

answers:

2

I want to create a Windows Service that tracks if the A/C power adapter is plugged in or not. For that, I am trying to build Windows Service as below:

using System;
using System.ServiceProcess;

namespace PowerAlert {
    partial class PowerAlert : ServiceBase {
        public PowerAlert() {
            InitializeComponent();
        }

        protected override void OnStart(string[] args) {
            base.OnStart(args);
        }

        protected override void OnStop() {
            base.OnStop();
        }

        protected new virtual void OnPowerEvent(PowerBroadcastStatus powerStatus) {
            Console.Beep();
        }
    }
}

After installing the service and starting it from services.msc, when I unplug my adapter and plug it back in, I don't hear the beep.

I am sure I am not doing something(s) correctly. Could you please help me identify that/those something(s)?

EDIT 1

As you can see from below, CanHandlePowerEvent is set to true.

namespace PowerAlert {
    partial class PowerAlert {
        /// <summary> 
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing) {
            if (disposing && (components != null)) {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Component Designer generated code

        /// <summary> 
        /// Required method for Designer support - do not modify 
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent() {
            // 
            // PowerAlert
            // 
            this.CanHandlePowerEvent = true;
            this.ServiceName = "PowerAlert";
        }

        #endregion
    }
}

I have overridden the OnPowerEvent as below:

using System;
using System.ServiceProcess;

namespace PowerAlert{
    partial class PowerAlert: ServiceBase {
        public PowerAlert() {
            InitializeComponent();
        }

        protected override void OnStart(string[] args) {
            base.OnStart(args);
        }

        protected override void OnStop() {
            base.OnStop();
        }

        protected override bool OnPowerEvent(PowerBroadcastStatus powerStatus) {
            Console.Beep();

            return base.OnPowerEvent(powerStatus);
        }
    }
}

Still I don't hear any beep.

+2  A: 

Beside the wrong syntax to override a method, it looks like you didn't set up the CanHandlePowerEvent property.

When the computer power status changes, the Service Control Manager (SCM) verifies whether the service accepts power event commands using the value of CanHandlePowerEvent.

If CanHandlePowerEvent is true, the command is passed to the service and the OnPowerEvent method is called if defined. If OnPowerEvent is not implemented in the derived class, the SCM handles the power event through the empty base class ServiceBase.OnPowerEvent method.ServiceBase.OnPowerEvent method.

And please one thing about the method:

The Beep method is not supported on the 64-bit editions of Windows Vista and Windows XP.

Henrik P. Hessel
Bingo! I am using 64-bit Windows 7. Let me try writing to a log file.
Ruby
+2  A: 
    protected new virtual void OnPowerEvent(PowerBroadcastStatus powerStatus) {
        Console.Beep();
    }

Check your favorite C# programming book about the new keyword. The brief version: it hides the base method, it doesn't override it. And it will thus never be called. Drop new virtual, use override, just like you did for the other methods. You will also have to set the CanHandlePowerEvent property to true in the constructor.

Hans Passant