从浏览器中获取URL到C#应用程序 [英] Get URL from browser to C# application

查看:297
本文介绍了从浏览器中获取URL到C#应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何可以从Chrome浏览器和Opera使用C#.NET Windows窗体应用程序的运行实例的网址是什么? 谢谢!

How can I get the url from a running instance of Chrome or Opera using C# .NET windows form app? Thanks!

推荐答案

基本上我有太多的code分离出的最小的这个例子,但我提供我自己的算法,下面为你倒过来。

Part 2:

Basically I have too much code to separate out the minimum for this example, but I have provided my own algorithm below for you to pour over.

这其中还跟踪标签的浏览器,因为当他们再次出现(即只),所以你需要剥离出位,你不想要的。我似乎记得我解决了这个IE8的,但不知道这要在这code去了,所以如果它需要一点点的调整并不感到惊讶:)

This one also keeps track of tabs in browsers, as and when they reappear (IE only), so you will need to strip out the bits you don't want. I seem to remember I fixed this for IE8, but not sure if that fix went in this code, so don't be surprised if it needs a little tweak :)

    // Iterate all browsers and record the details
    IntPtr hWnd = IntPtr.Zero;
    NativeWIN32.EnumChildWindows(hWnd, new NativeWIN32.Win32Callback(BrowserEnumCallback), hWnd);

    /// <summary>
    /// Called back for each IE browser.
    /// </summary>
    /// <param name="hWnd"></param>
    /// <param name="lParam"></param>
    /// <returns></returns>
    static bool BrowserEnumCallback(IntPtr hWnd, IntPtr lParam)
    {
        // Is this app IE?
        if (NativeWIN32.GetClassName(hWnd) == "IEFrame")
        {
            // If this is a new browser, add it
            if (!BrowserWindows.ContainsKey(hWnd))
            {
                // Record the Browser
                BrowserWindow browser = new BrowserWindow()
                {
                    hWnd = hWnd
                };
                // Store the browser in the temp list and temp member
                TempCurrentBrowser = browser;
                BrowserWindows.Add(hWnd, browser);
            }
            else
            {
                // Store the browser in the temp list and temp member
                TempCurrentBrowser = BrowserWindows[hWnd];
            }
            TempCurrentBrowser.WindowText = NativeWIN32.GetWindowText(hWnd);
            TempCurrentBrowser.Found = true;

            // Now that we know it is a browser, look for tabbed windows and address bar
            NativeWIN32.EnumChildWindows(hWnd, new NativeWIN32.Win32Callback(BrowserEnumChildrenCallback), hWnd);
        }
        return true;
    }

    /// <summary>
    /// Called back for each child window in the browser
    /// </summary>
    /// <param name="hWnd"></param>
    /// <param name="lParam"></param>
    /// <returns></returns>
    static bool BrowserEnumChildrenCallback(IntPtr hWnd, IntPtr lParam)
    {
        string classname = NativeWIN32.GetClassName(hWnd);
        switch (classname)
        {
            // This is the main address bar
            case "Edit":
                {
                    string url = NativeWIN32.GetWindowText(hWnd);
                    if (url.StartsWith(@"http://") || url.StartsWith(@"https://") || url.StartsWith("about:"))
                    {
                        TempCurrentBrowser.Url = url;
                        return true;
                    }
                }
                break;

            case "ComboBoxEx32":
                {
                    string url = NativeWIN32.GetWindowText(hWnd);
                    if (url.StartsWith(@"http://") || url.StartsWith(@"https://") || url.StartsWith("about:"))
                    {
                        TempCurrentBrowser.Url = url;
                        return true;
                    }
                }
                break;

            // Record any sub pages still active, by title to avoid revisiting popup
            // If this name matches the name of the browser, it is the current window
            // If so, record the browser url for reference in that tab window
            case "TabWindowClass":
                {
                    string title = NativeWIN32.GetWindowText(hWnd);
                    BrowserTabWindow tabWindow;
                    if (!TempCurrentBrowser.TabWindows.ContainsKey(hWnd))
                    {
                        // Create a new tabbed window for the current browser
                        tabWindow = new BrowserTabWindow()
                        {
                            hWnd = hWnd
                        };
                        TempCurrentBrowser.TabWindows.Add(hWnd, tabWindow);
                    }
                    else
                    {
                        tabWindow = TempCurrentBrowser.TabWindows[hWnd];
                    }
                    tabWindow.WindowText = title;
                    tabWindow.Found = true;
                }
                break;
        }
        return true;
    }

第1部分

如果微软间谍++可以看到地址控制,那么是的,它是可能的。

Part 1:

If Microsoft Spy++ can see the address control, then yes it is possible.

我没有安装歌剧,但间谍+ + Chrome的控制层次看起来是这样的:

I don't have Opera installed, but the Chrome control hierarchy in Spy++ looks like this:

我也做过类似的事情与Internet Explorer:

I have done similar things with Internet Explorer:

  • 要记录日记的访问的站点 - 然后弹出要求用户自己在做什么
  • 要显示一个小窗口弹出当某些知名网站进行了走访

火狐是的问题儿童的,因为它的内部并没有呈现在地址栏通过窗口的控制,但我看你已经找到了解决这一之一。

Firefox was the problem child as it renders the address bar internally and not via a windows control but I see you have already found the solution to that one.

