Reputation: 3512
I am trying to get URL from Opera browser, I assumed it is the same as for Chrome but I was wrong since it doesn't work this way.
whatever I have done so far is:
public static string GetURL(IntPtr intPtr, string programName, out string url)
{
string temp = null;
if (programName.Equals("opera"))
{
// // there are always multiple opera processes, so we have to loop through all of them to find the
// // process with a Window Handle and an automation element of name "Address and search bar"
/* string x = "";
DdeClient dde = new DdeClient("opera", "WWW_GetWindowInfo");
try
{
//temp := RequestData('0xFFFFFFFF');
dde.Connect();
string url1 = dde.Request("URL", int.MaxValue);
string[] text = url1.Split(new string[] { "\",\"" }, StringSplitOptions.RemoveEmptyEntries);
dde.Disconnect();
}
catch (Exception)
{
x = "failed";
}
*/
Process[] procsOpera = Process.GetProcessesByName("opera");
foreach (Process opera in procsOpera)
{
// the chrome process must have a window
if (opera.MainWindowHandle == IntPtr.Zero)
{
continue;
}
// find the automation element
AutomationElement elm = AutomationElement.FromHandle(opera.MainWindowHandle);
AutomationElement elmUrlBar = elm.FindFirst(TreeScope.Descendants,
new PropertyCondition(AutomationElement.NameProperty, "Address and search bar"));
// if it can be found, get the value from the URL bar
if (elmUrlBar != null)
{
AutomationPattern[] patterns = elmUrlBar.GetSupportedPatterns();
if (patterns.Length > 0)
{
ValuePattern val = (ValuePattern)elmUrlBar.GetCurrentPattern(patterns[0]);
temp = val.Current.Value.ToString();
url = val.Current.Value.ToString();
}
else
{
temp = "";
url = "";
}
}
else
{
temp = "";
url = "";
}
}
}
url = temp;
return temp;
}
I have tried it with both NDDE client and automation element, but both are failed :( I think in automation element the problem is in this line
AutomationElement elmUrlBar = elm.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "Address and search bar"));
Perhaps for opera it isn't "Address and search bar"
can some 1 help me to solve the issue please?
NOTE: There are couple question where chrome and opera tagged but there is no Opera working answer inside on SO.
Upvotes: 0
Views: 4178
Reputation: 51
Changed your function and made it simple as possible. Works with the current Opera version 47.0
public static string GetOperaURL()
{
string url = "";
Process[] procsOpera = Process.GetProcessesByName("opera");
foreach (Process opera in procsOpera)
{
// the chrome process must have a window
if (opera.MainWindowHandle == IntPtr.Zero)
{
continue;
}
// find the automation element
AutomationElement elm = AutomationElement.FromHandle(opera.MainWindowHandle);
AutomationElement elmUrlBar = elm.FindFirst(TreeScope.Descendants,
new PropertyCondition(AutomationElement.NameProperty, "Address field"));
// if it can be found, get the value from the URL bar
if (elmUrlBar == null) continue;
AutomationPattern pattern = elmUrlBar.GetSupportedPatterns().FirstOrDefault(wr=>wr.ProgrammaticName == "ValuePatternIdentifiers.Pattern");
if (pattern == null) continue;
ValuePattern val = (ValuePattern)elmUrlBar.GetCurrentPattern(pattern);
url = val.Current.Value;
break;
}
return url;
}
Upvotes: 1
Reputation: 894
Get Process id for opera:
public static void GetOperaURL() { Process[] OProcesses = Process.GetProcessesByName("opera"); string url = null; foreach (Process proc in OProcesses) { if (proc.MainWindowHandle != IntPtr.Zero) { url = getOperaUrlFromProcess(proc); break; } } }
Use automation element for determining URL
private static string getOperaUrlFromProcess(Process proc)
{
// find the automation element
AutomationElement elm = AutomationElement.FromHandle(proc.MainWindowHandle);
// manually walk through the tree, searching using TreeScope.Descendants is too slow (even if it's more reliable)
AutomationElement elmUrlBar = null;
try
{
var elm1 = elm.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Browser container"));
if (elm1 == null) { return null; }
elmUrlBar = elm.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "Address field"));
}
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
return null;
}
// make sure it's valid
if (elmUrlBar == null)
{
// it's not..
return null;
}
// 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 != "")
{
return ret;
}
return null;
}
return null;
}
Upvotes: 1
Reputation: 2896
You can download the NDde dll
. After adding a reference simply just copy this code to where you want to get the url.
NDde DLL Download : http://ndde.codeplex.com/
DdeClient dde = new DdeClient("opera", "WWW_GetWindowInfo");
dde.Connect();
string url = dde.Request("URL", int.MaxValue);
string[] text = url.Split(new string[] { "\",\"" }, StringSplitOptions.RemoveEmptyEntries);
dde.Disconnect();
If you want to get firefox data simply change the opera
to firefox
DdeClient dde = new DdeClient("firefox", "WWW_GetWindowInfo");
dde.Connect();
string url = dde.Request("URL", int.MaxValue);
string[] text = url.Split(new string[] { "\",\"" }, StringSplitOptions.RemoveEmptyEntries);
dde.Disconnect();
In a function
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;
}
}
Upvotes: 1