Click here to Skip to main content
15,888,037 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am working on an where i need to get a notification when power supply interrupted. several code which use Win32_Battry and Win32_PowerSupplySatus dll File for show Power supply status. but it works only for Laptop computer. Because they have battery. But In Desktop Computer there is no any battery. So i don't get any response for Desktop. Over all i want the code in C# for get a Notification when Main Power supply off and desktop system works on UPS. Kindly help me..

What I have tried:

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Runtime.InteropServices;

public enum ACLineStatus : byte
	{
	Offline = 0,
	Online = 1,
	Unknown = 255,
	}

public enum BatteryFlag : byte
	{
	High = 1,
	Low = 2,
	Critical = 4,
	Charging = 9,
	NoSystemBattery = 128,
	Unknown = 255
	}

// mirrors the unmanaged counterpart
[StructLayout(LayoutKind.Sequential)]
public class SystemPowerStatus
	{
	public ACLineStatus ACLineStatus;
	public BatteryFlag BatteryFlag;
	public Byte BatteryLifePercent;
	public Byte Reserved1;
	public Int32 BatteryLifeTime;
	public Int32 BatteryFullLifeTime;
	}

class Win32PowerManager
	{
	[DllImport("Kernel32")]
	private static extern Boolean GetSystemPowerStatus(SystemPowerStatus sps);

	public static SystemPowerStatus GetSystemPowerStatus()
		{
		SystemPowerStatus sps = new SystemPowerStatus();
		GetSystemPowerStatus(sps);
		return sps;
		}

	[Flags]
	public enum ExitWindowsBits : uint
		{
		// ONE of the following five:
		LogOff = 0x00,
		ShutDown = 0x01,
		Reboot = 0x02,
		PowerOff = 0x08,
		RestartApps = 0x40,
		// plus AT MOST ONE of the following two:
		Force = 0x04,
		ForceIfHung = 0x10,
		}

	[Flags]
	public enum ShutdownReasonBits : uint
		{
		MajorApplication = 0x00040000,
		MajorHardware = 0x00010000,
		MajorLegacyApi = 0x00070000,
		MajorOperatingSystem = 0x00020000,
		MajorOther = 0x00000000,
		MajorPower = 0x00060000,
		MajorSoftware = 0x00030000,
		MajorSystem = 0x00050000,

		MinorBlueScreen = 0x0000000F,
		MinorCordUnplugged = 0x0000000b,
		MinorDisk = 0x00000007,
		MinorEnvironment = 0x0000000c,
		MinorHardwareDriver = 0x0000000d,
		MinorHotfix = 0x00000011,
		MinorHung = 0x00000005,
		MinorInstallation = 0x00000002,
		MinorMaintenance = 0x00000001,
		MinorMMC = 0x00000019,
		MinorNetworkConnectivity = 0x00000014,
		MinorNetworkCard = 0x00000009,
		MinorOther = 0x00000000,
		MinorOtherDriver = 0x0000000e,
		MinorPowerSupply = 0x0000000a,
		MinorProcessor = 0x00000008,
		MinorReconfig = 0x00000004,
		MinorSecurity = 0x00000013,
		MinorSecurityFix = 0x00000012,
		MinorSecurityFixUninstall = 0x00000018,
		MinorServicePack = 0x00000010,
		MinorServicePackUninstall = 0x00000016,
		MinorTermSrv = 0x00000020,
		MinorUnstable = 0x00000006,
		MinorUpgrade = 0x00000003,
		MinorWMI = 0x00000015,

		FlagUserDefined = 0x40000000,
		FlagPlanned = 0x80000000
		}

	[DllImport("user32.dll")]
	static extern bool ExitWindowsEx(ExitWindowsBits uFlags, ShutdownReasonBits dwReason);

	[STAThread]
	public static bool ShutDown()
		{
		return ExitWindowsEx(ExitWindowsBits.PowerOff | ExitWindowsBits.Force,
						ShutdownReasonBits.MajorPower | ShutdownReasonBits.MinorCordUnplugged);
		}
	}


But Above Code Works for laptop.it don't work for Desktop Computer. i want when i turn off main power supply and my desktop runs on UPS Power. then it shows Offline.
Posted
Updated 30-Jul-19 22:37pm
v2

That's a tricky question, you can look in the Windows Event log if there are any warnings from the UPS and trigger on that.
EventLog eventLogSource = new EventLog("System");

