2011-10-18 10 views
21

Piszę aplikację na pasku systemowym, która musi sprawdzić, czy jest otwarta wewnętrzna aplikacja internetowa.Jak uzyskać adresy URL otwartych stron z przeglądarki Chrome i Firefox?

mogę sprawdzić IE przy użyciu następujących:

SHDocVw.ShellWindows shellWindows = new SHDocVw.ShellWindows(); 
     string filename; 
     bool sdOpen = false; 
     foreach (SHDocVw.InternetExplorer ie in shellWindows) 
     { 
      filename = Path.GetFileNameWithoutExtension(ie.FullName).ToLower(); 
      if (filename.Equals("iexplore")) 
      { 
       string[] urlParts = (ie.LocationURL.ToString()).Split('/'); 
       string website = urlParts[2]; 
       if (website == "myApp:8080") { sdOpen = true; }; 
      } 
     } 

     if (sdOpen) { Console.WriteLine("App is open"); } else { Console.WriteLine("App is not open"); }; 

     Console.ReadKey(true); 

Jednak niektórzy z użytkowników korzystających z systemu wolą Chrome lub Firefox.

Jak mogę zrobić to samo, co powyżej (tzn. Pobrać adresy URL wszystkich otwartych kart w przeglądarce) w przeglądarce Chrome i Firefox? (Nie będę zajmował się innymi przeglądarkami, ponieważ są to jedyne używane w naszej organizacji.)

+0

