user3071296
user3071296

Reputation: 103

C# How to use CallNtPowerInformation with Interop to get SYSTEM_POWER_INFORMATION

I am trying to write a small program that runs as a service and monitors if a user is active or not. If the user is idle (no mouse/keyboard) for an hour, then certain processes are killed. Got it working if run by a user by using the LASTINPUTINFO from user32.dll, but it won't work as a service. Looking further I ran across someone saying to call CallNtPowerInformation with SystemPowerInformation and examine the TimeRemaining member. I'd like to do this but have little experience with interop and was hoping to get a little help/example:

In C# I would import:

[DllImport("powrprof.dll", SetLastError = true)]
    private static extern UInt32 CallNtPowerInformation(
         Int32 InformationLevel,
         IntPtr lpInputBuffer,
         UInt32 nInputBufferSize,
         IntPtr lpOutputBuffer,
         UInt32 nOutputBufferSize
         );

I believe then I would need to create a struct for SYSTEM_POWER_INFORMATION to handle the result?

Apologies for the n00bness

Upvotes: 3

Views: 2512

Answers (1)

David Heffernan
David Heffernan

Reputation: 613441

You can get the information you need like this:

using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    class Program
    {
        const int SystemPowerInformation = 12;
        const uint STATUS_SUCCESS = 0;

        struct SYSTEM_POWER_INFORMATION
        {
            public uint MaxIdlenessAllowed;
            public uint Idleness;
            public uint TimeRemaining;
            public byte CoolingMode;
        }

        [DllImport("powrprof.dll")]
        static extern uint CallNtPowerInformation(
            int InformationLevel,
            IntPtr lpInputBuffer,
            int nInputBufferSize,
            out SYSTEM_POWER_INFORMATION spi,
            int nOutputBufferSize
        );

        static void Main(string[] args)
        {
            SYSTEM_POWER_INFORMATION spi;
            uint retval = CallNtPowerInformation(
                SystemPowerInformation,
                IntPtr.Zero,
                0,
                out spi,
                Marshal.SizeOf(typeof(SYSTEM_POWER_INFORMATION))
            );
            if (retval == STATUS_SUCCESS)
                Console.WriteLine(spi.TimeRemaining);
            Console.ReadLine();
        }
    }
}

I cannot tell you whether or not this method will give you the information you need when run from a service.

Upvotes: 1

Related Questions