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