Here is a piece of code for you that you can try in a Console Application, it's a bit cryptic I'm afraid:
namespace EventLogCheck
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Threading;
    using System.Threading.Tasks;

    class Program
    {
        private const string EventSource = "MyProgramName";

        private static bool Running = true;

        /// <summary>
        /// The windows event log to watch, e.g. "System".
        /// </summary>
        private static EventLog eventLogSource;

        /// <summary>
        /// The event log warning type(s) to watch, e.g. "Warning,Error".
        /// </summary>
        private static string eventlogWarningType;

        /// <summary>
        /// The last eventlog warning or error number (as filtered by EventlogSource and EventlogWarningType settings).
        /// </summary>
        private static volatile int lastEventlogWarning;

        /// <summary>
        /// Disk strings to check in EventLog, e.g. "Disk"
        /// </summary>
        private static volatile string diskEventCheck;

        /// <summary>
        /// Disk strings to check in EventLog, e.g. "Disk"
        /// </summary>
        private static List<string> diskEventCheckList = new List<string>();

        /// <summary>
        /// PSU strings to check in EventLog, e.g. "power supply, power supplies".
        /// </summary>
        private static volatile string psuEventCheck;

        /// <summary>
        /// PSU strings List to check in EventLog, e.g. "power supply, power supplies".
        /// </summary>
        private static List<string> psuEventCheckList = new List<string>();

        private static bool psuEventError;

        private static bool diskEventError;

        static void Main(string[] args)
        {
            Check();
        }

        private static void Check()
        {
            Task checkEventlog = null;
            psuEventCheck = "power supply, power supplies";
            eventLogSource = new EventLog("System");
            eventlogWarningType = "Error";
            CheckEventlogInit(eventLogSource, eventlogWarningType);
            checkEventlog = Task.Factory.StartNew(() => CheckEventlog(eventLogSource, eventlogWarningType));

            // Enter the loop and wait 10 seconds between tests.
            // When a task has finished, start a new one.
            while (Running)
            {
                if (checkEventlog != null)
                {
                    if (checkEventlog.IsCompleted)
                    {
                        checkEventlog.Dispose();
                        checkEventlog = Task.Factory.StartNew(() => CheckEventlog(eventLogSource, eventlogWarningType));
                    }
                }

                var stopwatch = new Stopwatch();
                stopwatch.Reset();
                stopwatch.Start();

                while ((stopwatch.ElapsedMilliseconds < 10000) && Running)
                {
                    // Avoid high CPU usage by tight loop.
                    Thread.CurrentThread.Join(100);
                }

                stopwatch.Stop();
            }
        }

        /// <summary>
        /// Find the index number of the last eventlog warning or error,
        /// and set the <see cref="lastEventlogWarning"/> index number.
        /// </summary>
        /// <param name="eventLogSource1">The event Log Source to monitor, e.g. EventLog("Application")</param>
        /// <param name="eventlogWarningType1">The eventlog Warning Type(s), e.g. "Warning,Error".</param>
        private static void CheckEventlogInit(EventLog eventLogSource1, string eventlogWarningType1)
        {
            int count = eventLogSource1.Entries.Count;
            int count2 = 0;
            lastEventlogWarning = 0;

            try
            {
                if (count < 1)
                {
                    return;
                }

                count2 = Math.Max(0, count - 20);
                lastEventlogWarning = eventLogSource1.Entries[count - 1].Index;
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error in CheckEventlogInit() " + ex.Message);
                return;
            }

            // Search only the top 20 entries.
            for (int i = count - 1; i >= count2; i--)
            {
                try
                {
                    var warningType = eventLogSource1.Entries[i].EntryType.ToString();

                    // Filter the wanted warning type(s).
                    if (eventlogWarningType1.ToLower().Contains(warningType.ToLower()))
                    {
                        if (!eventLogSource1.Entries[i].Source.Equals(EventSource))
                        {
                            ////Debug.Print(eventLogSource1.Entries[i].Message);
                            lastEventlogWarning = eventLogSource1.Entries[i].Index;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error in CheckEventlogInit() for " + ex.Message);
                }
            }

            psuEventCheckList.Clear();
            diskEventCheckList.Clear();

            // Add the PSU event error strings to check
            if (!string.IsNullOrEmpty(psuEventCheck))
            {
                var psuArr = psuEventCheck.Split(',');

                foreach (var extra in psuArr)
                {
                    psuEventCheckList.Add(extra.Trim());
                }
            }

            // Add the disk event error strings to check
            if (!string.IsNullOrEmpty(diskEventCheck))
            {
                var diskArr = diskEventCheck.Split(',');

                foreach (var extra in diskArr)
                {
                    diskEventCheckList.Add(extra.Trim());
                }
            }
        }

        /// <summary>
        /// Check the Windows event log for new warnings and/or errors.
        /// Skip 'Client Application exit'.
        /// </summary>
        /// <param name="eventLogSource1">The event Log Source to monitor, e.g. EventLog("Application")</param>
        /// <param name="eventlogWarningType1">The eventlog Warning Type(s), e.g. "Warning,Error".</param>
        private static void CheckEventlog(EventLog eventLogSource1, string eventlogWarningType1)
        {
            try
            {
                int count = eventLogSource1.Entries.Count;
                int count2 = Math.Max(0, count - 20);
                bool psuEventCleared = false;
                diskEventError = false;

                for (int i = count - 1; i >= count2; i--)
                {
                    if (lastEventlogWarning >= eventLogSource1.Entries[i].Index)
                    {
                        // Show new warnings up to last warning.
                        break;
                    }

                    var warningType = eventLogSource1.Entries[i].EntryType.ToString();
                    var message = eventLogSource1.Entries[i].Message;

                    // Check if PSU error message has to be cleared.
                    if (psuEventError)
                    {
                        if (message.ToLower().Contains(@"power supply") && (message.ToLower().Contains(@"operating correctly") || warningType.Equals("Information")))
                        {
                            // Clear the error status
                            psuEventError = false;
                            psuEventCleared = true;
                        }
                    }

                    // Filter the wanted warning type(s).
                    if (eventlogWarningType1.ToLower().Contains(warningType.ToLower()))
                    {
                        // Skip "MyProgram" warnings.
                        if (!eventLogSource1.Entries[i].Source.Equals(EventSource))
                        {
                            // Check for disk error messages
                            foreach (var diskString in diskEventCheckList)
                            {
                                if (message.Contains(diskString))
                                {
                                    diskEventError = true;
                                }
                            }

                            // Check if PSU error message has to be sent
                            if (!psuEventError && !psuEventCleared)
                            {
                                foreach (var psuString in psuEventCheckList)
                                {
                                    if (message.Contains(psuString))
                                    {
                                        psuEventError = true;
                                        Console.WriteLine(message);
                                    }
                                }
                            }

                            lastEventlogWarning = eventLogSource1.Entries[i].Index;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error in CheckEventlog() " + ex.Message);
            }
        }
    }
}
 
Share this answer
 
v7
Comments
Member 14545110 31-Jul-19 4:20am    
public static void Main()
{
// check for the event log source on specified machine
// the Application event log source on MCBcomputer
if (!EventLog.Exists("Application", "Intel"))
{
Console.WriteLine("The log does not exist!");
return;
}
EventLog myLog = new EventLog();
myLog.Log = "Application";
myLog.MachineName = "Intel";
Console.WriteLine("There are " + myLog.Entries.Count + " entr[y|ies] in the Application log:");
foreach (EventLogEntry entry in myLog.Entries)
{
Console.WriteLine("\tEntry: " + entry.Message);
}
// check for Demo event log source existence
// create it if it not exist
if (!EventLog.SourceExists("Demo"))
{
EventLog.CreateEventSource("Demo", "Demo");
}
EventLog.WriteEntry("AnySource", "writing error to demo log.",
EventLogEntryType.Error);
Console.WriteLine("Monitoring of Application event log began...");
Console.WriteLine(@"Press 'q' and 'Enter' to quit");
while (Console.Read() != 'q')
{
// Now we will monitor the new entries that will be written.
// When you create an EntryWrittenEventHandler delegate
// you identify the method that will handle the event.
myLog.EntryWritten += new EntryWrittenEventHandler(OnEntryWritten);
// EnableRaisingEvents gets or sets a value indicating whether the
// EventLog instance receives EntryWritten event notifications.
myLog.EnableRaisingEvents = true;
}
}
public static void OnEntryWritten(Object source, EntryWrittenEventArgs e)
{
Console.WriteLine("written entry: " + e.Entry.Message);
}
i have try this but it gives all a bulk Result. how can get power supply interrupted Log Notification.. Please help me if you have any kind of Code
Member 14545110 31-Jul-19 6:28am    
checkEventlog = Task.Factory.StartNew(() => this.CheckEventlog(eventLogSource, eventlogWarningType));
-----------------------------
what is " CheckEventlog " . this Gives Error
-------

while (Running)
{
if (checkEventlog != null)
{
if (checkEventlog.IsCompleted)
{
checkEventlog.Dispose();
checkEventlog = Task.Factory.StartNew(() => this.CheckEventlog(eventLogSource, eventlogWarningType));
}
}

var stopwatch = new Stopwatch();
stopwatch.Reset();
stopwatch.Start();

while ((stopwatch.ElapsedMilliseconds < 10000) && Running)
{
// Avoid high CPU usage by tight loop.
Thread.CurrentThread.Join(100);
#if DEBUG
Application.DoEvents();
#endif
stopwatch.Stop();
}
}
---------------------
while (Running) . what is Running.. it Giving Error
RickZeeland 31-Jul-19 6:36am    
Running is a boolean variable that I use to stop the application, you can replace it with True. checkEventlog is a Task.
RickZeeland 31-Jul-19 6:43am    
The line stopwatch.Stop(); had to be outside the loop, updated the solution :)
Member 14545110 31-Jul-19 7:06am    
One last thing sir
private const string EventSource = "MyProgramName";
in This Line what MyProgramName Name?
 
Share this answer
 
Comments
Member 14545110 31-Jul-19 5:12am    
PBT_APMPOWERSTATUSCHANGE This function Works in laptop Charging and Unchanging. how i get EventLog 's Event ID For UPS Supply. and Main Supply Event ID.
Richard MacCutchan 31-Jul-19 5:15am    
Sorry, I do not know. You need to study the MSDN documentation for all power notification messages
Member 14545110 31-Jul-19 5:17am    
no Problem Bro.. Reply me if you have any other way to solve this problem.
Please look into below link.
WinMust - Simple UPS Status Monitor[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900