Interesujące pytanie. Znalazłem wątek o [robiąc to z AutoHotkey] (http://www.autohotkey.com/forum/topic51981.html) z Firefoksem (obecna karta), dyskusja może ci w tym pomóc. Możesz utworzyć dodatek Firefox, który będzie iterować po wszystkich kartach, i podobnie w Chrome.[This] (http://www.autohotkey.com/forum/topic46974.html) również może się przydać. –

+0

Więcej linków: [MozRepl @ AMO] (https://addons.mozilla.org/pl/firefox/addon/mozrepl/), [film YouTube] (http://www.youtube.com/watch?v=5RSnHN6S52c). Aby wyświetlić listę wszystkich adresów URL otwartych kart w Firefoksie, zobacz [to rozszerzenie] (https://addons.mozilla.org/en-US/firefox/addon/list-open-urls/). Rozszerzenia Firefox to w zasadzie pliki ZIP zawierające kod JavaScript i XUL, dzięki czemu możesz z łatwością go dostosować. –

+1

A może zamiast tego sprawdzać ruch internetowy użytkowników? Możesz ustawić na przykład [proxy] (http://stackoverflow.com/questions/226784/how-to-create-a-simple-proxy-in-c). – Dmitriy

Odpowiedz

22

Jest to specyficzne dla każdej przeglądarki. To dla tych największych:

  • Internet Explorer - Można używać SHDocVw (jak ty)
  • Firefox - można uzyskać adres URL za pomocą DDE (źródło poniżej)
  • Chrome - można uzyskać adres URL podczas wyliczając wszystkie okna potomne aż dojdziesz do sterowania z klasą „Chrome_OmniboxView”, a następnie uzyskać tekst używając GetWindowText
  • Opera - Można używać samo jak Firefox, ale z „opera”
  • Safari - Nie jest znana metoda ponieważ używa niestandardowych wyciągnąć kontroli

EDIT: Od 2014 roku, Chrome uległa zmianie i musisz uzyskać adres URL z dostępnością.

kod aby otrzymać adres URL z Firefox/Opera za pomocą DDE (który używany NDDE - tylko dobre opakowanie DDE dla .NET):

// 
// usage: GetBrowserURL("opera") or GetBrowserURL("firefox") 
// 

private string GetBrowserURL(string browser) { 
    try { 
     DdeClient dde = new DdeClient(browser, "WWW_GetWindowInfo"); 
     dde.Connect(); 
     string url = dde.Request("URL", int.MaxValue); 
     string[] text = url.Split(new string[] { "\",\"" }, StringSplitOptions.RemoveEmptyEntries); 
     dde.Disconnect(); 
     return text[0].Substring(1); 
    } catch { 
     return null; 
    } 
} 
+1

Dla przeglądarki Chrome to prawdopodobnie zmieniło się w późniejszej wersji ? Wszystkie okna podrzędne słowa "Chrome_WidgitWin_1" mają typ "Statyczny" i nie mają zestawu tytułów. –

+0

Nawet z FireFox, nawet bez string.Split, dostarczony kod DDE zwraca tylko aktualnie aktywną kartę. Nie wylicza wszystkich kart. Nie wspominając o tym, że string.split jest błędny (nie zwróci poprawnego adresu URL, jeśli twój adres URL ma na przykład podwójny cudzysłów, ponieważ staje się escaped dla transportu DDE) ... – BrainSlugs83

+0

Dla Opery nie działa tak jak dla przeglądarki Firefox , Dodałem tutaj, jak to zrobić: http://stackoverflow.com/questions/21968177/get-url-from-opera-browser – Lucian

2

Może ten kod może pomóc coś; Dzięki BLEZ za udostępnienie tego kodu. Używam tego kodu do przechwytywania unikalnych adresów z firefox i dodawania ich do listbox. Ale myślę, że to nie jest prawda dla Chrome?

(należy dodać NDde.dll do projektu, aby to zrobić przejdź do Solution Explorer kliknij prawym przyciskiem myszy na References-> Add Reference-> Browse-> okaże się, że DLL (http://ndde.codeplex.com/ z folderu binarnym.))

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using NDde.Client; 

namespace WindowsFormsApplication9 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      timer1.Enabled = true; 
     } 

     private string GetBrowserURL(string browser) 
     { 
      try 
      { 
       DdeClient dde = new DdeClient(browser, "WWW_GetWindowInfo"); 
       dde.Connect(); 
       string url = dde.Request("URL", int.MaxValue); 
       string[] text = url.Split(new string[] { "\",\"" }, StringSplitOptions.RemoveEmptyEntries); 
       dde.Disconnect(); 
       return text[0].Substring(1); 
      } 
      catch 
      { 
       return null; 
      } 
     } 

     private void timer1_Tick(object sender, EventArgs e) 
     { 
      int j=0; 
      for (int i = 0; i < listBox1.Items.Count; i++) 
      { 
       if (listBox1.Items[i].ToString() == GetBrowserURL("Firefox")) 
       { 
        break; 
       } 
       else 
       { 
        j++; 
       } 
      } 
      if (j == listBox1.Items.Count) 
      { 
       listBox1.Items.Add(GetBrowserURL("Firefox")); 
      } 
     } 
    } 
} 
2

Korzystanie UIAutomation - dostać adresy URL dla Firefox i Chrome:

else if (browser == BrowserType.Chrome) 
     { 
      //"Chrome_WidgetWin_1" 

      Process[] procsChrome = Process.GetProcessesByName("chrome"); 
      foreach (Process chrome in procsChrome) 
      { 
       // the chrome process must have a window 
       if (chrome.MainWindowHandle == IntPtr.Zero) 
       { 
        continue; 
       } 
       //AutomationElement elm = AutomationElement.RootElement.FindFirst(TreeScope.Children, 
       //   new PropertyCondition(AutomationElement.ClassNameProperty, "Chrome_WidgetWin_1")); 
       // find the automation element 
       AutomationElement elm = AutomationElement.FromHandle(chrome.MainWindowHandle); 

       // manually walk through the tree, searching using TreeScope.Descendants is too slow (even if it's more reliable) 
       AutomationElement elmUrlBar = null; 
       try 
       { 
        // walking path found using inspect.exe (Windows SDK) for Chrome 29.0.1547.76 m (currently the latest stable) 
        var elm1 = elm.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Google Chrome")); 
        var elm2 = TreeWalker.ControlViewWalker.GetLastChild(elm1); // I don't know a Condition for this for finding :(
        var elm3 = elm2.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "")); 
        var elm4 = elm3.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.ToolBar)); 
        elmUrlBar = elm4.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Address and search bar")); 
       } 
       catch 
       { 
        // Chrome has probably changed something, and above walking needs to be modified. :(
        // put an assertion here or something to make sure you don't miss it 
        continue; 
       } 

       // make sure it's valid 
       if (elmUrlBar == null) 
       { 
        // it's not.. 
        continue; 
       } 

       // elmUrlBar is now the URL bar element. we have to make sure that it's out of keyboard focus if we want to get a valid URL 
       if ((bool)elmUrlBar.GetCurrentPropertyValue(AutomationElement.HasKeyboardFocusProperty)) 
       { 
        continue; 
       } 

       // there might not be a valid pattern to use, so we have to make sure we have one 
       AutomationPattern[] patterns = elmUrlBar.GetSupportedPatterns(); 
       if (patterns.Length == 1) 
       { 
        string ret = ""; 
        try 
        { 
         ret = ((ValuePattern)elmUrlBar.GetCurrentPattern(patterns[0])).Current.Value; 
        } 
        catch { } 
        if (ret != "") 
        { 
         // must match a domain name (and possibly "https://" in front) 
         if (Regex.IsMatch(ret, @"^(https:\/\/)?[a-zA-Z0-9\-\.]+(\.[a-zA-Z]{2,4}).*$")) 
         { 
          // prepend http:// to the url, because Chrome hides it if it's not SSL 
          if (!ret.StartsWith("http")) 
          { 
           ret = "http://" + ret; 
          } 
          return ret; 
         } 
        } 
        continue; 
       } 
      } 

     } 
     else if (browser == BrowserType.Firefox) 
     { 
      AutomationElement root = AutomationElement.RootElement.FindFirst(TreeScope.Children, 
       new PropertyCondition(AutomationElement.ClassNameProperty, "MozillaWindowClass")); 

       Condition toolBar = new AndCondition(
       new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.ToolBar), 
       new PropertyCondition(AutomationElement.NameProperty, "Browser tabs")); 
       var tool = root.FindFirst(TreeScope.Children, toolBar); 

       var tool2 = TreeWalker.ControlViewWalker.GetNextSibling(tool); 

       var children = tool2.FindAll(TreeScope.Children, Condition.TrueCondition); 

       foreach (AutomationElement item in children) 
       { 
        foreach (AutomationElement i in item.FindAll(TreeScope.Children, Condition.TrueCondition)) 
        { 
         foreach (AutomationElement ii in i.FindAll(TreeScope.Children, Condition.TrueCondition)) 
         { 
          if (ii.Current.LocalizedControlType == "document") 
          { 
           if (!ii.Current.BoundingRectangle.X.ToString().Contains("Infinity")) 
           { 
            ValuePattern activeTab = ii.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern; 
            var activeUrl = activeTab.Current.Value; 
            return activeUrl; 
           } 
          } 
         } 
        } 
       } 
      } 
+0

. Framework 3.0 i nowszy jest wymagany – K3rnel31

+0

Dla Chrome 'new PropertyCondition (AutomationElement.ControlTypeProperty , ControlType.TabItem) 'wydaje się wypisywać wszystkie tabulatory, którymi są dzieci, które byłyby zainteresowane po znalezieniu' elm1'. –

+2

Jednak, pozornie tylko aktualnie aktywna karta może być znaleziona przy użyciu tej metody. :-( –

0

Poniżej pracy kodu całkiem dobrze z Chrome w wersji 58.0.3029.110:

Należy dodać odniesienia UIAutomationClient i UIAutomationProvider z Assembly dostarczone przez .NET.

 foreach (Process proc in procsChrome) 
     { 
      // the chrome process must have a window 
      if (proc.MainWindowHandle == IntPtr.Zero) 
       continue; 

      // to find the tabs we first need to locate something reliable - the 'New Tab' button 
      AutomationElement root = AutomationElement.FromHandle(proc.MainWindowHandle); 
      var SearchBar = root.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "Address and search bar")); 
      if (SearchBar != null) 
       return (string)SearchBar.GetCurrentPropertyValue(ValuePatternIdentifiers.ValueProperty); 
     } 
Powiązane problemy