当盖子关闭时,我写了一个小程序来关闭我的笔记本屏幕,当盖子打开时我打开屏幕。
我尝试了很多,但我的代码仍有问题。功能" 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.");
}
}
}
}
答案 0 :(得分:0)
答案很简单:
第一:Windows服务无法发送消息,使用通用应用程序将正常运行。
第二:C#服务可能与C / C ++服务不同,使用RegisterPowerSettingNotification()永远不会让它工作。
在找到原因后,我写了一个纯C和Winapi程序。 它很完美。
非常感谢那些关心这个问题的人!