Start Default Browser - Windows - vb.net

When starting the default browser like this:
Dim trgt1 As String = "http://www.vbforums.com/showthread.php?t=612471"
pi.FileName = trgt1
System.Diagnostics.Process.Start(pi)
It takes about 40 seconds to open the page.
If I do it like this, though this isn't the default browser
Dim trgt1 As String = "http://www.vbforums.com/showthread.php?t=612471"
pi.Arguments = trgt1
pi.FileName = "iexplore.exe" 'or firefox.exe
System.Diagnostics.Process.Start(pi)
it opens immediately. Is this a bug or a feature? I have tried this with both IE and FireFox set to be the default browser.

1
Windows is running through the registry looking for an appropriate application to open the document with (via explorer.exe).
2
You are explicitly telling windows to use xxx.exe to open the document.
Update for the moving target: ;-)
The reason it is so slow is that the Url you are specifying doesn't look like anything it knows how to open, with a browser or otherwise, and has to employ brute force in determining this.
If you wan to speed up launching with the default browser, get it from HKEY_CURRENT_USER\Software\Classes\http\shell\open\command and use #2.
Use this function to retrieve path of default browser
/// <summary>
/// Reads path of default browser from registry
/// </summary>
/// <returns></returns>
private static string GetDefaultBrowserPath()
{
string key = #"htmlfile\shell\open\command";
RegistryKey registryKey =
Registry.ClassesRoot.OpenSubKey(key, false);
// get default browser path
return ((string) registryKey.GetValue(null, null)).Split('"')[1];
}
Opens URL in default browser from within the C# program.
string defaultBrowserPath = GetDefaultBrowserPath();
try
{
// launch default browser
Process.Start(defaultBrowserPath, "http://www.yahoo.com");
}
catch (Exception exp)
{
MessageBox.Show(exp.Message);
}
Opens URL in separate instance of default browser from within the C# program.
// open URL in separate instance of default browser
Process p = new Process();
p.StartInfo.FileName = GetDefaultBrowserPath();
p.StartInfo.Arguments = "http://www.yahoo.com";
p.Start();
From this blog post

I respectfully differ with the Sky. I have tried this on numerous machines now and the value
string key = #"htmlfile\shell\open\command";
seems to always default to IE even if Chrome is set to the default browser. Now, to be honest I have not tried this on machines with firefox set to the default browser only chrome, so it could do with more testing but the value does seem to only store IE from my testing.
Hope this helps those who use alternative browsers.
I am going to stick with process.start(url) as that pretty much guarantees that you get the users default browser every time. Let the framework handle it! that is why MS built it...

Related

How to run Selenium test using Edge headless

Some time ago, I wrote some Selenium unit tests and these used the Firefox browser (headless). After a few years, I have returned to these (and cannot now remember how they worked) and would like to update them to use the Edge browser (in headless mode). How do I do this ? Specifically, when I ask the IWebDriver to "Navigate", how does it know the root URL - specifically the port ? I presume that my URL would be "http://localhost:nnnn/blah...", but how do I determine the port (which I also presume I need) ?
My code is based upon the following:
protected IWebDriver GetBrowserEdge(bool headless = true)
{
var service = SeleniumTools.EdgeDriverService.CreateChromiumService();
service.UseVerboseLogging = true;
var options = new SeleniumTools.EdgeOptions { PageLoadStrategy = PageLoadStrategy.Normal, UseChromium = true };
if (headless) options.AddArgument("headless");
return new SeleniumTools.EdgeDriver(service, options);
}
I wasn't using "CreateChromiumService" before (and I note it is disposable - which gives me a design issue), but I note that the service it returns has a "port" property. Do I need to leverage that in my "IWebDriver.Navigate" calls ?
I am using Edge v92.0.902.73 and Microsoft.Edge.SeleniumTools v3.141.2

How to disable SmartScreen (safebrowsing in edge) on C# Selenium Edge Chromium?

