Recupera l’URL corrente dall’applicazione di windows di Windows C #

Ho progettato un programma utilizzando Visual C # e ho riscontrato un problema nel far interagire il mio programma con i browser web. Fondamentalmente ciò di cui ho bisogno è di recuperare l’indirizzo URL da un browser web (Internet Explorer, Firefox, Chrome ecc …).

Ho pensato che non sarebbe stato troppo difficile per un compito, ma dopo giorni e giorni di ricerche e test, sembra quasi imansible! Finora, mi sono imbattuto in questo …

Ottieni l’URL di Firefox?

Quale ha il codice qui sotto:

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

Che è perfetto per Firefox, ma per qualche motivo non riesco a farlo funzionare con qualcos’altro. Ho modificato la parte del codice che dice “Firefox” in “Iexplore”, come ho trovato su Internet, insieme a provare altre forms di espressione di Internet Explorer e ottengo il seguente errore:

“Il client non è riuscito a connettersi a” IExplorer | WWW_GetWindowInfo “, assicurarsi che l’applicazione server sia in esecuzione e che supporti il ​​nome del servizio specificato e la coppia nome argomento”

Qualsiasi aiuto sulla questione sarebbe molto apprezzato in quanto è diventato un compito abbastanza da capire.

Ecco cosa ho finora (anche se Chrome non sto trovando alcun articolo utile su, oltre a utilizzare FindWindowEx (non mi piace particolarmente quel metodo, personalmente).

 public class BrowserLocation { ///  /// Structure to hold the details regarding a browed location ///  public struct URLDetails { ///  /// URL (location) ///  public String URL; ///  /// Document title ///  public String Title; } #region Internet Explorer // requires the following DLL added as a reference: // C:\Windows\System32\shdocvw.dll ///  /// Retrieve the current open URLs in Internet Explorer ///  ///  public static URLDetails[] InternetExplorer() { System.Collections.Generic.List URLs = new System.Collections.Generic.List(); 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.InternetExplorer())).ForEach(u => { Console.WriteLine("[{0}]\r\n{1}\r\n", u.Title, u.URL); }); Console.WriteLine(); Console.WriteLine("Firefox:"); (new List(BrowserLocation.Firefox())).ForEach(u => { Console.WriteLine("[{0}]\r\n{1}\r\n", u.Title, u.URL); }); Console.WriteLine(); } } 

Ecco un codice basato su 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; } 

Puoi utilizzare lo strumento UI Spy per comprendere la gerarchia visiva per tutti e 3 i browser. Potrebbe essere necessario adattare le cose per assicurarsi che funzioni davvero nei casi specifici, ma dovresti ottenere l’idea generale con questi esempi.

E un esempio che scarica tutti gli URL per tutti i 3 tipi di processo (IE, FF, CH) attualmente in esecuzione nel sistema:

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

Utilizza il parametro “1” anziché “URL” in oDde.Request (“URL”, int.MaxValue) per IE.

  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, grazie per la tua soluzione Microsoft UI Automation . Anche se non ha funzionato con Firefox 41.0, ho analizzato la struttura della finestra di Firefox con il tool “Automation Spy “. Poi ho cambiato leggermente le condizioni di ricerca, e ha funzionato perfettamente!

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

Ed ecco la soluzione per 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 mostra la struttura dei controlli della finestra di Firefox. Il controllo del tipo “modifica” con il nome “Cerca o inserisci indirizzo” contiene l’url: Automation Spy

Nota: nel tuo progetto .NET hai bisogno di 2 riferimenti:

  • UIAutomationClient.dll
  • UIAutomationTypes.dll

WWW_GetWindowInfo è supportato in IE e dalla versione 3.02 è tornato nei 16 bit giorni! Funziona con Firefox e Opera

Credo che Chrome sia in effetti il ​​più strano.

Non ho alcuna conoscenza di come le cose vanno oltre quelle quattro.

la scelta migliore è quella di utilizzare il webdriver di selenium. la migliore e la piena api completa con piena premisione