diff --git a/FLSystem/Forms/main.cs b/FLSystem/Forms/main.cs index b2c32b7..fb3276d 100644 --- a/FLSystem/Forms/main.cs +++ b/FLSystem/Forms/main.cs @@ -101,6 +101,8 @@ namespace FLSystem.Forms { try { + //var ss = ApiClient.ShortURL("https://detail.tmall.com/item.htm?spm=a230r.1.14.16.11f547a36SIAOY&id=526234772827&ns=1&abbucket=1", DwzType.官方短网址).Result; + DevExpress.UserSkins.BonusSkins.Register(); DevExpress.Skins.SkinManager.EnableFormSkins(); @@ -573,7 +575,7 @@ namespace FLSystem.Forms System.Timers.Timer timer = new System.Timers.Timer(); timer.Elapsed += Timer_Elapsed; - timer.Interval = 40 * 60 * 1000; + timer.Interval = 60 * 60 * 1000; //timer.Interval = 1000 * 10; timer.Start(); diff --git a/PCRobot/PCRobot.csproj b/PCRobot/PCRobot.csproj index e1a025a..ac98f7e 100644 --- a/PCRobot/PCRobot.csproj +++ b/PCRobot/PCRobot.csproj @@ -211,6 +211,7 @@ + diff --git a/PCRobot/PCRobotForm.cs b/PCRobot/PCRobotForm.cs index 864afed..b3324a6 100644 --- a/PCRobot/PCRobotForm.cs +++ b/PCRobot/PCRobotForm.cs @@ -14,6 +14,7 @@ using System.Threading.Tasks; using System.Windows.Forms; using PCRobot.PCWechat.Enterprise; using PCRobot.PCWechat.Routine; +using WechatHelper; namespace PCRobot { @@ -38,6 +39,14 @@ namespace PCRobot private void PCRobotForm_Load(object sender, EventArgs e) { + + try + { + WeChatActivateHelper.Init(TimeSpan.FromMinutes(20)); + } + catch (Exception exception) + { } + try { //Common.MainExeHandle = this.Handle; @@ -84,7 +93,6 @@ namespace PCRobot IniData(); this.label5.Text = "版本:" + Common.CurVersion; - //MessageBox.Show("版本:" + Common.CurVersion); if (string.IsNullOrWhiteSpace(Config.GetValue("设置", "静态"))) { @@ -148,25 +156,26 @@ namespace PCRobot MessageBox.Show("异常 = " + ex.Message + " --- " + ex.StackTrace); } - try - { - //自动切换聊天对象 - var th = new Thread(OnHandle); - th.IsBackground = true; - th.Start(); - //切换窗口 - var th1 = new Thread(OnActivationHandle); - th1.IsBackground = true; - th1.Start(); + //try + //{ + // //自动切换聊天对象 + // var th = new Thread(OnHandle); + // th.IsBackground = true; + // th.Start(); - //发送消息 - var th2 = new Thread(OnSendHandle); - th2.IsBackground = true; - th2.Start(); - } - catch - { } + // //切换窗口 + // var th1 = new Thread(OnActivationHandle); + // th1.IsBackground = true; + // th1.Start(); + + // //发送消息 + // var th2 = new Thread(OnSendHandle); + // th2.IsBackground = true; + // th2.Start(); + //} + //catch + //{ } } List userNameList = new List() { "gh_3dfda90e39d6"/*, "gh_7aac992b0363"*/ }; diff --git a/PCRobot/Utils/WeChatActivateHelper.cs b/PCRobot/Utils/WeChatActivateHelper.cs new file mode 100644 index 0000000..7757a56 --- /dev/null +++ b/PCRobot/Utils/WeChatActivateHelper.cs @@ -0,0 +1,443 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using PCRobot; + +namespace WechatHelper +{ + /// + /// 微信激活帮助类 + /// + internal class WeChatActivateHelper + { + #region WIN32 API函数 + [DllImport("User32.dll", EntryPoint = "SendMessage")] + private static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam); + + /// + /// 聚焦 + /// + /// + /// + [DllImport("user32.dll", EntryPoint = "SetFocus")] + private static extern IntPtr SetFocus(IntPtr hWnd); + + /// + /// 判断是否最小化 + /// + /// + /// + [DllImport("user32.dll")] + private static extern bool IsIconic(IntPtr hWnd); + + /// + /// 判断是否可见 + /// + /// + /// + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool IsWindowVisible(IntPtr hWnd); + + [DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)] + public static extern int ShowWindow(IntPtr hwnd, int nCmdShow); + + /// + /// 附加线程输入 + /// + /// 当前线程 + /// 目标线程 + /// + /// + [DllImport("user32.dll", CharSet = CharSet.Unicode, EntryPoint = "AttachThreadInput", ExactSpelling = true, SetLastError = true)] + private static extern bool AttachThreadInput(IntPtr idAttach, IntPtr idAttachTo, bool fAttach); + + //通过句柄获取线程ID + [DllImport("User32.dll", CharSet = CharSet.Auto)] + private static extern IntPtr GetWindowThreadProcessId(IntPtr hwnd, IntPtr id); + + [System.Runtime.InteropServices.DllImport("user32.dll")] + private static extern IntPtr FindWindowExA(IntPtr parentHandle, IntPtr childAfter, string lpClassName, string lpWindowName); + + [System.Runtime.InteropServices.DllImport("USER32.DLL")] + private static extern bool SetForegroundWindow(IntPtr hWnd); + + [System.Runtime.InteropServices.DllImport("user32.dll")] + private static extern bool SetActiveWindow(IntPtr hWnd); + #endregion + + + /// + /// 激活窗口 + /// + private static void ActivateWindow(string lpClassName, string lpWindowName) + { + try + { + //主窗口句柄 + var handle = IntPtr.Zero; + var handleList = new List(); + do + { + //优先休眠,防止continue未休眠 + Thread.Sleep(1000); + + //查找窗口句柄并筛选 + handle = FindWindowExA(IntPtr.Zero, handle, lpClassName, lpWindowName); + if (handle == IntPtr.Zero) + { + break; + } + + if (handleList.Contains(handle)) + { + continue; + } + + handleList.Add(handle); + var isIconic = IsIconic(handle); + + //窗体不可见,视为最小化了 + var isWindowVisible = IsWindowVisible(handle); + if (!isWindowVisible) + { + isIconic = true; + } + + //窗体不可见,或者最小化了 + if (isIconic) + { + ShowWindow(handle, 1); + Thread.Sleep(1000); + } + + var thisHandel = Process.GetCurrentProcess().MainWindowHandle; + //获取自己的线程ID + var thisThreadId = GetWindowThreadProcessId(thisHandel, IntPtr.Zero); + var targetThreadId = GetWindowThreadProcessId(handle, IntPtr.Zero); + //如果这里报错,请添加引用PresentationFramework + var cur = _mSynchronizationContext; + + if (cur == null) + { + Console.WriteLine("当前线程信息获取失败"); + continue; + } + + var handle1 = handle; + cur.Send((e) => + { + try + { + //附加线程 + AttachThreadInput(targetThreadId, thisThreadId, true); + SetFocus(handle1); + var setForegroundWindowResult = SetForegroundWindow(handle1); + var setActiveWindow = SetActiveWindow(handle1); + AttachThreadInput(targetThreadId, thisThreadId, false); + LogHelper.GetSingleObj().Debug("激活", $"this={thisThreadId} target={targetThreadId} fore={setForegroundWindowResult} active={setActiveWindow} "); + + } + catch (Exception exception) + { + Console.WriteLine(exception); + } + + }, null); + + //如果微信最小化了,重新让他最小化 + if (!isIconic) continue; + + Thread.Sleep(1000); + ShowWindow(handle, 2); + } while (true); + } + catch (Exception e) + { + Console.WriteLine($"ActivateWindow Error:{e.Message}\r\nParams:lpClassName={lpClassName} lpWindowName={lpWindowName}"); + } + } + + /// + /// 关闭窗口 + /// + private static void CloseWindow(string className, string windowName) + { + int index = 1; + //主窗口句柄 + var handle = IntPtr.Zero; + var handleList = new List(); + do + { + try + { + Thread.Sleep(1000); + var rstHandlePtr = FindWindowExA(IntPtr.Zero, handle, className, windowName); + if (handle == IntPtr.Zero) break; + if (handleList.Contains(handle)) break; + handleList.Add(handle); + + //找到了,就自动关闭 + SendMessage(rstHandlePtr, 0x0010, 0, 0); + } + catch (Exception e) + { + Console.WriteLine($"关闭窗口失败:{e.Message}"); + break; + } + index++; + } while (index < 10); + } + + /// + /// 激活微信 + /// + private static void ActivateWeChat() + { + CloseWindow("UpdateWnd", "升级"); + ActivateWindow("WeChatMainWndForPC", "微信"); + } + + private static Thread _thread; + private static SynchronizationContext _mSynchronizationContext; + private static MouseHook _mouse; + private static DateTime _lastActiveTime = DateTime.Now; + + /// + /// 初始化激活器 + /// 注:请务必在主线程调用,不要再子线程 + /// + /// 多久激活一次 + /// 强制运行小时 + /// 总激活次数(0表示无限制) + /// + public static bool Init(TimeSpan time, int forcedRunHours = 2, int maxCount = 0) + { + if (_thread != null && _thread.IsAlive) + { + throw new Exception("当前线程尚未结束,请勿重复初始化"); + } + + if (_mouse == null) + { + _mouse = new MouseHook(); + _mouse.OnMouseActivity += _mouse_OnMouseActivity; + _mouse.Start(); + } + + + _mSynchronizationContext = SynchronizationContext.Current; + if (_mSynchronizationContext == null) + { + throw new Exception("获取主线程失败,请不要再子线程执行"); + } + + _thread = new Thread(() => + { + int index = 0; + while (true) + { + try + { + //操作鼠标键盘时间较短 + var curTime = DateTime.Now; + var interval = curTime - _mouseHeartbeatTime; + var isNext = false; + //超过12小时没有激活过,强制激活一次 + if ((curTime - _lastActiveTime).TotalHours > forcedRunHours) + { + isNext = true; + } + //超过了一定时间,没有操作鼠标 + else if (interval > time) + { + isNext = true; + } + + if (!isNext) continue; + index++; + _lastActiveTime = DateTime.Now; + ActivateWeChat(); + if (maxCount != 0 && index >= maxCount) + { + break; + } + } + catch (Exception e) + { + Console.WriteLine($"激活窗口发生异常:{e.Message}"); + } + finally + { + Thread.Sleep(time); + } + } + }) + { + IsBackground = true + }; + _thread.Start(); + return true; + } + + private static DateTime _mouseHeartbeatTime = DateTime.Now; + private static void _mouse_OnMouseActivity(object sender, MouseEventArgs e) + { + _mouseHeartbeatTime = DateTime.Now; + } + } + + internal class MouseHook + { + private const int WM_MOUSEMOVE = 0x200; + private const int WM_LBUTTONDOWN = 0x201; + private const int WM_RBUTTONDOWN = 0x204; + private const int WM_MBUTTONDOWN = 0x207; + private const int WM_LBUTTONUP = 0x202; + private const int WM_RBUTTONUP = 0x205; + private const int WM_MBUTTONUP = 0x208; + private const int WM_LBUTTONDBLCLK = 0x203; + private const int WM_RBUTTONDBLCLK = 0x206; + private const int WM_MBUTTONDBLCLK = 0x209; + + //全局的事件 + public event MouseEventHandler OnMouseActivity; + + static int hMouseHook = 0; //鼠标钩子句柄 + + //鼠标常量 + public const int WH_MOUSE_LL = 14; //mouse hook constant + + HookProc MouseHookProcedure; //声明鼠标钩子事件类型. + + //声明一个Point的封送类型 + [StructLayout(LayoutKind.Sequential)] + public class POINT + { + public int x; + public int y; + } + + //声明鼠标钩子的封送结构类型 + [StructLayout(LayoutKind.Sequential)] + public class MouseHookStruct + { + public POINT pt; + public int hWnd; + public int wHitTestCode; + public int dwExtraInfo; + } + + //装置钩子的函数 + [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] + public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId); + + //卸下钩子的函数 + [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] + public static extern bool UnhookWindowsHookEx(int idHook); + + //下一个钩挂的函数 + [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] + public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam); + + public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam); + + /// + /// 墨认的构造函数构造当前类的实例. + /// + public MouseHook() + { + } + + //析构函数. + ~MouseHook() + { + Stop(); + } + + public void Start() + { + //安装鼠标钩子 + if (hMouseHook == 0) + { + //生成一个HookProc的实例. + MouseHookProcedure = new HookProc(MouseHookProc); + + hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProcedure, Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]), 0); + + //如果装置失败停止钩子 + if (hMouseHook == 0) + { + Stop(); + throw new Exception("SetWindowsHookEx failed."); + } + } + } + + public void Stop() + { + bool retMouse = true; + if (hMouseHook != 0) + { + retMouse = UnhookWindowsHookEx(hMouseHook); + hMouseHook = 0; + } + + //如果卸下钩子失败 + if (!(retMouse)) throw new Exception("UnhookWindowsHookEx failed."); + } + + private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam) + { + //如果正常运行并且用户要监听鼠标的消息 + if ((nCode >= 0) && (OnMouseActivity != null)) + { + MouseButtons button = MouseButtons.None; + int clickCount = 0; + + switch (wParam) + { + case WM_LBUTTONDOWN: + button = MouseButtons.Left; + clickCount = 1; + break; + case WM_LBUTTONUP: + button = MouseButtons.Left; + clickCount = 1; + break; + case WM_LBUTTONDBLCLK: + button = MouseButtons.Left; + clickCount = 2; + break; + case WM_RBUTTONDOWN: + button = MouseButtons.Right; + clickCount = 1; + break; + case WM_RBUTTONUP: + button = MouseButtons.Right; + clickCount = 1; + break; + case WM_RBUTTONDBLCLK: + button = MouseButtons.Right; + clickCount = 2; + break; + } + + //从回调函数中得到鼠标的信息 + MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct)); + MouseEventArgs e = new MouseEventArgs(button, clickCount, MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y, 0); + //if(e.X>700)return 1;//如果想要限制鼠标在屏幕中的移动区域可以在此处设置 + OnMouseActivity(this, e); + } + return CallNextHookEx(hMouseHook, nCode, wParam, lParam); + } + } + +} diff --git a/应用/AutoAnswer/Class1.cs b/应用/AutoAnswer/Class1.cs index 72069d8..a68eb39 100644 --- a/应用/AutoAnswer/Class1.cs +++ b/应用/AutoAnswer/Class1.cs @@ -196,7 +196,7 @@ namespace AutoAnswer } #region 呼叫客服 - if (Class1.Config.CellCustomerServiceSwitch == Api.Framework.Enums.SwitchType.开启) + if (Class1.Config.CellCustomerServiceSwitch == Api.Framework.Enums.SwitchType.开启 && !issend) { if (string.IsNullOrEmpty(e.Groupid)) //私聊信息 { diff --git a/类库/Api.Framework/ApiClient.cs b/类库/Api.Framework/ApiClient.cs index 7119c6f..02f0833 100644 --- a/类库/Api.Framework/ApiClient.cs +++ b/类库/Api.Framework/ApiClient.cs @@ -3630,6 +3630,12 @@ namespace Api.Framework //} case DwzType.快站短网址: { + if (CacheTool.GetSingleObj().Exist("KZShortUrl")) + { + type = DwzType.官方短网址; + goto Next; + } + var urlTmp = KuaiZhanShort.GetShort(url); if (urlTmp == url) { diff --git a/类库/Api.Framework/Tools/KuaiZhanShort.cs b/类库/Api.Framework/Tools/KuaiZhanShort.cs index 37219b5..9d45921 100644 --- a/类库/Api.Framework/Tools/KuaiZhanShort.cs +++ b/类库/Api.Framework/Tools/KuaiZhanShort.cs @@ -63,6 +63,7 @@ namespace Api.Framework.Tools } else if ((int)jobj["code"] == 1001) { + CacheTool.GetSingleObj().Set("KZShortUrl", "", (int)(DateTime.Now.AddDays(1).AddMinutes(5) - DateTime.Now).TotalMinutes); EventClient.OnEvent("短连接", "由于快站短连接接口请求的额度超限制,正在切换其他短连接"); } }