using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows;
namespace TestProject;
/// <summary>
/// 크롬 브라우저 프로세스 헬퍼
/// </summary>
public class ChromBrowserProcessHelper
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Structure
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 사각형 - RECT
/// <summary>
/// 사각형
/// </summary>
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Public
#region Field
/// <summary>
/// 왼쪽
/// </summary>
public int Left;
/// <summary>
/// 위쪽
/// </summary>
public int Top;
/// <summary>
/// 오른쪽
/// </summary>
public int Right;
/// <summary>
/// 아래쪽
/// </summary>
public int Bottom;
#endregion
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Delegate
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 윈도우 나열하기 대리자 - EnumerateWindowDelegate(windowHandle, longParameter)
/// <summary>
/// 윈도우 나열하기 대리자
/// </summary>
/// <param name="windowHandle">윈도우 핸들</param>
/// <param name="longParameter">LONG 매개 변수</param>
/// <returns>처리 결과</returns>
public delegate bool EnumerateWindowDelegate(IntPtr windowHandle, IntPtr longParameter);
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Import
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region 윈도우 열거하기 - EnumWindows(enumerateWindowDelegate, longParameter)
/// <summary>
/// 윈도우 열거하기
/// </summary>
/// <param name="enumerateWindowDelegate">윈도우 열거하기 대리자</param>
/// <param name="longParameter">LONG 매개 변수</param>
/// <returns>처리 결과</returns>
[DllImport("user32")]
private static extern bool EnumWindows(EnumerateWindowDelegate enumerateWindowDelegate, IntPtr longParameter);
#endregion
#region 윈도우 표시 여부 구하기 - IsWindowVisible(windowHandle)
/// <summary>
/// 윈도우 표시 여부 구하기
/// </summary>
/// <param name="windowHandle">윈도우 핸들</param>
/// <returns>윈도우 표시 여부</returns>
[DllImport("user32")]
private static extern bool IsWindowVisible(IntPtr windowHandle);
#endregion
#region 윈도우 제목 구하기 - GetWindowText(windowHandle, stringBuilder, maximumCount)
/// <summary>
/// 윈도우 제목 구하기
/// </summary>
/// <param name="windowHandle">윈도우 핸들</param>
/// <param name="stringBuilder">문자열 빌더</param>
/// <param name="maximumCount">최대 카운트</param>
/// <returns>처리 결과</returns>
[DllImport("user32", SetLastError = true)]
private static extern int GetWindowText(IntPtr windowHandle, StringBuilder stringBuilder, int maximumCount);
#endregion
#region 윈도우 사각형 구하기 - GetWindowRect(windowHandle, rectangle)
/// <summary>
/// 윈도우 사각형 구하기
/// </summary>
/// <param name="windowHandle">윈도우 핸들</param>
/// <param name="rectangle">사각형</param>
/// <returns>처리 결과</returns>
[DllImport("user32")]
private static extern bool GetWindowRect(IntPtr windowHandle, out RECT rectangle);
#endregion
#region 활성 윈도우 설정하기 - SetForegroundWindow(windowHandle)
/// <summary>
/// 활성 윈도우 설정하기
/// </summary>
/// <param name="windowHandle">윈도우 핸들</param>
/// <returns>처리 결과</returns>
[DllImport("user32")]
private static extern bool SetForegroundWindow(IntPtr windowHandle);
#endregion
#region 윈도우 스레드 프로세스 ID 구하기 - GetWindowThreadProcessId(windowHandle, processID)
/// <summary>
/// 윈도우 스레드 프로세스 ID 구하기
/// </summary>
/// <param name="windowHandle">윈도우 핸들</param>
/// <param name="processID">프로세스 ID</param>
/// <returns>처리 결과</returns>
[DllImport("user32")]
private static extern uint GetWindowThreadProcessId(IntPtr windowHandle, out uint processID);
#endregion
#region 윈도우 최소화 여부 구하기 - IsIconic(windowHandle)
/// <summary>
/// 윈도우 최소화 여부 구하기
/// </summary>
/// <param name="windowHandle">윈도우 핸들</param>
/// <returns>윈도우 최소화 여부</returns>
[DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsIconic(IntPtr windowHandle);
#endregion
#region 윈도우 표시하기 - ShowWindow(windowHandle, showCommand)
/// <summary>
/// 윈도우 표시하기
/// </summary>
/// <param name="windowHandle">윈도우 핸들</param>
/// <param name="showCommand">표시 명령</param>
/// <returns>처리 결과</returns>
[DllImport("user32")]
private static extern bool ShowWindow(IntPtr windowHandle, int showCommand);
#endregion
#region 전경 윈도우 구하기 - GetForegroundWindow()
/// <summary>
/// 전경 윈도우 구하기
/// </summary>
/// <returns>전경 윈도우 핸들</returns>
[DllImport("user32")]
private static extern IntPtr GetForegroundWindow();
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// SW_MAXIMIZE
/// </summary>
private const int SW_MAXIMIZE = 3;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Public
#region 크롬 브라우저 윈도우 정보 리스트 구하기 - GetChromeBrowserWindowInfoList()
/// <summary>
/// 크롬 브라우저 윈도우 정보 리스트 구하기
/// </summary>
/// <returns></returns>
public static List<WindowInformation> GetChromeBrowserWindowInfoList()
{
List<WindowInformation> windowInformationList = new List<WindowInformation>();
EnumWindows
(
delegate(IntPtr windowHandle, IntPtr longParameter)
{
if(IsWindowVisible(windowHandle))
{
uint processID;
GetWindowThreadProcessId(windowHandle, out processID);
try
{
Process process = Process.GetProcessById((int)processID);
if(process.ProcessName.ToLower().Contains("chrome"))
{
StringBuilder stringBuilder = new StringBuilder(256);
GetWindowText(windowHandle, stringBuilder, 256);
GetWindowRect(windowHandle, out RECT rectangle);
int width = rectangle.Right - rectangle.Left;
int height = rectangle.Bottom - rectangle.Top;
windowInformationList.Add
(
new WindowInformation
{
WindowHandle = windowHandle,
Title = stringBuilder.ToString(),
ProcessID = processID,
Width = width,
Height = height
}
);
}
}
catch(ArgumentException)
{
}
}
return true;
},
IntPtr.Zero
);
return windowInformationList;
}
#endregion
#region 메인 크롬 브라우저 윈도우 정보 구하기 - GetMainChromeBrowserWindowInformation(windowInformationList)
/// <summary>
/// 메인 크롬 브라우저 윈도우 정보 구하기
/// </summary>
/// <param name="windowInformationList">윈도우 정보 리스트</param>
/// <returns>윈도우 정보</returns>
public static WindowInformation GetMainChromeBrowserWindowInformation(List<WindowInformation> windowInformationList)
{
if(windowInformationList == null || windowInformationList.Count == 0)
{
return null;
}
WindowInformation mainWindowInformation = null;
int maximumArea = 0;
foreach(WindowInformation windowInformation in windowInformationList)
{
int area = windowInformation.Width * windowInformation.Height;
if(area > maximumArea)
{
maximumArea = area;
mainWindowInformation = windowInformation;
}
}
return mainWindowInformation;
}
#endregion
#region 윈도우 활성화 대기하기 - WaitForWindowActivation(targetWindowHandle, timeout)
/// <summary>
/// 윈도우 활성화 대기하기
/// </summary>
/// <param name="targetWindowHandle">타겟 윈도우 핸들</param>
/// <param name="timeout">타임아웃 (단위 : 초)</param>
public static void WaitForWindowActivation(IntPtr targetWindowHandle, int timeout = 30)
{
var startTime = DateTime.Now;
while((DateTime.Now - startTime).TotalSeconds < timeout)
{
IntPtr foregroundWindow = GetForegroundWindow();
if(foregroundWindow == targetWindowHandle)
{
return;
}
Thread.Sleep(100);
}
throw new TimeoutException("지정 시간 내에 윈도우를 활성화하는데 실패했습니다.");
}
#endregion
#region 활성탭 텍스트 구하기 - GetActiveTabText(windowInformation)
/// <summary>
/// 활성탭 텍스트 구하기
/// </summary>
/// <param name="windowInformation">윈도우 정보</param>
/// <returns>텍스트</returns>
public static string GetActiveTabText(WindowInformation windowInformation)
{
IntPtr windowHandle = windowInformation.WindowHandle;
if(IsIconic(windowHandle))
{
ShowWindow(windowHandle, SW_MAXIMIZE);
}
SetForegroundWindow(windowHandle);
WaitForWindowActivation(windowHandle);
MessageHelper.ClickMouse(windowHandle, 1, 150);
System.Windows.Forms.SendKeys.SendWait("^{a}");
Thread.Sleep(500);
System.Windows.Forms.SendKeys.SendWait("^{c}");
Thread.Sleep(100);
string text = Clipboard.GetText();
Thread.Sleep(100);
MessageHelper.ClickMouse(windowHandle, 0, 200);
return text;
}
#endregion
}