簡體   English   中英

從C#windows窗體應用程序中檢索當前URL

[英]Retrieve current URL from C# windows forms application

我一直在使用Visual C#設計程序,並且遇到了使我的程序與Web瀏覽器交互的問題。 基本上我需要的是從Web瀏覽器(Internet Explorer,Firefox,Chrome等)中檢索URL地址。

我認為這不是一項任務太難,但經過數天和數天的研究和測試,似乎幾乎不可能! 到目前為止,我遇到過這個......

獲取Firefox URL?

其中包含以下代碼:

using NDde.Client;
Class Test
{
    public static string GetFirefoxURL()
    {
        DdeClient dde = new DdeClient("Firefox", "WWW_GetWindowInfo");
        dde.Connect();
        string url = dde.Request("URL", int.MaxValue);
        dde.Disconnect();
        return url;
    }
}

這對於Firefox來說是完美的,但由於某種原因,我不能讓它與其他任何東西一起工作。 我已經將代碼“Firefox”的部分更改為“Iexplore”,就像我在互聯網上找到的一樣,並嘗試其他形式的表達Internet Explorer,我收到以下錯誤:

“客戶端無法連接到”IExplorer | WWW_GetWindowInfo“,請確保服務器應用程序正在運行,並且它支持指定的服務名稱和主題名稱對”

任何關於這個問題的幫助都會受到高度贊賞,因為它已成為一項非常重要的任務。

這是基於Microsoft UI Automation的代碼:

public static string GetChromeUrl(Process process)
{
    if (process == null)
        throw new ArgumentNullException("process");

    if (process.MainWindowHandle == IntPtr.Zero)
        return null;

    AutomationElement element = AutomationElement.FromHandle(process.MainWindowHandle);
    if (element == null)
        return null;

    AutomationElement edit = element.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit));
    return ((ValuePattern)edit.GetCurrentPattern(ValuePattern.Pattern)).Current.Value as string;
}

public static string GetInternetExplorerUrl(Process process)
{
    if (process == null)
        throw new ArgumentNullException("process");

    if (process.MainWindowHandle == IntPtr.Zero)
        return null;

    AutomationElement element = AutomationElement.FromHandle(process.MainWindowHandle);
    if (element == null)
        return null;

    AutomationElement rebar = element.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "ReBarWindow32"));
    if (rebar == null)
        return null;

    AutomationElement edit = rebar.FindFirst(TreeScope.Subtree, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit));

    return ((ValuePattern)edit.GetCurrentPattern(ValuePattern.Pattern)).Current.Value as string;
}

public static string GetFirefoxUrl(Process process)
{
    if (process == null)
        throw new ArgumentNullException("process");

    if (process.MainWindowHandle == IntPtr.Zero)
        return null;

    AutomationElement element = AutomationElement.FromHandle(process.MainWindowHandle);
    if (element == null)
        return null;

    AutomationElement doc = element.FindFirst(TreeScope.Subtree, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Document));
    if (doc == null)
        return null;

    return ((ValuePattern)doc.GetCurrentPattern(ValuePattern.Pattern)).Current.Value as string;
}

您可以使用UI Spy工具來了解所有3個瀏覽器的可視層次結構。 您可能需要調整一些事項以確保它在您的特定情況下真正起作用,但您應該對這些樣本有所了解。

並且轉儲當前在系統中運行的所有3種類型的進程(IE,FF,CH)的所有URL的示例:

