提交记录修改Core/Servicers/Instances/Sleepdiscover.cs+185 −115看文件
| @@ -9,6 +9,7 @@ using System.Diagnostics; | ||
| 9 | 9 | using System.Linq; |
| 10 | 10 | using System.Runtime.InteropServices; |
| 11 | 11 | using System.Text; |
| 12 | 新增:using System.Threading; | |
| 12 | 13 | using System.Threading.Tasks; |
| 13 | 14 | using System.Windows; |
| 14 | 15 | using System.Windows.Threading; |
| @@ -35,20 +36,45 @@ namespace Core.Servicers.Instances | ||
| 35 | 36 | /// </summary> |
| 36 | 37 | private DateTime pressKeyboardLastTime; |
| 37 | 38 | |
| 38 | 删除: private readonly IObserver observer; | |
| 39 | 删除: | |
| 39 | 新增: // 键盘钩子 | |
| 40 | 40 | private Win32API.LowLevelKeyboardProc keyboardProc; |
| 41 | 41 | private static IntPtr hookKeyboardID = IntPtr.Zero; |
| 42 | 新增: | |
| 43 | 新增: | |
| 44 | 新增: // 鼠标钩子 | |
| 45 | 新增: private Win32API.LowLevelKeyboardProc mouseProc; | |
| 46 | 新增: private static IntPtr hookMouseID = IntPtr.Zero; | |
| 47 | 新增: private IntPtr mouseHook; | |
| 48 | 新增: | |
| 42 | 49 | private int emptyPointNum = 0; |
| 43 | 删除: public Sleepdiscover(IObserver observer) | |
| 50 | 新增: public Sleepdiscover() | |
| 44 | 51 | { |
| 45 | 删除: this.observer = observer; | |
| 46 | 删除: observer.OnAppActive += Observer_OnAppActive; | |
| 47 | 52 | SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(OnPowerModeChanged); |
| 48 | 53 | SystemEvents.SessionSwitch += SystemEvents_SessionSwitch; |
| 54 | 新增: | |
| 49 | 55 | keyboardProc = HookCallback; |
| 56 | 新增: mouseProc = HookMouseCallback; | |
| 50 | 57 | } |
| 51 | 58 | |
| 59 | 新增: public void Start() | |
| 60 | 新增: { | |
| 61 | 新增: timer = new DispatcherTimer(); | |
| 62 | 新增: timer.Interval = new TimeSpan(0, 5, 0); | |
| 63 | 新增: //#if DEBUG | |
| 64 | 新增: // timer.Interval = new TimeSpan(0, 0, 10); | |
| 65 | 新增: //#endif | |
| 66 | 新增: timer.Tick += Timer_Tick; | |
| 67 | 新增: timer.Start(); | |
| 68 | 新增: | |
| 69 | 新增: lastPoint = Win32API.GetCursorPosition(); | |
| 70 | 新增: | |
| 71 | 新增: playSoundStartTime = DateTime.MinValue; | |
| 72 | 新增: | |
| 73 | 新增: pressKeyboardLastTime = DateTime.Now; | |
| 74 | 新增: | |
| 75 | 新增: // 设置键盘钩子 | |
| 76 | 新增: Win32API.SetKeyboardHook(keyboardProc); | |
| 77 | 新增: } | |
| 52 | 78 | private void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e) |
| 53 | 79 | { |
| 54 | 80 | if (e.Reason == SessionSwitchReason.RemoteDisconnect || e.Reason == SessionSwitchReason.ConsoleDisconnect) |
| @@ -56,24 +82,38 @@ namespace Core.Servicers.Instances | ||
| 56 | 82 | // 与这台设备远程桌面连接断开 |
| 57 | 83 | if (status == SleepStatus.Wake) |
| 58 | 84 | { |
| 59 | 删除: status = SleepStatus.Sleep; | |
| 60 | 删除: SleepStatusChanged?.Invoke(status); | |
| 61 | 85 | Logger.Warn("与这台设备远程桌面连接断开"); |
| 86 | 新增: Sleep(); | |
| 62 | 87 | } |
| 63 | 88 | } |
| 64 | 89 | } |
| 65 | 90 | |
| 91 | 新增: private IntPtr HookMouseCallback(int nCode, IntPtr wParam, IntPtr lParam) | |
| 92 | 新增: { | |
| 93 | 新增: | |
| 94 | 新增: if (nCode >= 0) | |
| 95 | 新增: { | |
| 96 | 新增: if (wParam == (IntPtr)Win32API.WM_LBUTTONDBLCLK || wParam == (IntPtr)Win32API.WM_WHEEL) | |
| 97 | 新增: { | |
| 98 | 新增: Logger.Info("鼠标唤醒"); | |
| 99 | 新增: | |
| 100 | 新增: Wake(); | |
| 101 | 新增: } | |
| 102 | 新增: | |
| 103 | 新增: } | |
| 104 | 新增: | |
| 105 | 新增: return Win32API.CallNextHookEx(hookMouseID, nCode, wParam, lParam); | |
| 106 | 新增: } | |
| 66 | 107 | private IntPtr HookCallback( |
| 67 | 108 | int nCode, IntPtr wParam, IntPtr lParam) |
| 68 | 109 | { |
| 69 | 110 | if (nCode >= 0 && wParam == (IntPtr)Win32API.WM_KEYDOWN) |
| 70 | 111 | { |
| 71 | 删除: int vkCode = Marshal.ReadInt32(lParam); | |
| 72 | 删除: | |
| 73 | 112 | if (status == SleepStatus.Sleep) |
| 74 | 113 | { |
| 75 | 删除: status = SleepStatus.Wake; | |
| 76 | 删除: SleepStatusChanged?.Invoke(status); | |
| 114 | 新增: Logger.Info("键盘唤醒"); | |
| 115 | 新增: | |
| 116 | 新增: Wake(); | |
| 77 | 117 | } |
| 78 | 118 | else |
| 79 | 119 | { |
| @@ -92,160 +132,190 @@ namespace Core.Servicers.Instances | ||
| 92 | 132 | // 电脑休眠 |
| 93 | 133 | if (status == SleepStatus.Wake) |
| 94 | 134 | { |
| 95 | 删除: status = SleepStatus.Sleep; | |
| 96 | 删除: SleepStatusChanged?.Invoke(status); | |
| 97 | 删除: Logger.Warn("设备已休眠"); | |
| 135 | 新增: Logger.Info("设备已休眠"); | |
| 136 | 新增: | |
| 137 | 新增: Sleep(); | |
| 98 | 138 | } |
| 99 | 139 | break; |
| 100 | 140 | case PowerModes.Resume: |
| 101 | 141 | // 电脑恢复 |
| 102 | 142 | if (status == SleepStatus.Sleep) |
| 103 | 143 | { |
| 104 | 删除: playSoundStartTime = DateTime.MinValue; | |
| 105 | 删除: status = SleepStatus.Wake; | |
| 106 | 删除: SleepStatusChanged?.Invoke(status); | |
| 107 | 删除: Logger.Warn("设备已恢复"); | |
| 144 | 新增: Logger.Info("设备已恢复"); | |
| 145 | 新增: | |
| 146 | 新增: Wake(); | |
| 108 | 147 | } |
| 109 | 148 | break; |
| 110 | 149 | } |
| 111 | 150 | } |
| 112 | 151 | |
| 113 | 删除: private void Observer_OnAppActive(string processName, string description, string file) | |
| 152 | 新增: | |
| 153 | 新增: | |
| 154 | 新增: #region 指示当前是否处于睡眠状态 | |
| 155 | 新增: /// <summary> | |
| 156 | 新增: /// 指示当前是否处于睡眠状态 | |
| 157 | 新增: /// </summary> | |
| 158 | 新增: /// <returns>睡眠返回true</returns> | |
| 159 | 新增: private async Task<bool> IsSleepAsync() | |
| 114 | 160 | { |
| 115 | 删除: if (status == SleepStatus.Sleep) | |
| 161 | 新增: // 1.先判断鼠标是否有过移动 | |
| 162 | 新增: Point point = Win32API.GetCursorPosition(); | |
| 163 | 新增: | |
| 164 | 新增: if (point.X + point.Y == 0) | |
| 116 | 165 | { |
| 117 | 删除: TimeSpan timeSpan = DateTime.Now - pressKeyboardLastTime; | |
| 166 | 新增: emptyPointNum++; | |
| 118 | 167 | |
| 119 | 删除: Point point = Win32API.GetCursorPosition(); | |
| 120 | 删除: if (lastPoint.ToString() == point.ToString() && timeSpan.TotalSeconds > 10) | |
| 168 | 新增: if (emptyPointNum == 2) | |
| 121 | 169 | { |
| 122 | 删除: // 非鼠标或键盘激活 | |
| 123 | 删除: return; | |
| 170 | 新增: emptyPointNum = 0; | |
| 171 | 新增: return true; | |
| 124 | 172 | } |
| 173 | 新增: } | |
| 125 | 174 | |
| 126 | 删除: playSoundStartTime = DateTime.MinValue; | |
| 127 | 删除: status = SleepStatus.Wake; | |
| 128 | 删除: SleepStatusChanged?.Invoke(status); | |
| 175 | 新增: if (lastPoint.ToString() != point.ToString()) | |
| 176 | 新增: { | |
| 177 | 新增: // 鼠标在移动,更新坐标 | |
| 178 | 新增: lastPoint = point; | |
| 179 | 新增: return false; | |
| 129 | 180 | } |
| 130 | 删除: } | |
| 131 | 181 | |
| 132 | 删除: public void Start() | |
| 133 | 删除: { | |
| 134 | 删除: timer = new DispatcherTimer(); | |
| 135 | 删除: timer.Interval = new TimeSpan(0, 2, 0); | |
| 136 | 删除:#if DEBUG | |
| 137 | 删除: //timer.Interval = new TimeSpan(0, 0, 10); | |
| 138 | 删除:#endif | |
| 139 | 删除: timer.Tick += Timer_Tick; | |
| 140 | 删除: timer.Start(); | |
| 182 | 新增: // 2.判断是否键盘超时 | |
| 183 | 新增: if (!IsKeyboardOuttime()) | |
| 184 | 新增: { | |
| 185 | 新增: // 十分钟内有键盘操作 | |
| 186 | 新增: return false; | |
| 187 | 新增: } | |
| 141 | 188 | |
| 142 | 删除: lastPoint = Win32API.GetCursorPosition(); | |
| 189 | 新增: // 3.鼠标和键盘都没有操作时判断是否在播放声音 | |
| 143 | 190 | |
| 144 | 删除: playSoundStartTime = DateTime.MinValue; | |
| 191 | 新增: // 持续30秒检测当前是否在播放声音 | |
| 192 | 新增: bool isPlaySound = await IsPlaySoundAsync(); | |
| 145 | 193 | |
| 146 | 删除: pressKeyboardLastTime = DateTime.Now; | |
| 194 | 新增: if (!isPlaySound) | |
| 195 | 新增: { | |
| 196 | 新增: // 没有声音判定为睡眠状态 | |
| 197 | 新增: return true; | |
| 198 | 新增: } | |
| 147 | 199 | |
| 148 | 删除: // 设置键盘钩子 | |
| 149 | 删除: Win32API.SetKeyboardHook(keyboardProc); | |
| 200 | 新增: // 在播放声音 | |
| 201 | 新增: if (playSoundStartTime == DateTime.MinValue) | |
| 202 | 新增: { | |
| 203 | 新增: // 第一次记录声音开始时间 | |
| 204 | 新增: playSoundStartTime = DateTime.Now; | |
| 205 | 新增: return false; | |
| 206 | 新增: } | |
| 207 | 新增: | |
| 208 | 新增: // 声音播放超过两个小时视为睡眠状态 | |
| 209 | 新增: TimeSpan timeSpan = DateTime.Now - playSoundStartTime; | |
| 210 | 新增: | |
| 211 | 新增: if (timeSpan.TotalHours >= 2) | |
| 212 | 新增: { | |
| 213 | 新增: // 重置声音开始时间 | |
| 214 | 新增: playSoundStartTime = DateTime.MinValue; | |
| 215 | 新增: return true; | |
| 216 | 新增: } | |
| 217 | 新增: | |
| 218 | 新增: return false; | |
| 150 | 219 | } |
| 220 | 新增: #endregion | |
| 151 | 221 | |
| 152 | 删除: private void Timer_Tick(object sender, EventArgs e) | |
| 222 | 新增: private async void Timer_Tick(object sender, EventArgs e) | |
| 153 | 223 | { |
| 154 | 删除: Point point = Win32API.GetCursorPosition(); | |
| 155 | 删除: | |
| 156 | 删除: if (point.X + point.Y == 0) | |
| 224 | 新增: timer.Stop(); | |
| 225 | 新增: bool isSleep = await IsSleepAsync(); | |
| 226 | 新增: if (isSleep) | |
| 157 | 227 | { |
| 158 | 删除: emptyPointNum++; | |
| 228 | 新增: Sleep(); | |
| 229 | 新增: } | |
| 230 | 新增: else | |
| 231 | 新增: { | |
| 232 | 新增: timer.Start(); | |
| 233 | 新增: } | |
| 234 | 新增: } | |
| 159 | 235 | |
| 160 | 删除: if (emptyPointNum == 2) | |
| 161 | 删除: { | |
| 162 | 删除: emptyPointNum = 0; | |
| 163 | 删除: status = SleepStatus.Sleep; | |
| 164 | 删除: SleepStatusChanged?.Invoke(status); | |
| 165 | 删除: Logger.Info("empty point num:" + point.ToString()); | |
| 166 | 删除: } | |
| 236 | 新增: private void Sleep() | |
| 237 | 新增: { | |
| 238 | 新增: // 停止离开检测计时器 | |
| 239 | 新增: timer.Stop(); | |
| 240 | 新增: | |
| 241 | 新增: if (status == SleepStatus.Sleep) | |
| 242 | 新增: { | |
| 167 | 243 | return; |
| 168 | 244 | } |
| 245 | 新增: status = SleepStatus.Sleep; | |
| 169 | 246 | |
| 170 | 删除: if (lastPoint == null) | |
| 247 | 新增: // 设置鼠标钩子 | |
| 248 | 新增: mouseHook = Win32API.SetMouseHook(mouseProc); | |
| 249 | 新增: | |
| 250 | 新增: // 状态通知 | |
| 251 | 新增: SleepStatusChanged?.Invoke(status); | |
| 252 | 新增: } | |
| 253 | 新增: | |
| 254 | 新增: private void Wake() | |
| 255 | 新增: { | |
| 256 | 新增: if (status == SleepStatus.Wake) | |
| 171 | 257 | { |
| 172 | 删除: lastPoint = point; | |
| 173 | 258 | return; |
| 174 | 259 | } |
| 175 | 260 | |
| 176 | 删除: if (status == SleepStatus.Wake) | |
| 261 | 新增: status = SleepStatus.Wake; | |
| 262 | 新增: | |
| 263 | 新增: // 卸载鼠标钩子 | |
| 264 | 新增: Win32API.UnhookWindowsHookEx(mouseHook); | |
| 265 | 新增: | |
| 266 | 新增: // 启动离开检测 | |
| 267 | 新增: timer.Start(); | |
| 268 | 新增: | |
| 269 | 新增: | |
| 270 | 新增: | |
| 271 | 新增: // 重置声音播放时间 | |
| 272 | 新增: playSoundStartTime = DateTime.MinValue; | |
| 273 | 新增: | |
| 274 | 新增: // 重置鼠标坐标 | |
| 275 | 新增: lastPoint = Win32API.GetCursorPosition(); | |
| 276 | 新增: | |
| 277 | 新增: // 状态通知 | |
| 278 | 新增: SleepStatusChanged?.Invoke(status); | |
| 279 | 新增: | |
| 280 | 新增: } | |
| 281 | 新增: | |
| 282 | 新增: private async Task<bool> IsPlaySoundAsync() | |
| 283 | 新增: { | |
| 284 | 新增: bool result = false; | |
| 285 | 新增: | |
| 286 | 新增: await Task.Run(() => | |
| 177 | 287 | { |
| 288 | 新增: // 持续30秒 | |
| 289 | 新增: int time = 30; | |
| 178 | 290 | |
| 179 | 删除: if (lastPoint.ToString() == point.ToString()) | |
| 291 | 新增: while (time > 0) | |
| 180 | 292 | { |
| 181 | 删除: // 处于活跃状态 | |
| 182 | 删除: bool isPlaySound = Win32API.IsWindowsPlayingSound(); | |
| 183 | 删除: // 超过时间未活动鼠标 | |
| 184 | 删除: | |
| 185 | 删除: if (isPlaySound) | |
| 293 | 新增: bool isPlay = Win32API.IsWindowsPlayingSound(); | |
| 294 | 新增: if (isPlay) | |
| 186 | 295 | { |
| 187 | 删除: // 在播放声音 | |
| 188 | 删除: | |
| 189 | 删除: if (playSoundStartTime == DateTime.MinValue) | |
| 190 | 删除: { | |
| 191 | 删除: playSoundStartTime = DateTime.Now;//没有正确更新时间导致没超过2个小时就进入睡眠状态了 | |
| 192 | 删除: } | |
| 193 | 删除: else | |
| 194 | 删除: { | |
| 195 | 删除: // 判断声音时间是否超过2个小时 | |
| 196 | 删除: TimeSpan timeSpan = DateTime.Now - playSoundStartTime; | |
| 197 | 删除: | |
| 198 | 删除: if (timeSpan.TotalHours >= 2 && IsPressKeyboardOuttime()) | |
| 199 | 删除: { | |
| 200 | 删除: // 超过表示可能睡着了,切换状态 | |
| 201 | 删除: status = SleepStatus.Sleep; | |
| 202 | 删除: Logger.Info("[sleep] [1] time:" + timeSpan.TotalHours + ",start:" + playSoundStartTime); | |
| 203 | 删除: | |
| 204 | 删除: playSoundStartTime = DateTime.MinValue; | |
| 205 | 删除: SleepStatusChanged?.Invoke(status); | |
| 206 | 删除: } | |
| 207 | 删除: } | |
| 296 | 新增: result = true; | |
| 297 | 新增: break; | |
| 208 | 298 | } |
| 209 | 299 | else |
| 210 | 300 | { |
| 211 | 删除: if (IsPressKeyboardOuttime()) | |
| 212 | 删除: { | |
| 213 | 删除: // 没有播放声音且键盘休眠超时 | |
| 214 | 删除: status = SleepStatus.Sleep; | |
| 215 | 删除: Logger.Info("[sleep] [2] " + pressKeyboardLastTime); | |
| 216 | 删除: | |
| 217 | 删除: SleepStatusChanged?.Invoke(status); | |
| 218 | 删除: } | |
| 301 | 新增: time--; | |
| 302 | 新增: Debug.WriteLine(time); | |
| 303 | 新增: Thread.Sleep(1000); | |
| 219 | 304 | } |
| 220 | 305 | } |
| 221 | 删除: else | |
| 222 | 删除: { | |
| 223 | 删除: playSoundStartTime = DateTime.MinValue; | |
| 224 | 删除: } | |
| 225 | 删除: } | |
| 226 | 删除: else | |
| 227 | 删除: { | |
| 228 | 删除: // 处于休眠状态 | |
| 229 | 删除: if (lastPoint.ToString() != point.ToString()) | |
| 230 | 删除: { | |
| 231 | 删除: // 鼠标活动了切换状态 | |
| 232 | 删除: status = SleepStatus.Wake; | |
| 233 | 删除: SleepStatusChanged?.Invoke(status); | |
| 234 | 删除: } | |
| 235 | 删除: } | |
| 236 | 删除: | |
| 237 | 删除: lastPoint = point; | |
| 306 | 新增: }); | |
| 307 | 新增: return result; | |
| 238 | 308 | } |
| 239 | 309 | |
| 240 | 删除: | |
| 241 | 310 | /// <summary> |
| 242 | 删除: /// 通过按键时间判断(超过5分钟未有键盘操作视为超时) | |
| 311 | 新增: /// 指示是否键盘行为超时(超过10分钟) | |
| 243 | 312 | /// </summary> |
| 244 | 删除: /// <returns></returns> | |
| 245 | 删除: private bool IsPressKeyboardOuttime() | |
| 313 | 新增: /// <returns>超时返回true</returns> | |
| 314 | 新增: private bool IsKeyboardOuttime() | |
| 246 | 315 | { |
| 247 | 316 | TimeSpan timeSpan = DateTime.Now - pressKeyboardLastTime; |
| 248 | 删除: return timeSpan.TotalMinutes >= 5; | |
| 317 | 新增: | |
| 318 | 新增: return timeSpan.TotalMinutes >= 10; | |
| 249 | 319 | } |
| 250 | 320 | } |
| 251 | 321 | } |

