Как получить URL-адрес из выделенного окна браузера Internet Explorer

У меня есть реализация ловушки клавиатуры, которая изменяет вывод определенного текста при заданных условиях. Чтобы определить, как форматировать вывод, мне нужно иметь возможность видеть, какое окно находится в фокусе, и если Internet Explorer находится в фокусе, мне нужно иметь возможность определить, какой URL-адрес открыт на этой конкретной вкладке.

Я работал с кодом, опубликованным Саймоном в следующем сообщении: Получить текущий URL-адрес из приложения Windows Forms C#

Process[] localByName = Process.GetProcessesByName("iexplore");


if((Keys)vkCode == Keys.LShiftKey)
{
    return CallNextHookEx(_hookID, nCode, wParam, lParam);
}


foreach (Process process in Process.GetProcessesByName("iexplore"))
{
    string url = GetInternetExplorerUrl(process);
    if (url == null)
        continue;

    Console.WriteLine("IE Url for '" + process.MainWindowTitle + "' is " + url);
}

Поскольку у меня запущен Internet Explorer (и в этом отношении открыты веб-страницы), я надеялся/ожидал увидеть какой-то вывод с URL-адресами, показывающий открытые URL-адреса. Вместо того, чтобы записывать URL-адреса в консоль, я ничего не получаю. В случае, когда я пытался использовать GetProcessesByName, я просто получаю следующий вывод: System.Diagnostics.Process[]


person Josh41    schedule 18.06.2019    source источник
comment
не цитируйте меня по этому поводу, но я, кажется, помню, что чтение URL-адреса из внешней программы было заблокировано намеренно. Это достаточно сложно сделать даже при встраивании элемента управления active-x в форму.   -  person John Lord    schedule 18.06.2019
comment
С какой версией IE? Если я проверю иерархию IE с помощью Inspect в моей версии IE (11), я увижу, что этот код неверен...   -  person Castorix    schedule 18.06.2019
comment
Все URL-адреса, которые необходимо обнаружить, должны быть в настоящее время в IE11.   -  person Josh41    schedule 19.06.2019


Ответы (2)


Чтобы получить все URL-адреса с вкладок Internet Explorer, вы можете сделать следующее:

1. Добавьте ссылку на "Microsoft Internet Controls" введите здесь описание изображения

2. Добавьте следующий код, чтобы получить URL:

SHDocVw.ShellWindows shellWindows = new SHDocVw.ShellWindows();

List<string> urls = shellWindows
    .Cast<SHDocVw.InternetExplorer>()
    .Where(ie => System.IO.Path.GetFileNameWithoutExtension(ie.FullName).ToLower() == "iexplore")
    .Select(ie => ie.LocationURL)
    .ToList();

foreach (string url in urls)
{
    Console.WriteLine(url);
}
person Eliahu Aaron    schedule 18.06.2019
comment
Спасибо! Это отлично работает для извлечения всех URL-адресов, открытых в IE (по крайней мере, в IE11), но мне действительно нужно определить, находится ли один из этих URL-адресов в сфокусированном окне. Моя первоначальная мысль заключалась в том, чтобы попытаться связать эти URL-адреса с идентификатором процесса, но я пока не совсем уверен, как это сделать. - person Josh41; 19.06.2019

Это решение является хакерским способом выполнения работы.

Главная идея

  1. Отправьте ALT+D в браузер, чтобы выбрать текст URL.
  2. Отправьте CTRL+C, чтобы скопировать URL

Несколько вещей, которые следует учитывать

  1. Чтобы отправить ключи окну, оно должно быть активным окном (окно переднего плана).
  2. Если состояние окна браузера было изменено, было бы хорошо вернуть его в исходное состояние.
  3. Если буфер обмена используется, было бы хорошо вернуть его в исходное состояние.

