old_flsystem/PCRobot/Utils/WeChatActivateHelper.cs

491 lines
17 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.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using PCRobot;
namespace WechatHelper
{
/// <summary>
/// 微信激活帮助类
/// </summary>
internal class WeChatActivateHelper
{
#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)]
public 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);
#endregion
/// <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
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)
{
Thread.Sleep(4000);
ShowWindow(handle, 2);
}
//休眠
Thread.Sleep(new Random(Guid.NewGuid().GetHashCode()).Next(40000, 60000));
} while (true);
}
catch (Exception e)
{
Console.WriteLine($"ActivateWindow Error{e.Message}\r\nParamslpClassName={lpClassName} lpWindowName={lpWindowName}");
}
}
/// <summary>
/// 关闭窗口
/// </summary>
private static void CloseWindow(string className, string windowName)
{
int index = 1;
//主窗口句柄
var handle = IntPtr.Zero;
var handleList = new List<IntPtr>();
do
{
try
{
Thread.Sleep(5000);
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);
}
/// <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.Now;
/// <summary>
/// 初始化激活器
/// 注:请务必在主线程调用,不要再子线程
/// </summary>
/// <param name="time">多久激活一次</param>
/// <param name="forcedRunHours">强制运行小时</param>
/// <param name="maxCount">总激活次数0表示无限制</param>
/// <exception cref="Exception"></exception>
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;
}
public static void Set_Hosts(string domain, string ip)
{
string path = System.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}");
}
File.WriteAllLines(path, list.ToArray());
}
public static void Remove_Hosts(string hosts_str)
{
string path = System.Environment.GetFolderPath(Environment.SpecialFolder.System) + "\\drivers\\etc\\hosts";
string[] hosts = File.ReadAllLines(path);
List<string> list = hosts.ToList();
//int index = list.FindIndex(x => x.Contains(hosts_str));
//list.RemoveAt(index);
list.RemoveAll(x => x.Contains(hosts_str));
//foreach (string item in list.ToArray())
//{
// if (item.Contains(hosts_str))
// {
// list.Remove(item);
// }
//}
File.WriteAllLines(path, list.ToArray());
}
}
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);
}
}
}