Files
better-genshin-impact/BetterGenshinImpact/GameTask/SystemControl.cs
2024-03-22 22:58:02 +08:00

238 lines
6.9 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.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Vanara.PInvoke;
namespace BetterGenshinImpact.GameTask;
public class SystemControl
{
public static nint FindGenshinImpactHandle()
{
return FindHandleByProcessName("YuanShen", "GenshinImpact", "Genshin Impact Cloud Game");
}
public static async Task<nint> StartFromLocalAsync(string path)
{
// 直接exe启动
Process.Start(new ProcessStartInfo(path)
{
UseShellExecute = true,
Arguments = TaskContext.Instance().Config.GenshinStartConfig.GenshinStartArgs,
WorkingDirectory = Path.GetDirectoryName(path)
});
for (var i = 0; i < 5; i++)
{
var handle = FindGenshinImpactHandle();
if (handle != 0)
{
await Task.Delay(2333);
handle = FindGenshinImpactHandle();
await Task.Delay(2577);
return handle;
}
await Task.Delay(5577);
}
return FindGenshinImpactHandle();
}
public static bool IsGenshinImpactActiveByProcess()
{
var name = GetActiveProcessName();
return name is "YuanShen" or "GenshinImpact" or "Genshin Impact Cloud Game";
}
public static bool IsGenshinImpactActive()
{
var hWnd = User32.GetForegroundWindow();
return hWnd == TaskContext.Instance().GameHandle;
}
public static nint GetForegroundWindowHandle()
{
return (nint)User32.GetForegroundWindow();
}
public static nint FindHandleByProcessName(params string[] names)
{
foreach (var name in names)
{
var pros = Process.GetProcessesByName(name);
if (pros.Any())
{
return pros[0].MainWindowHandle;
}
}
return 0;
}
public static nint FindHandleByWindowName()
{
var handle = (nint)User32.FindWindow("UnityWndClass", "原神");
if (handle != 0)
{
return handle;
}
handle = (nint)User32.FindWindow("UnityWndClass", "Genshin Impact");
if (handle != 0)
{
return handle;
}
handle = (nint)User32.FindWindow("Qt5152QWindowIcon", "云·原神");
if (handle != 0)
{
return handle;
}
return 0;
}
public static string? GetActiveProcessName()
{
try
{
var hWnd = User32.GetForegroundWindow();
_ = User32.GetWindowThreadProcessId(hWnd, out var pid);
var p = Process.GetProcessById((int)pid);
return p.ProcessName;
}
catch
{
return null;
}
}
public static Process? GetProcessByHandle(nint hWnd)
{
try
{
_ = User32.GetWindowThreadProcessId(hWnd, out var pid);
var p = Process.GetProcessById((int)pid);
return p;
}
catch (Exception ex)
{
Debug.WriteLine(ex);
return null;
}
}
/// <summary>
/// 获取窗口位置
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
public static RECT GetWindowRect(nint hWnd)
{
// User32.GetWindowRect(hWnd, out var windowRect);
DwmApi.DwmGetWindowAttribute<RECT>(hWnd, DwmApi.DWMWINDOWATTRIBUTE.DWMWA_EXTENDED_FRAME_BOUNDS, out var windowRect);
return windowRect;
}
/// <summary>
/// 游戏本身分辨率获取
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
public static RECT GetGameScreenRect(nint hWnd)
{
User32.GetClientRect(hWnd, out var clientRect);
return clientRect;
}
/// <summary>
/// GetWindowRect or GetGameScreenRect
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
public static RECT GetCaptureRect(nint hWnd)
{
var windowRect = GetWindowRect(hWnd);
var gameScreenRect = GetGameScreenRect(hWnd);
var left = windowRect.Left;
var top = windowRect.Top + windowRect.Height - gameScreenRect.Height;
var right = left + gameScreenRect.Width;
var bottom = top + gameScreenRect.Height;
return new RECT(left, top, right, bottom);
}
public static void ActivateWindow(nint hWnd)
{
User32.ShowWindow(hWnd, ShowWindowCommand.SW_RESTORE);
User32.SetForegroundWindow(hWnd);
}
public static void ActivateWindow()
{
if (!TaskContext.Instance().IsInitialized)
{
throw new Exception("请先启动BetterGI");
}
ActivateWindow(TaskContext.Instance().GameHandle);
}
public static void Focus(nint hWnd)
{
if (User32.IsWindow(hWnd))
{
_ = User32.SendMessage(hWnd, User32.WindowMessage.WM_SYSCOMMAND, User32.SysCommand.SC_RESTORE, 0);
_ = User32.SetForegroundWindow(hWnd);
while (User32.IsIconic(hWnd))
{
continue;
}
_ = User32.BringWindowToTop(hWnd);
}
}
public static bool IsFullScreenMode(IntPtr hWnd)
{
if (hWnd == IntPtr.Zero)
{
return false;
}
var exStyle = User32.GetWindowLong(hWnd, User32.WindowLongFlags.GWL_EXSTYLE);
return (exStyle & (int)User32.WindowStylesEx.WS_EX_TOPMOST) != 0;
}
// private static void StartFromLauncher(string path)
// {
// // 通过launcher启动
// var process = Process.Start(new ProcessStartInfo(path) { UseShellExecute = true });
// Thread.Sleep(1000);
// // 获取launcher窗口句柄
// var hWnd = FindHandleByProcessName("launcher");
// var rect = GetWindowRect(hWnd);
// var dpiScale = Helpers.DpiHelper.ScaleY;
// // 对于launcher启动按钮的位置时固定的在launcher窗口的右下角
// Thread.Sleep(1000);
// Simulation.MouseEvent.Click((int)((float)rect.right * dpiScale) - (rect.Width / 5), (int)((float)rect.bottom * dpiScale) - (rect.Height / 8));
// }
//
// private static void StartCloudYaunShen(string path)
// {
// // 通过launcher启动
// var process = Process.Start(new ProcessStartInfo(path) { UseShellExecute = true });
// Thread.Sleep(10000);
// // 获取launcher窗口句柄
// var hWnd = FindHandleByProcessName("Genshin Impact Cloud Game");
// var rect = GetWindowRect(hWnd);
// var dpiScale = Helpers.DpiHelper.ScaleY;
// // 对于launcher启动按钮的位置时固定的在launcher窗口的右下角
// Simulation.MouseEvent.Click(rect.right - (rect.Width / 6), rect.bottom - (rect.Height / 13 * 3));
// // TODO点完之后有个15s的倒计时好像不处理也没什么问题直接睡个20s吧
// Thread.Sleep(20000);
// }
}