-
Notifications
You must be signed in to change notification settings - Fork 0
/
Power.cs
161 lines (143 loc) · 5.31 KB
/
Power.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
namespace Gravity
{
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
//using System.Linq;
using System.Collections.Generic;
using System.Text;
//public class test
//{
// static void Main()
// {
// PowerNotifications pn = new PowerNotifications();
// pn.Start();
// Console.WriteLine("starting to sleep");
// Thread.Sleep(20000);
// pn.Stop();
// Console.WriteLine("finally done");
// }
//}
public class PowerNotifications
{
public delegate void PowerStatusChangeEventHandler(object sender, System.EventArgs e, string strPowerMessage);
public event PowerStatusChangeEventHandler PowerStatusChanged;
IntPtr ptr = IntPtr.Zero;
Thread t = null;
bool done = false;
[DllImport("coredll.dll")]
private static extern IntPtr RequestPowerNotifications(IntPtr hMsgQ, uint Flags);
[DllImport("coredll.dll")]
private static extern uint WaitForSingleObject(IntPtr hHandle, int wait);
[DllImport("coredll.dll")]
private static extern IntPtr CreateMsgQueue(string name, ref MsgQOptions options);
[DllImport("coredll.dll")]
private static extern bool ReadMsgQueue(IntPtr hMsgQ, byte[] lpBuffer, uint cbBufSize, ref uint lpNumRead, int dwTimeout, ref uint pdwFlags);
public PowerNotifications()
{
MsgQOptions options = new MsgQOptions();
options.dwFlags = 0;
options.dwMaxMessages = 20;
options.cbMaxMessage = 10000;
options.bReadAccess = true;
options.dwSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(options);
ptr = CreateMsgQueue("Test", ref options);
RequestPowerNotifications(ptr, 0xFFFFFFFF);
t = new Thread(new ThreadStart(DoWork));
}
public void Start()
{
t.Start();
}
public void Stop()
{
done = true;
t.Abort();
}
private void DoWork()
{
byte[] buf = new byte[10000];
uint nRead = 0, flags = 0, res = 0;
Console.WriteLine("starting loop");
try
{
while (!done)
{
res = WaitForSingleObject(ptr, 1000);
if (res == 0)
{
ReadMsgQueue(ptr, buf, (uint)buf.Length, ref nRead, -1, ref flags);
//Console.WriteLine("message: " + ConvertByteArray(buf, 0) + " flag: " + ConvertByteArray(buf, 4));
uint flag = ConvertByteArray(buf, 4);
string msg = null;
switch (flag)
{
// case 65536:
// msg = "Power On";
// break;
case 0x00020000:
msg = "Power Off";
System.EventArgs p = new System.EventArgs();
PowerStatusChanged(this, p, msg);
break;
//case 262144:
// msg = "Power Critical";
// break;
//case 524288:
// msg = "Power Boot";
// break;
//case 1048576:
// msg = "Power Idle";
// break;
//case 2097152:
// msg = "Power Suspend";
// break;
//case 8388608:
// msg = "Power Reset";
// break;
case 0:
// non power transition messages are ignored
break;
default:
msg = "Unknown Flag: " + flag;
break;
}
if (msg != null)
Console.WriteLine(msg);
}
}
}
catch (Exception ex)
{
if (!done)
{
Console.WriteLine("Got exception: " + ex.ToString());
}
}
}
uint ConvertByteArray(byte[] array, int offset)
{
uint res = 0;
res += array[offset];
res += array[offset + 1] * (uint)0x100;
res += array[offset + 2] * (uint)0x10000;
res += array[offset + 3] * (uint)0x1000000;
return res;
}
[StructLayout(LayoutKind.Sequential)]
public struct MsgQOptions
{
public uint dwSize;
public uint dwFlags;
public uint dwMaxMessages;
public uint cbMaxMessage;
public bool bReadAccess;
}
}
}