void _ThreadProc() { AHookWin hk = null, hm = null; AHookAcc hwe = null; try { try { if (_block.Has(BIEvents.Keys)) { hk = AHookWin.Keyboard(_keyHookProc ??= _KeyHookProc); } if (_block.HasAny(BIEvents.MouseClicks | BIEvents.MouseMoving)) { hm = AHookWin.Mouse(_mouseHookProc ??= _MouseHookProc); } } catch (AuException e1) { ADebug.Print(e1); _block = 0; return; } //failed to hook //This prevents occassional inserting a foreign key after the first our-script-pressed key. //To reproduce, let our script send small series of chars in loop, and simultaneously a foreign script send other chars. ATime.DoEvents(); //AOutput.Write("started"); Api.SetEvent(_syncEvent); //the acc hook detects Ctrl+Alt+Del, Win+L, UAC consent, etc. SystemEvents.SessionSwitch only Win+L. try { hwe = new AHookAcc(AccEVENT.SYSTEM_DESKTOPSWITCH, 0, _winEventProc ??= _WinEventProc); } catch (AuException e1) { ADebug.Print(e1); } //failed to hook AWaitFor.Wait_(-1, WHFlags.DoEvents, _stopEvent, _threadHandle); if (_blockedKeys != null) { bool onlyUp = _discardBlockedKeys || ATime.WinMilliseconds - _startTime > c_maxResendTime; _blockedKeys.SendBlocked_(onlyUp); } //AOutput.Write("ended"); } finally { _blockedKeys = null; hk?.Dispose(); hm?.Dispose(); hwe?.Dispose(); Api.SetEvent(_syncEvent); } GC.KeepAlive(this); }
/// <summary> /// Waits until the target app gets (Paste) or sets (Copy) clipboard text. /// Throws AuException on timeout (3 s normally, 28 s if the target window is hung). /// </summary> /// <param name="ctrlKey">The variable that was used to send Ctrl+V or Ctrl+C. This function may call Release to avoid too long Ctrl down.</param> public void Wait(ref AKeys.Internal_.SendCopyPaste ctrlKey) { //AOutput.Write(Success); //on Paste often already true, because SendInput dispatches sent messages for (int n = 6; !Success;) //max 3 s (6*500 ms). If hung, max 28 s. { AWaitFor.Wait_(500, WHFlags.DoEvents, null, this); if (Success) { break; } //is hung? if (--n == 0) { throw new AuException(_paste ? "*paste" : "*copy"); } ctrlKey.Release(); _wFocus.SendTimeout(5000, 0, flags: 0); } }