C# 服务计划,Can';无法检测笔记本电脑盖的状态

C# 服务计划,Can';无法检测笔记本电脑盖的状态,c#,C#,我写了一个小程序,当盖子关闭时关闭我的笔记本电脑屏幕,当盖子打开时打开屏幕 我尝试了很多,但是我的代码中仍然有一些错误。“OnLidPowerEvent”功能不起作用 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Linq; using System.ServiceProce

我写了一个小程序,当盖子关闭时关闭我的笔记本电脑屏幕,当盖子打开时打开屏幕

我尝试了很多,但是我的代码中仍然有一些错误。“OnLidPowerEvent”功能不起作用

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Runtime.InteropServices;

namespace DeviceWatcher
{
    public partial class Service1 : ServiceBase
    {
        [DllImport("User.dll", CharSet = CharSet.Unicode)]
        public static extern int SendMessage(int hWnd,int Msg,int wParam,int lParam);

        public const int HWND_BROADCAST = 0xffff;
        public const int WM_SYSCOMMAND = 0x0112;
        public const int SC_MONITORPOWER = 0xf170;
        // Broadcast Msg to close screen

        [DllImport("User32.dll", CharSet = CharSet.Unicode)]
        public static extern int RegisterPowerSettingNotification(IntPtr Recipient, Guid guid, int flags);

        static Guid GUID_LIDSWITCH_STATE_CHANGE = new Guid(0xBA3E0F4D, 0xB817, 0x4094, 0xA2, 0xD1, 0xD5, 0x63, 0x79, 0xE6, 0xA0, 0xF3);
        public const int DEVICE_NOTIFY_SERVICE_HANDLE = 1;
        // using DEVICE_NOTIFY_SERVICE_HANDLE as flag

        public delegate int callbackEx(int control, int eventType, IntPtr eventData, IntPtr context);
        callbackEx hamster = OnLidPowerEvent; 

        [DllImport("Advapi32.dll", CharSet = CharSet.Unicode)]
        public static extern IntPtr RegisterServiceCtrlHandlerEx(string lpServiceName, callbackEx lpHandlerProc, IntPtr lpContext);

        internal struct POWERBROADCAST_SETTING
        {
            public Guid PowerSetting;
            public uint DataLength;
            public byte Data;
        }
        private static POWERBROADCAST_SETTING pos = new POWERBROADCAST_SETTING();

        public Service1()
        {
            InitializeComponent();
            //this.CanHandlePowerEvent = true;
            // C# Service can not deal GUID_LIDSWITCH_STATE_CHANGE
            this.ServiceName = "DeviceWatcher";

            IntPtr serviceControlHandle = RegisterServiceCtrlHandlerEx("DeviceWatcher", hamster, IntPtr.Zero);
            RegisterPowerSettingNotification(serviceControlHandle,GUID_LIDSWITCH_STATE_CHANGE,DEVICE_NOTIFY_SERVICE_HANDLE);
            // should I using this.serviceHandle or this.ServiceHandle

            using (System.IO.StreamWriter sw = new System.IO.StreamWriter("C:\\log.txt", true))
            {
                sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ") + "Service Init.");
            }
        }

        private static int OnLidPowerEvent(int control, int eventType, IntPtr eventData, IntPtr context)
        {
            using (System.IO.StreamWriter sw = new System.IO.StreamWriter("C:\\log.txt", true))
            {
                sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ") + "PowerFunc Called.");
            }
            // never reach this Function when my Notebook Lid Closes. :-(

            // below need some check on pos data
            pos = (POWERBROADCAST_SETTING)Marshal.PtrToStructure(eventData, typeof(POWERBROADCAST_SETTING));

            if (pos.PowerSetting == GUID_LIDSWITCH_STATE_CHANGE)
            {
                if (pos.Data == 0)
                {
                    SendMessage(HWND_BROADCAST,WM_SYSCOMMAND,SC_MONITORPOWER,2);
                    // when lid Closes,turn screen off
                }
                else if (pos.Data == 1)
                {
                    SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, -1);
                    // when lid opens ,turn screen on
                }
            }
            return 0;
        }

        protected override void OnStart(string[] args)
        {
            using (System.IO.StreamWriter sw = new System.IO.StreamWriter("C:\\log.txt", true))
            {
                sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ") + "Service Start Func.");
            }            
        }

        protected override void OnStop()
        {
            using (System.IO.StreamWriter sw = new System.IO.StreamWriter("C:\\log.txt", true))
            {
                sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ") + "Service Stop Func.");
            }
        }
    }
}
答案很简单:

1st:Windows服务无法发送消息,使用通用应用程序将正常工作

2nd:C#服务可能与C/C++服务有所不同,使用RegisterPowerSettingNotification()将永远无法工作

找到原因后,我编写了一个纯C和Winapi程序。 它工作得很好

非常感谢那些关心这个问题的人