Hook into lid close event using a .NET Windows Application

-3

I am looking make a .NET Windows application that will function similar to laplock. I have tried to implement Laplock but when my systems team deploy it via policy, it wants to run in 64-bit and does not work. I am stuck on how to run the WndProc in my program.

I have been going off of the SO article here. I do not know how to perform the "AddHook" in a .NET Windows Application

void MainWindow_SourceInitialized(object sender, EventArgs e)
{
    RegisterForPowerNotifications();

    // This is where I am getting lost at.
    IntPtr hwnd = new WindowInteropHelper(this).Handle;
    HwndSource.FromHwnd(hwnd).AddHook(new HwndSourceHook(WndProc));
}

This is what I have so far

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace Application
{
internal class Program
{
    /// <summary>
    /// Registers the application to receive power setting notifications for the specific power setting event
    /// </summary>
    /// <param name="hRecipient"></param>
    /// <param name="PowerSettingGuid"></param>
    /// <param name="Flags"></param>
    /// <returns></returns>
    [DllImport(@"User32", SetLastError = true, EntryPoint = "RegisterPowerSettingNotification", CallingConvention = CallingConvention.StdCall)]
    private static extern IntPtr RegisterPowerSettingNotification(IntPtr hRecipient, ref Guid PowerSettingGuid, int Flags);

    /// <summary>
    /// Locks the workstation's display
    /// </summary>
    /// <returns></returns>
    [DllImport("user32.dll")]
    public static extern bool LockWorkStation();

    internal struct POWERBROADCAST_SETTING
    {
        public Guid _PowerSetting;
        public uint _DataLength;
        public byte _Data;
    }

    private Guid _GUID_LIDSWITCH_STATE_CHANGE = new Guid(0xBA3E0F4D, 0xB817, 0x4094, 0xA2, 0xD1, 0xD5, 0x63, 0x79, 0xE6, 0xA0, 0xF3);
    private const int DEVICE_NOTIFY_WINDOW_HANDLE = 0x00000000;
    private const int WM_POWERBROADCAST = 0x0218;
    private const int PBT_POWERSETTINGCHANGE = 0x8013;

    private bool? _PreviousLidState = null;
    private IntPtr _Handle;


    private void Main(string[] args)
    {
        RegisterForPowerNotifications();
        
    }

    private void RegisterForPowerNotifications()
    {
        _Handle = new IntPtr();
        IntPtr hLIDSWITCHSTATECHANGE = RegisterPowerSettingNotification(_Handle, ref _GUID_LIDSWITCH_STATE_CHANGE, DEVICE_NOTIFY_WINDOW_HANDLE);
    }

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        switch (msg)
        {
            case WM_POWERBROADCAST:
                OnPowerBroadcast(wParam, lParam);
                break;
            default:
                break;
        }
        return IntPtr.Zero;
    }

    private void OnPowerBroadcast(IntPtr wParam, IntPtr lParam)
    {
        if ((int)wParam == PBT_POWERSETTINGCHANGE)
        {
            POWERBROADCAST_SETTING ps = (POWERBROADCAST_SETTING)Marshal.PtrToStructure(lParam, typeof(POWERBROADCAST_SETTING));
            IntPtr pData = (IntPtr)((int)lParam + Marshal.SizeOf(ps));
            int iData = (int)Marshal.PtrToStructure(pData, typeof(int));
            if (ps._PowerSetting == _GUID_LIDSWITCH_STATE_CHANGE)
            {
                bool isLidOpen = ps._Data != 0;

                if (!isLidOpen == _PreviousLidState)
                {
                    LidStatusChanged(isLidOpen);
                }

                _PreviousLidState = isLidOpen;
            }
        }
    }

    private void LidStatusChanged(bool isLidOpen)
    {
        if (isLidOpen)
        {
            //Do some action on lid open event
        }
        else
        {
            //Do some action on lid close event
            LockWorkStation();
        }
    }
}
}
c#
.net
asked on Stack Overflow Aug 21, 2020 by Red_Phoenix

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0