From bab0e8e817e84d606f397da80ce528b16243d85c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=88=E6=A3=AE=E5=90=B4?= <8402134@qq.com> Date: Sun, 5 Feb 2023 16:53:12 +0800 Subject: [PATCH] =?UTF-8?q?1.=E6=BF=80=E6=B4=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PCRobot/PCRobot.csproj | 1 + PCRobot/PCRobotForm.cs | 12 +- PCRobot/Utils/WeChatActivateHelperV2.cs | 611 ++++++++++++++++++++++++ 3 files changed, 618 insertions(+), 6 deletions(-) create mode 100644 PCRobot/Utils/WeChatActivateHelperV2.cs diff --git a/PCRobot/PCRobot.csproj b/PCRobot/PCRobot.csproj index 48b42fe..9caa499 100644 --- a/PCRobot/PCRobot.csproj +++ b/PCRobot/PCRobot.csproj @@ -214,6 +214,7 @@ + diff --git a/PCRobot/PCRobotForm.cs b/PCRobot/PCRobotForm.cs index 2a6bee7..4a31522 100644 --- a/PCRobot/PCRobotForm.cs +++ b/PCRobot/PCRobotForm.cs @@ -50,12 +50,12 @@ namespace PCRobot LogHelper.GetSingleObj().Info("屏蔽", "屏蔽微信自动更新异常"); } - //try - //{ - // WeChatActivateHelper.Init(TimeSpan.FromMinutes(40)); - //} - //catch (Exception exception) - //{ } + try + { + WeChatActivateHelperV2.Init(2); + } + catch (Exception exception) + { } try { diff --git a/PCRobot/Utils/WeChatActivateHelperV2.cs b/PCRobot/Utils/WeChatActivateHelperV2.cs new file mode 100644 index 0000000..75ff306 --- /dev/null +++ b/PCRobot/Utils/WeChatActivateHelperV2.cs @@ -0,0 +1,611 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using System.Windows.Forms; + +namespace PCRobot.Utils +{ + /// + /// 微信激活帮助类 + /// + public class WeChatActivateHelperV2 + { + #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)] + private 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); + [System.Runtime.InteropServices.DllImport("kernel32.dll")] + private static extern IntPtr GetCurrentThreadId(); + + public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); + public static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2); + public const int SWP_NOSIZE = 0x1; + public const int SWP_NOMOVE = 0x2; + [DllImport("user32.dll")] + public static extern IntPtr GetForegroundWindow(); + + [DllImport("user32.dll")] + private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndlnsertAfter, int x, int y, int cx, int cy, uint flags); + + [System.Runtime.InteropServices.DllImport("user32.dll")] + public static extern bool BringWindowToTop(IntPtr hWnd); + #endregion + + #region 激活相关代码 + /// + /// 置顶窗口 + /// + /// + /// + private static bool SetForegroundWindowCustom(IntPtr hwnd) + { + IntPtr currentWindow = GetForegroundWindow(); + if (currentWindow == hwnd) + { + return true; + } + + SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + + return SetForegroundWindow(hwnd); + } + + /// + /// 激活窗口 + /// + 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(3000); + } + + //var thisHandel = Process.GetCurrentProcess().MainWindowHandle; + //获取自己的线程ID + + //如果这里报错,请添加引用PresentationFramework + var cur = _mSynchronizationContext; + + if (cur == null) + { + Console.WriteLine("当前线程信息获取失败"); + continue; + } + + var handle1 = handle; + //用主线程的上下文 + cur.Send((e) => + { + try + { + + //var thisThreadId = GetCurrentThreadId();// AppDomain.GetCurrentThreadId(); + var thisThreadId = GetCurrentThreadId(); + var targetThreadId = GetWindowThreadProcessId(handle1, IntPtr.Zero); + //附加线程 + var attachThreadStart = AttachThreadInput(targetThreadId, thisThreadId, true); + + //置顶 + var bringWindowToTop = BringWindowToTop(handle1); + + //置焦点(输入框可获得光标) + SetFocus(handle1); + + //置前台 + var setForegroundWindowResult = SetForegroundWindowCustom(handle1); + + //激活 + var setActiveWindow = SetActiveWindow(handle1); + + //分离线程 + var attachThreadEnd = AttachThreadInput(targetThreadId, thisThreadId, false); + + //log.Info($"完成微信激活!attachThreadStart={attachThreadStart} - bringWindowToTop={bringWindowToTop} - setForegroundWindowResult={setForegroundWindowResult} - setActiveWindow={setActiveWindow} - attachThreadEnd={attachThreadEnd}"); + } + catch (Exception exception) + { + //log.Error($"激活微信失败2:{exception.Message}"); + } + + }, null); + + //如果微信最小化了,重新让他最小化 + + if (isIconic) + { + Thread.Sleep(4000); + ShowWindow(handle, 2); + } + + //休眠 + Thread.Sleep(new Random(Guid.NewGuid().GetHashCode()).Next(40000, 60000)); + + } while (true); + } + catch (Exception e) + { + //log.Error($"激活微信失败1:{e.Message}"); + } + } + + /// + /// 屏蔽微信的更新功能 + /// + private static void ShieldingWeChatUpdateFunction() + { + SetHost("dldir1v6.qq.com", "127.0.0.1"); + SetHost("dldir1.qq.com", "127.0.0.1"); + } + + /// + /// 激活微信 + /// + 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.MinValue; + + /// + /// 初始化激活器 + /// 注:请务必在主线程调用,不要再子线程 + /// + /// 强制运行小时 + /// 总激活次数(0表示无限制) + /// + public static bool Init(int forcedRunHours = 2, int maxCount = 0) + { + //log.Info("初始化"); + 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 isNext = false; + //超过2小时没有激活过,强制激活一次 + if ((curTime - _lastActiveTime).TotalHours > forcedRunHours) + { + isNext = true; + } + //超过了一定时间,没有操作鼠标 + else if (_mouse != null) + { + var time = TimeSpan.FromMinutes(30); + var interval = curTime - _mouseHeartbeatTime; + if (interval > time) + { + _mouseHeartbeatTime = DateTime.Now; + isNext = true; + } + } + + if (!isNext) + { + continue; + } + + //log.Info("开始激活"); + index++; + _lastActiveTime = DateTime.Now; + ActivateWeChat(); + //log.Info("激活完成"); + if (maxCount != 0 && index >= maxCount) + { + break; + } + } + catch (Exception e) + { + Console.WriteLine($"激活窗口发生异常:{e.Message}"); + } + finally + { + Thread.Sleep(TimeSpan.FromMinutes(1)); + } + } + }) + { + IsBackground = true + }; + _thread.Start(); + + //屏蔽微信的更新功能 + ShieldingWeChatUpdateFunction(); + + //开启自动关闭微信更新进程 + StartCheckUpdateThread(); + + return true; + } + + + + private static bool _isStartCheckUpdateThread = false; + /// + /// 定时检测,关闭微信自动更新 + /// + private static void StartCheckUpdateThread() + { + if (_isStartCheckUpdateThread) + { + return; + } + + _isStartCheckUpdateThread = true; + + var th = new Thread(() => + { + while (true) + { + try + { + var process = Process.GetProcessesByName("WeChatUpdate"); + foreach (var pro in process) + { + pro.Kill(); + Thread.Sleep(5); + } + } + catch (Exception) + { + // ignored + } + Thread.Sleep(1000 * 5); + } + }) + { + IsBackground = true + }; + th.Start(); + } + + + + private static DateTime _mouseHeartbeatTime = DateTime.Now; + private static void _mouse_OnMouseActivity(object sender, MouseEventArgs e) + { + _mouseHeartbeatTime = DateTime.Now; + } + + /// + /// 设置HOST文件 + /// + /// 域名 + /// IP地址 + /// + private static bool SetHost(string domain, string ip) + { + try + { + string path = Environment.GetFolderPath(Environment.SpecialFolder.System) + "\\drivers\\etc\\hosts"; + if (File.GetAttributes(path) == (FileAttributes.ReadOnly | FileAttributes.Archive)) + { + File.SetAttributes(path, FileAttributes.Archive); + } + + + string[] hosts = File.ReadAllLines(path); + List list = hosts.ToList(); + string temp = hosts.ToList().FirstOrDefault(x => x.Contains(domain)); + if (string.IsNullOrEmpty(temp)) + { + list.Add($"{ip} {domain}"); + } + + if (list.Count <= 0) + { + return true; + } + + File.WriteAllLines(path, list.ToArray()); + return true; + } + catch (Exception) + { + return false; + } + } + + + #endregion + + #region 公共代码 + /// + /// 获取文件MD5(大写) + /// + /// + /// + /// + private static string GetMD5HashFromFile(string fileName) + { + try + { + FileStream file = new FileStream(fileName, FileMode.Open); + System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); + byte[] retVal = md5.ComputeHash(file); + file.Close(); + + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < retVal.Length; i++) + { + sb.Append(retVal[i].ToString("X2")); + } + return sb.ToString(); + } + catch (Exception) + { + } + return string.Empty; + } + + #endregion + + [DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize")] + private static extern int SetProcessWorkingSetSize(IntPtr process, int minSize, int maxSize); + + } + + 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); + } + } +} \ No newline at end of file