173 lines
5.8 KiB
C#
173 lines
5.8 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|