Шаги для получения URL-адреса активной вкладки

  1. Найдите процессы с именем iexplor с заголовком главного окна.
  2. Запомните исходное активное окно и исходное состояние окна браузера.
  3. Сделайте окно браузера активным окном.
  4. Запомните исходные данные в буфере обмена.
  5. Отправить ALT+D, CTRL+C
  6. Скопируйте буфер обмена.
  7. Восстановите исходные данные буфера обмена.
  8. Если окно браузера было свернуто, сверните его.
  9. Восстановите исходное активное окно.

Недостатки

  1. Изменение состояния окна браузера заметно заметно.
  2. Если окно браузера не было свернуто, то, сделав его активным, оно переместится на передний план. Даже если исходное активное окно будет восстановлено, оно все равно будет окном позади него.

Требования кода

  1. Этот код использует пакет Vanara NuGet для Win32 API.
  2. Ссылка на System.Windows.Forms требуется для Clipboard и SendKeys
  3. Main должен иметь атрибут [STAThread], чтобы использовать Clipboard

Код

using System.Windows.Forms;
using System.Diagnostics;
using Vanara.PInvoke;

…

// Get all Internet Explorer processes with a window title 
Process[] ieProcs = Process.GetProcessesByName("iexplore")
    .Where(p => !string.IsNullOrEmpty(p.MainWindowTitle))
    .ToArray();

// Initialize a URL array to hold the active tab URL
string[] ieUrls = new string[ieProcs.Length];

for (int i = 0; i < ieProcs.Length; i++)
{
    Process proc = ieProcs[i];

    // Remember the initial window style of the process window
    User32_Gdi.WindowStyles initialWndStyles = (User32_Gdi.WindowStyles)User32_Gdi.GetWindowLongPtr(proc.MainWindowHandle, User32_Gdi.WindowLongFlags.GWL_STYLE);

    // Remember the initial foreground window
    IntPtr initialFgdWnd = (IntPtr)User32_Gdi.GetForegroundWindow();

    // Show the process window.
    // If it is minimized, it needs to be restored, if not, just show
    if (initialWndStyles.HasFlag(User32_Gdi.WindowStyles.WS_MINIMIZE))
    {
        User32_Gdi.ShowWindow(proc.MainWindowHandle, ShowWindowCommand.SW_RESTORE);
    }
    else
    {
        User32_Gdi.ShowWindow(proc.MainWindowHandle, ShowWindowCommand.SW_SHOW);
    }

    // Set the process window as the foreground window
    User32_Gdi.SetForegroundWindow(proc.MainWindowHandle);

    ieUrls[i] = null;

    // Remember the initial data on the clipboard and clear the clipboard
    IDataObject dataObject = Clipboard.GetDataObject();
    Clipboard.Clear();

    // Start a Stopwatch to timeout if no URL found
    Stopwatch sw = Stopwatch.StartNew();

    // Try to copy the active tab URL
    while (string.IsNullOrEmpty(ieUrls[i]) && sw.ElapsedMilliseconds < 1000)
    {
        // Send ALT+D
        SendKeys.SendWait("%(d)");
        SendKeys.Flush();

        // Send CRTL+C
        SendKeys.SendWait("^(c)");
        SendKeys.Flush();

        ieUrls[i] = Clipboard.GetText();
    }
    // Return the initial clipboard data to the clipboard
    Clipboard.SetDataObject(dataObject);

    // If the process window was initially minimized, minimize it
    if(initialWndStyles.HasFlag(User32_Gdi.WindowStyles.WS_MINIMIZE))
    {
        User32_Gdi.ShowWindow(proc.MainWindowHandle, ShowWindowCommand.SW_MINIMIZE);
    }

    // Return the initial foreground window to the foreground
    User32_Gdi.SetForegroundWindow(initialFgdWnd);
}

// Print the active tab URL's
for (int i = 0; i < ieUrls.Length; i++)
{
    Console.WriteLine(ieUrls[i]);
}
person Eliahu Aaron    schedule 21.06.2019