在C#中,你需要做非托管调用Windows API的方法。正如你可以从C#API $ C $独自C见(下图),它可以得到一点点参与:

In C# you need to make unmanaged calls to Windows API methods. As you can see from the C# API code alone (below) it can get a little involved:

const int WM_GETTEXT = 0xD;

// used for an output LPCTSTR parameter on a method call
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct STRINGBUFFER
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string szText;
}

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindowEx(IntPtr parent /*HWND*/, 
                                         IntPtr next /*HWND*/, 
                                         string sClassName,  
                                         IntPtr sWindowTitle);

/// <summary>
/// 
/// </summary>
/// <param name="hWnd">handle to destination window</param>
/// <param name="msg">message</param>
/// <param name="wParam">first message parameter</param>
/// <param name="lParam"second message parameter></param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SendMessage(IntPtr hWnd,
    int msg, int wParam, out STRINGBUFFER ClassName);


[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int GetWindowText(IntPtr hWnd, out STRINGBUFFER ClassName, int nMaxCount);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int GetClassName(IntPtr hWnd, out STRINGBUFFER ClassName, int nMaxCount);

//[DllImport("user32.dll")]
//[return: MarshalAs(UnmanagedType.Bool)]
//static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);

public delegate bool Win32Callback(IntPtr hwnd, IntPtr lParam);

[DllImport("user32.Dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr parentHandle, Win32Callback callback, IntPtr lParam);

/// <summary>
/// Helper to get window classname
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
static public string GetClassName(IntPtr hWnd)
{
    NativeWIN32.STRINGBUFFER sLimitedLengthWindowTitle;
    NativeWIN32.GetClassName(hWnd, out sLimitedLengthWindowTitle, 256);
    return sLimitedLengthWindowTitle.szText;
}

/// <summary>
/// Helper to get window text
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
static public string GetWindowText(IntPtr hWnd)
{
    NativeWIN32.STRINGBUFFER sLimitedLengthWindowTitle;
    SendMessage(hWnd, WM_GETTEXT, 256, out sLimitedLengthWindowTitle);
    //NativeWIN32.GetWindowText(hWnd, out sLimitedLengthWindowTitle, 256);
    return sLimitedLengthWindowTitle.szText;
}

涉及的基本算法搜索从桌面上的所有窗口上,直到它找到的浏览器的窗口(根据具体的类或窗口属性)。然后它搜索基于浏览器的类型特定的子元素。当你终于到达地址控制,你可以提取控制地址。希望我的辅助类code会加速你的发展。

The algorithm involved basically searches all windows from the Desktop on down until it finds Browser windows (based on specific class or window attributes). It then searches for specific child elements based on the type of browser. When you finally get to the address control you can extract the address from the control. Hopefully my helper class code will speed your development.

NativeWIN32 引用仅仅包含有用的常量和方法等的Win32功能的包装类。我已经在这里添加了完整的:

The NativeWIN32 references are simply to a wrapper class containing useful constants and methods for other Win32 features. I have added it here in full:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace YourProject
{
    /// <summary>
    /// Wrapper for native win32 calls
    /// </summary>
    public class NativeWIN32
    {
        const int WM_GETTEXT = 0xD;

        // used for an output LPCTSTR parameter on a method call
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct STRINGBUFFER
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
            public string szText;
        }

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr FindWindowEx(IntPtr parent /*HWND*/, 
                                                 IntPtr next /*HWND*/, 
                                                 string sClassName,  
                                                 IntPtr sWindowTitle);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="hWnd">handle to destination window</param>
        /// <param name="msg">message</param>
        /// <param name="wParam">first message parameter</param>
        /// <param name="lParam"second message parameter></param>
        /// <returns></returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int SendMessage(IntPtr hWnd,
            int msg, int wParam, out STRINGBUFFER ClassName);


        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int GetWindowText(IntPtr hWnd, out STRINGBUFFER ClassName, int nMaxCount);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int GetClassName(IntPtr hWnd, out STRINGBUFFER ClassName, int nMaxCount);

        //[DllImport("user32.dll")]
        //[return: MarshalAs(UnmanagedType.Bool)]
        //static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);

        public delegate bool Win32Callback(IntPtr hwnd, IntPtr lParam);

        [DllImport("user32.Dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool EnumChildWindows(IntPtr parentHandle, Win32Callback callback, IntPtr lParam);

        /// <summary>
        /// Helper to get window classname
        /// </summary>
        /// <param name="hWnd"></param>
        /// <returns></returns>
        static public string GetClassName(IntPtr hWnd)
        {
            NativeWIN32.STRINGBUFFER sLimitedLengthWindowTitle;
            NativeWIN32.GetClassName(hWnd, out sLimitedLengthWindowTitle, 256);
            return sLimitedLengthWindowTitle.szText;
        }

        /// <summary>
        /// Helper to get window text
        /// </summary>
        /// <param name="hWnd"></param>
        /// <returns></returns>
        static public string GetWindowText(IntPtr hWnd)
        {
            NativeWIN32.STRINGBUFFER sLimitedLengthWindowTitle;
            SendMessage(hWnd, WM_GETTEXT, 256, out sLimitedLengthWindowTitle);
            //NativeWIN32.GetWindowText(hWnd, out sLimitedLengthWindowTitle, 256);
            return sLimitedLengthWindowTitle.szText;
        }
    }
}

这篇关于从浏览器中获取URL到C#应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