I'm trying to run some selenium C# end-to-end tests on Edge Chromium browser. One of the tests does a download check, basically it downloads a xml file and check whether it exists in the downloaded location.
I'm using Microsoft.Edge.SeleniumTools EdgeOptions to construct options for the EdgeDriver.
But the issue right now is that Edge blocks downloads.
Tried different sorts of things but none of them worked.
Same issue can be solved on Chrome by disabling "safebrowsing" on UserProfilePreferences in ChromeOptions.
I know for a fact that SmartScreen does the blocking, if that is so is there any profile preference that I can use to disable SmartScreen ?
Or any other workaround to force download without the block would be very helpful.
For testing purposes, I suggest you create HashMap objects and try to set Edge preferences like below.
static void Main(string[] args)
{
HashMap<String, Object> edgePrefs = new HashMap<String, Object>();
edgePrefs.put("profile.default_content_settings.popups", 0);
edgePrefs.put("profile.default_content_setting_values.notifications", 2);
edgePrefs.put("profile.default_content_setting_values.automatic_downloads" , 1);
edgePrefs.put("profile.content_settings.pattern_pairs.*,*.multiple-automatic-downloads",1);
var options = new EdgeOptions();
egdeOptions.setExperimentalOption("prefs",edgePrefs);
options.UseChromium = true;
options.BinaryLocation = #"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"; // Here add the Edge browser exe path.
var driver = new EdgeDriver(#"Edge_driver_path_here...", options); // Here modify the selenium web driver path.
driver.Navigate().GoToUrl("http://website_URL_here...");
driver.FindElementById("lnk1").Click();
}
If the issue persists then I suggest you set the default download directory like below.
options.AddUserProfilePreference("download.default_directory", #"D://Folder1");
See whether it help to download the file.
I was trying to find the answer with the usage of W3C WebDriver Protocol, but it seems like the only possible way is to turn off XML Edge SmartScreen policies using Windows Registry:
public void SetEdgeXmlDownloadPolicy()
{
var keyName = #"HKEY_CURRENT_USER\Software\Policies\Microsoft\Edge\ExemptDomainFileTypePairsFromFileTypeDownloadWarnings";
var valueName = "AllowXmlDownload";
var valueData = #"{""domains"": ["" * ""], ""file_extension"": ""xml""}";
var currentValue = Registry.GetValue(keyName, valueName, string.Empty).ToString();
if (currentValue == string.Empty || !currentValue.Contains("xml"))
Registry.SetValue(keyName, valueName, valueData, RegistryValueKind.String);
}
Credits to this workaround goes to IndianCodeMaster

Check if Seleniums chrome webbrowser is downloading

I've seen a few questions asking if it's possible to check if a specific download is completed, or if a specific download has been completed successfully. (to which the answer appears to be no.)
What I want to know: Is it possible to see if selenium is currently downloading any file? I.e. it doesn't matter if it's one file, or 20. Something like a small boolean check would be ideal.
When chrome is downloading a file you can check your downloads folder for the temp file (*.crdownload) that Chrome uses. When the download finishes that file is "replaced" by the actual filename/type.
/// <summary>
/// Looks for a file with the given extension (Example: "*.crdownload") in the current user's "Download" folder.
/// </summary>
public static string LocateDownloadedFile(string fileExtension)
{
// Get the default downloads folder for the current user
string downloadFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\Downloads";
DirectoryInfo di = new DirectoryInfo(downloadFolderPath);
FileInfo[] filesFound = di.GetFiles(fileExtension);
if (filesFound.Length == 0)
{
// do stuff
}
else
{
// do other stuff
}
}

Read a file from the cache in CEFSharp

I need to navigate to a web site that ultimately contains a .pdf file and I want to save that file locally. I am using CEFSharp to do this. The nature of this site is such that once the .pdf appears in the browser, it cannot be accessed again. For this reason, I was wondering if once you have a .pdf displayed in the browser, is there a way to access the source for that file in the cache?
I have tried implementing IDownloadHandler and that works, but you have to click the save button on the embedded .pdf. I am trying to get around that.
OK, here is how I got it to work. There is a function in CEFSharp that allows you to filter an incoming web response. Consequently, this gives you complete access to the incoming stream. My solution is a little on the dirty side and not particularly efficient, but it works for my situation. If anyone sees a better way, I am open for suggestions. There are two things I have to assume in order for my code to work.
GetResourceResponseFilter is called every time a new page is downloaded.
The PDF is that last thing to be downloaded during the navigation process.
Start with the CEF Minimal Example found here : https://github.com/cefsharp/CefSharp.MinimalExample
I used the WinForms version. Implement the IRequestHandler and IResponseFilter in the form definition as follows:
public partial class BrowserForm : Form, IRequestHandler, IResponseFilter
{
public readonly ChromiumWebBrowser browser;
public BrowserForm(string url)
{
InitializeComponent();
browser = new ChromiumWebBrowser(url)
{
Dock = DockStyle.Fill,
};
toolStripContainer.ContentPanel.Controls.Add(browser);
browser.BrowserSettings.FileAccessFromFileUrls = CefState.Enabled;
browser.BrowserSettings.UniversalAccessFromFileUrls = CefState.Enabled;
browser.BrowserSettings.WebSecurity = CefState.Disabled;
browser.BrowserSettings.Javascript = CefState.Enabled;
browser.LoadingStateChanged += OnLoadingStateChanged;
browser.ConsoleMessage += OnBrowserConsoleMessage;
browser.StatusMessage += OnBrowserStatusMessage;
browser.TitleChanged += OnBrowserTitleChanged;
browser.AddressChanged += OnBrowserAddressChanged;
browser.FrameLoadEnd += browser_FrameLoadEnd;
browser.LifeSpanHandler = this;
browser.RequestHandler = this;
The declaration and the last two lines are the most important for this explanation. I implemented the IRequestHandler using the template found here:
https://github.com/cefsharp/CefSharp/blob/master/CefSharp.Example/RequestHandler.cs
I changed everything to what it recommends as default except for GetResourceResponseFilter which I implemented as follows:
IResponseFilter IRequestHandler.GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response)
{
if (request.Url.EndsWith(".pdf"))
return this;
return null;
}
I then implemented IResponseFilter as follows:
FilterStatus IResponseFilter.Filter(Stream dataIn, out long dataInRead, Stream dataOut, out long dataOutWritten)
{
BinaryWriter sw;
if (dataIn == null)
{
dataInRead = 0;
dataOutWritten = 0;
return FilterStatus.Done;
}
dataInRead = dataIn.Length;
dataOutWritten = Math.Min(dataInRead, dataOut.Length);
byte[] buffer = new byte[dataOutWritten];
int bytesRead = dataIn.Read(buffer, 0, (int)dataOutWritten);
string s = System.Text.Encoding.UTF8.GetString(buffer);
if (s.StartsWith("%PDF"))
File.Delete(pdfFileName);
sw = new BinaryWriter(File.Open(pdfFileName, FileMode.Append));
sw.Write(buffer);
sw.Close();
dataOut.Write(buffer, 0, bytesRead);
return FilterStatus.Done;
}
bool IResponseFilter.InitFilter()
{
return true;
}
What I found is that the PDF is actually downloaded twice when it is loaded. In any case, there might be header information and what not at the beginning of the page. When I get a stream segment that begins with %PDF, I know it is the beginning of a PDF so I delete the file to discard any previous contents that might be there. Otherwise, I just keep appending each segment to the end of the file. Theoretically, the PDF file will be safe until you navigate to another PDF, but my recommendation is to do something with the file as soon as the page is loaded just to be safe.

Unable to find browser object in RFT 8.5

I installed RFT 8.5 and JRE 7. When I run the scripts it's not finding browser object.
Below is the code which I have used in RFt to find the brwoser object.
Dim Allobjects() as TestObeject
Allobjects=RootTestObject.GetRootTestObject.Find(".class","Html.HtmlBrowser"))
Here it's is returning Allbects.lenth=0. Because of the I am getting struck.
Anybody can help me how to resolve this issue.
Note: I am using IE8
I was not able to find the browsers using RootTestObject either. But it is possible to find the browser windows using the Html domains:
startApp("Google");
startApp("asdf");
sleep(5);
DomainTestObject[] dtos = getDomains();
List<DomainTestObject> htmlDomains = new ArrayList<DomainTestObject>();
for (DomainTestObject dto : dtos) {
if (dto.getName().equals("Html")) {
htmlDomains.add(dto);
}
}
List<BrowserTestObject> browsers = new ArrayList<BrowserTestObject>();
for (DomainTestObject htmlDomain : htmlDomains) {
TestObject[] tos = htmlDomain.getTopObjects();
for (TestObject to : tos) {
if (to.getProperty(".class").equals("Html.HtmlBrowser")) {
browsers.add((BrowserTestObject) to);
}
}
}
System.out.println("Found " + browsers.size() + " browsers:");
for (BrowserTestObject browser : browsers) {
System.out.println(browser.getProperty(".documentName"));
}
Output:
Found 2 browsers:
https://www.google.ch/
http://www.asdf.com/
First, I start 2 browsers. Then I get all Html domain test objects. After that, I get all top objects and check whether their class is Html.HtmlBrowser.
I hope there is a simpler solution—looking forward to seeing one :)
Try the below code Snippet:
Dim Allobjects() As TestObject
Allobjects = Find(AtDescendant(".class", "Html.HtmlBrowser"))
Hope it helps.
Browser is a toplevel window so what you can do is :
Dim Allobjects() as TestObeject
Allobjects=Find(AtChild(".class","Html.HtmlBrowser"))
'The above code expects the browser to be statically enabled , also RootTestObject is not needed as implicitly RFT will use the RootTestObject if no anchor is provided.
Also if the browser is not statically enabled then you could also use:
DynamicEnabler.HookBrowsers() API so that browsers get enabled.