feat: add csharp win helper probe

This commit is contained in:
zhaoyilun
2026-07-05 14:29:29 +08:00
parent d58b9a0274
commit f2dd1c7e57
7 changed files with 816 additions and 0 deletions

View File

@@ -0,0 +1,172 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
namespace ISphereWinHelper
{
internal static class WindowScanner
{
private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll")]
private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32.dll")]
private static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("user32.dll", SetLastError = true)]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("user32.dll")]
private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
public static Dictionary<string, object> Scan(Dictionary<string, object> args)
{
bool includeAllVisible = HelperProtocol.GetBool(args, "include_all_visible", false);
var windows = new List<Dictionary<string, object>>();
EnumWindows(delegate(IntPtr hwnd, IntPtr lParam)
{
if (!IsWindowVisible(hwnd))
{
return true;
}
string title = GetWindowTextValue(hwnd);
string className = GetClassNameValue(hwnd);
uint pidRaw;
GetWindowThreadProcessId(hwnd, out pidRaw);
int pid = unchecked((int)pidRaw);
string processName = GetProcessName(pid);
int score = ScoreWindow(processName, title, className);
if (!includeAllVisible && score <= 0)
{
return true;
}
RECT rect;
GetWindowRect(hwnd, out rect);
windows.Add(new Dictionary<string, object>
{
{ "hwnd", FormatHwnd(hwnd) },
{ "pid", pid },
{ "process_name", processName },
{ "title", title },
{ "class_name", className },
{ "visible", true },
{ "bounds", new Dictionary<string, object>
{
{ "x", rect.Left },
{ "y", rect.Top },
{ "width", Math.Max(0, rect.Right - rect.Left) },
{ "height", Math.Max(0, rect.Bottom - rect.Top) }
}
},
{ "score", score }
});
return true;
}, IntPtr.Zero);
windows.Sort(delegate(Dictionary<string, object> left, Dictionary<string, object> right)
{
return Convert.ToInt32(right["score"]).CompareTo(Convert.ToInt32(left["score"]));
});
return new Dictionary<string, object> { { "windows", windows } };
}
public static bool TryParseHwnd(string text, out IntPtr hwnd)
{
hwnd = IntPtr.Zero;
if (string.IsNullOrWhiteSpace(text))
{
return false;
}
string normalized = text.Trim();
try
{
long value;
if (normalized.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
{
value = Convert.ToInt64(normalized.Substring(2), 16);
}
else
{
value = Convert.ToInt64(normalized, 10);
}
hwnd = new IntPtr(value);
return hwnd != IntPtr.Zero;
}
catch
{
return false;
}
}
public static string FormatHwnd(IntPtr hwnd)
{
return "0x" + hwnd.ToInt64().ToString("X");
}
private static string GetWindowTextValue(IntPtr hwnd)
{
var buffer = new StringBuilder(512);
GetWindowText(hwnd, buffer, buffer.Capacity);
return buffer.ToString();
}
private static string GetClassNameValue(IntPtr hwnd)
{
var buffer = new StringBuilder(256);
GetClassName(hwnd, buffer, buffer.Capacity);
return buffer.ToString();
}
private static string GetProcessName(int pid)
{
try
{
using (Process process = Process.GetProcessById(pid))
{
return process.ProcessName;
}
}
catch
{
return "";
}
}
private static int ScoreWindow(string processName, string title, string className)
{
int score = 0;
string combined = ((processName ?? "") + " " + (title ?? "") + " " + (className ?? "")).ToLowerInvariant();
if (combined.Contains("implatformclient")) score += 60;
if (combined.Contains("isphere")) score += 50;
if (combined.Contains("impp")) score += 30;
if (combined.Contains("importal")) score += 20;
if ((className ?? "").IndexOf("WindowsForms", StringComparison.OrdinalIgnoreCase) >= 0) score += 5;
return score;
}
}
}