![](/img/trans.png)
[英]How to retrieve information in a second thread with a Windows Forms C# Application
[英]Retrieve current URL from C# windows forms application
我一直在使用Visual C#設計程序,並且遇到了使我的程序與Web瀏覽器交互的問題。 基本上我需要的是從Web瀏覽器(Internet Explorer,Firefox,Chrome等)中檢索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個引用:
這是我到目前為止(雖然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與完整的首映
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.