static void Main(string[] args)
{
    foreach (Process process in Process.GetProcessesByName("firefox"))
    {
        string url = GetFirefoxUrl(process);
        if (url == null)
            continue;

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

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

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

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

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

在IE的oDde.Request(“URL”,int.MaxValue)中使用參數“1”而不是“URL”。

    public static void ProcessIEURLs()
    {

        string sURL;
        try
        {
            DdeClient oDde = new DdeClient("IExplore", "WWW_GetWindowInfo");

            try
            {
                oDde.Connect();

                sURL = oDde.Request("1", int.MaxValue);

                oDde.Disconnect();

                bool bVisited = false;
                if ( oVisitedURLList != null && oVisitedURLList.Count > 0 )
                {
                    bVisited = FindURL(sURL, oVisitedURLList);
                }

                if ( !bVisited )
                {
                    oVisitedURLList.Add(sURL);
                }
            }
            catch ( Exception ex )
            {
                throw ex;
            }

        }
        catch ( Exception ex )
        {
            throw ex;
        }
    }

Mourier,感謝您的解決方案Microsoft UI Automation 即使如此,它對Firefox 41.0也沒有用,我用小工具“Automation Spy ”分析了Firefox窗口結構。 然后我稍微改變了搜索條件,它完美地工作了!

 public static string GetFirefoxUrl(Process process)
        {
            if (process == null)
                throw new ArgumentNullException("process");

            if (process.MainWindowHandle == IntPtr.Zero)
                return null;

            AutomationElement element = AutomationElement.FromHandle(process.MainWindowHandle);
            if (element == null)
                return null;


            element = element.FindFirst(TreeScope.Subtree, 
                  new AndCondition(
                      new PropertyCondition(AutomationElement.NameProperty, "search or enter address", PropertyConditionFlags.IgnoreCase),
                      new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit)));


            if (element == null)
                return null;

            return ((ValuePattern)element.GetCurrentPattern(ValuePattern.Pattern)).Current.Value as string;
        }

以下是Chromium 48的解決方案:

 public static string GetChromeUrl(Process process)
    {
        if (process == null)
            throw new ArgumentNullException("process");

        if (process.MainWindowHandle == IntPtr.Zero)
            return null;

        AutomationElement element = AutomationElement.FromHandle(process.MainWindowHandle);
        if (element == null)
            return null;

        AutomationElement edit = element.FindFirst(TreeScope.Subtree,
             new AndCondition(
                  new PropertyCondition(AutomationElement.NameProperty, "address and search bar", PropertyConditionFlags.IgnoreCase),
                  new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit)));

        return ((ValuePattern)edit.GetCurrentPattern(ValuePattern.Pattern)).Current.Value as string;
    }

Automation Spy顯示Firefox窗口控件結構。 名為“搜索或輸入地址”的“編輯”類型控件包含以下網址: 自動化間諜

注意:在.NET項目中,您需要2個引用:

  • UIAutomationClient.dll
  • UIAutomationTypes.dll

這是我到目前為止(雖然Chrome我沒有找到任何有用的文章,除了使用FindWindowEx(我個人並不特別喜歡這種方法)。

public class BrowserLocation
{
    /// <summary>
    /// Structure to hold the details regarding a browed location
    /// </summary>
    public struct URLDetails
    {
        /// <summary>
        /// URL (location)
        /// </summary>
        public String URL;

        /// <summary>
        /// Document title
        /// </summary>
        public String Title;
    }

    #region Internet Explorer

    // requires the following DLL added as a reference:
    // C:\Windows\System32\shdocvw.dll

    /// <summary>
    /// Retrieve the current open URLs in Internet Explorer
    /// </summary>
    /// <returns></returns>
    public static URLDetails[] InternetExplorer()
    {
        System.Collections.Generic.List<URLDetails> URLs = new System.Collections.Generic.List<URLDetails>();
        var shellWindows = new SHDocVw.ShellWindows();
        foreach (SHDocVw.InternetExplorer ie in shellWindows)
            URLs.Add(new URLDetails() { URL = ie.LocationURL, Title = ie.LocationName });
        return URLs.ToArray();
    }

    #endregion

    #region Firefox

    // This requires NDde
    // http://ndde.codeplex.com/

    public static URLDetails[] Firefox()
    {
        NDde.Client.DdeClient dde = new NDde.Client.DdeClient("Firefox", "WWW_GetWindowInfo");
        try
        {
            dde.Connect();
            String url = dde.Request("URL", Int32.MaxValue);
            dde.Disconnect();

            Int32 stop = url.IndexOf('"', 1);
            return new URLDetails[]{
                new URLDetails()
                {
                    URL = url.Substring(1, stop - 1),
                    Title = url.Substring(stop + 3, url.Length - stop - 8)
                }
            };
        }
        catch (Exception)
        {
            return null;
        }
    }

    #endregion
}

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Internet Explorer: ");
        (new List<BrowserLocation.URLDetails>(BrowserLocation.InternetExplorer())).ForEach(u =>
        {
            Console.WriteLine("[{0}]\r\n{1}\r\n", u.Title, u.URL);
        });
        Console.WriteLine();

        Console.WriteLine("Firefox:");
        (new List<BrowserLocation.URLDetails>(BrowserLocation.Firefox())).ForEach(u =>
        {
            Console.WriteLine("[{0}]\r\n{1}\r\n", u.Title, u.URL);
        });
        Console.WriteLine();
    }
}

選擇是使用selenium webdriver。 最佳和功率完整的api與完整的首映

IE中支持WWW_GetWindowInfo,並且 16位以來版本已經恢復到3.02版本 適用於Firefox和Opera

我相信Chrome實際上是奇怪的。

我不知道事情是如何超越這四個。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM