简体   繁体   中英

How to get the URL from the focused Internet Explorer browser window

I have a keyboard hook implementation that changes the output of certain text under given conditions. To determine how to format the output, I need to be able to see which window is in focus, and if Internet Explorer is in focus, I need to be able to determine which URL is open on that specific tab.

I've been working with the code posted by Simon in the following post: Retrieve current URL from C# windows forms application

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);
}

As I have Internet Explorer running (and have webpages open for that matter), I was hoping/expecting to see an output of some sort with URLs, showing the URL(s) open. Instead of getting URLs written to the console, I get nothing. In the case where I tried to use GetProcessesByName , I just get the following output, System.Diagnostics.Process[]

To get the all URL's from Internet Explorer tabs you can do the following:

1. Add a reference to "Microsoft Internet Controls" 在此处输入图片说明

2. Add the following code to get the URL's:

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);
}

This solution is a hacky way of doing the job.

The main idea

  1. Send ALT+D to the browser to select the URL text
  2. Send CTRL+C to copy the URL

A few things to consider

  1. In order to send keys to a window, it needs to be the active window (foreground window).
  2. If the browser window state was changed, it would be good to return it to its original state.
  3. If the clipboard is used, it would be good to return it to its original state.

The steps to get the active tab URL

  1. Find processes named "iexplor" with a main window title.
  2. Remember the original active window and the original browser window state.
  3. Make the browser window the active window.
  4. Remember the original data on the clipboard.
  5. Send ALT+D , CTRL+C
  6. Copy the clipboard.
  7. Restore the original clipboard data.
  8. If the browser window was minimized, minimize it.
  9. Restore the original active window.

Disadvantages

  1. Changing the browser window state is visibly noticeable.
  2. If the browser window was not minimized, making it the active window will bring it to the front. Even if the original active window is restored, it will still be the window behind it.

Code requirements

  1. This code uses Vanara NuGet package for Win32 API
  2. A reference to System.Windows.Forms is required for Clipboard and SendKeys
  3. The Main needs to have [STAThread] attribute in order to use Clipboard

Code

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]);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM