old_flsystem/PCRobot/Utils/WeChatActivateHelperV2.cs

611 lines
21 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// 微信激活帮助类
/// </summary>
public class WeChatActivateHelperV2
{
#region WIN32 API函数
[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
/// <summary>
/// 聚焦
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
[DllImport("user32.dll", EntryPoint = "SetFocus")]
private static extern IntPtr SetFocus(IntPtr hWnd);
/// <summary>
/// 判断是否最小化
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
[DllImport("user32.dll")]
private static extern bool IsIconic(IntPtr hWnd);
/// <summary>
/// 判断是否可见
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
[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);
/// <summary>
/// 附加线程输入
/// </summary>
/// <param name="idAttach">当前线程</param>
/// <param name="idAttachTo">目标线程</param>
/// <param name="fAttach"></param>
/// <returns></returns>
[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
/// <summary>
/// 置顶窗口
/// </summary>
/// <param name="hwnd"></param>
/// <returns></returns>
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);
}
/// <summary>
/// 激活窗口
/// </summary>
private static void ActivateWindow(string lpClassName, string lpWindowName)
{
try
{
//主窗口句柄
var handle = IntPtr.Zero;
var handleList = new List<IntPtr>();
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}");
}
}
/// <summary>
/// 屏蔽微信的更新功能
/// </summary>
private static void ShieldingWeChatUpdateFunction()
{
SetHost("dldir1v6.qq.com", "127.0.0.1");
SetHost("dldir1.qq.com", "127.0.0.1");
}
/// <summary>
/// 激活微信
/// </summary>
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;
/// <summary>
/// 初始化激活器
/// 注:请务必在主线程调用,不要再子线程
/// </summary>
/// <param name="forcedRunHours">强制运行小时</param>
/// <param name="maxCount">总激活次数0表示无限制</param>
/// <exception cref="Exception"></exception>
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;
/// <summary>
/// 定时检测,关闭微信自动更新
/// </summary>
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;
}
/// <summary>
/// 设置HOST文件
/// </summary>
/// <param name="domain">域名</param>
/// <param name="ip">IP地址</param>
/// <returns></returns>
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<string> 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
/// <summary>
/// 获取文件MD5(大写)
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
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);
/// <summary>
/// 墨认的构造函数构造当前类的实例.
/// </summary>
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);
}
}
}