Within the browser I can use this to open a pop-up window:
System.Windows.Browser.HtmlPage.Window.Navigate(new Uri(uri), "_blank");
How do I do this when running outside of the browser?
In an OOB app, you can use the following work around:
Create a derived hyperlink button like this:
public class MyHyperlinkButton : HyperlinkButton
{
public void ClickMe()
{
base.OnClick();
}
}
Use that for navigation:
private void NavigateToUri(Uri url)
{
if (App.Current.IsRunningOutOfBrowser)
{
MyHyperlinkButton button = new MyHyperlinkButton();
button.NavigateUri = url;
button.TargetName = "_blank";
button.ClickMe();
}
else
{
System.Windows.Browser.HtmlPage.Window.Navigate(url, "_blank");
}
}
see forums.silverlight.net
You don't. System.Windows.Browser.HtmlPage is a call to the HtmlPage that is hosting the silverlight application. In out of Browser, you are not hosted by a web page. Trying to do that just hangs the application.
If you have elevated privileges, than you could make an OS call to open a new browser, or I'm sure there are 3rd party controls that act as a hosted browser.
Another way to do this is through ShellExecute:
if (App.Current.IsRunningOutOfBrowser)
{
dynamic shell = AutomationFactory.CreateObject("Shell.Application");
shell.ShellExecute("someURL", "", "", "open", 1);
}
Documentation for ShellExecute is here: http://msdn.microsoft.com/en-us/library/bb774148(VS.85).aspx
Related
With WebVeiw2 you can send a message to a web app running in it using WebView2Ctrl?.CoreWebView2?.PostWebMessageAsJson(message).
Is there a way of doing this in CefSharp
Create a class (I used JavascriptCallbackMessenger) to Set and Run the callbacks.
public class JavascriptCallbackMessenger
{
private IJavascriptCallback _callback;
public void SetCallBack(IJavascriptCallback callback)
{
_callback = callback;
}
public void RunCallback(string message)
{
if (_callback != null && _callback.CanExecute)
{
_callback.ExecuteAsync(message);
}
}
}
Create an instance of JavascriptCallbackMessenger and register it with the CefSharp control
CefSharpCtrl.JavascriptObjectRepository.Register(JavascriptCallbackMessengerName, _messenger, true, BindingOptions.DefaultBinder);
Set the callback in Javascript as follows (I'm not a JS developer, but this was my solution).
(async function() {
const cefSharp = (window as any).CefSharp;
await cefSharp.BindObjectAsync(JavascriptCallbackMessengerName);
window.javascriptCallbackMessenger.setCallBack(function(message: string)
{
console.log("messageHandler: " + message);
})
})();
I was using typescript, so I had to extend the Window with the newly created variable.
declare global {
interface Window { javascriptCallbackMessenger: any; }
}
Apologies, but the formatting seems to be a bit "off"!
In my scenario, when I launch a URL, an authentication alert window opens up and I need to enter Username and Password from excel and on clicking on 'Log In' it'll show me the web homepage. I've implemented this using the below code snippet and it's working perfectly in IE11. But when I'm trying to run the same code in Chrome v60, it's not working. It's showing the authentication alert window but not performing any action on it. Screenshot attached. Can anyone suggest please.
Selenium WD version - 3.4.0
Code:
public static void loadApplicationURL(WebDriver driver) throws Exception
{
String SSPathl = null;
String URL = Generic_Functions.GetParameterFromInputSheet("URL");
try
{
driver.get(URL);
Thread.sleep(6000);
LoginApplication.isAlertPresent(driver);
}
}
public static boolean isAlertPresent(WebDriver driver) {
try {
driver.switchTo().alert();
UserAndPassword UP = new UserAndPassword(UserName,Password);
driver.switchTo().alert().authenticateUsing(UP);
Thread.sleep(8000);
return true;
}
catch (Exception e) {
return false;
}
}
For test browsers, have created a separate class. Find below the snippet used for IE and Chrome browsers.
For Chrome
System.setProperty("webdriver.chrome.driver",".\\Resources\\chromedriver.exe");
driver = new ChromeDriver()
In case of IE,
[System.setProperty("webdriver.ie.driver",".\\Resources\\IEDriverServer.exe");
DesiredCapabilities ieCapabilities = DesiredCapabilities.internetExplorer();
ieCapabilities.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS,true);
ieCapabilities.setCapability("nativeEvents", true);
driver = new InternetExplorerDriver(ieCapabilities);][1]
I'm using CefSharp (47) to render a webpage from a host that I have no control over, and I want to make some additional CSS tweaks to those provided by the host.
Reading up on various topics across GitHub (https://github.com/cefsharp/CefSharp/blob/cefsharp/47/CefSharp.Example/CefSharpSchemeHandlerFactory.cs), and here (CefSharp custom SchemeHandler), I wrote a custom scheme handler accordingly:
public class CustomSchemeHandlerFactory : ISchemeHandlerFactory
{
public const string SchemeName = "custom";
public IResourceHandler Create(IBrowser browser, IFrame frame, string schemeName, IRequest request)
{
Console.WriteLine(request.Url);
if (schemeName.ToLower() == SchemeName.ToLower())
{
// Do some stuff
}
return null;
}
}
I attempt to bind it in my application in the following manner:
CefSettings settings = new CefSettings();
settings.CachePath = browserCachePath;
settings.RegisterScheme(new CefCustomScheme()
{
SchemeName = CustomSchemeHandlerFactory.SchemeName,
SchemeHandlerFactory = new CustomSchemeHandlerFactory()
});
Cef.Initialize(settings);
The application then browses to the appropriate website, and uses the 'LoadingStateChanged' event to then fire off some JavaScript to inject the CSS file I want to load:
string linkText = "<link rel=\u0022stylesheet\u0022 type=\u0022text/css\u0022 href=\u0022custom://custom.css\u0022>";
var jsFunctionText = string.Format("(function() {{ $('head').append('{0}'); return true;}}) ();", linkText);
var injectionTask = await _myBrowser.GetMainFrame().EvaluateScriptAsync(jsFunctionText, null);
...which succeeds.
But my custom resource handler 'Create' event is never fired.
I can only presume that the handler isn't being registered properly, so I'd appreciate any advice/help in getting this working properly!
Thanks!
I'm having issues with trying to sign in via Google on the SoundCloud authorize page (www.soundcloud.com/connect). When a user tries to auth with that, they see a blank page and they are not redirected back to the app. It works fine for the Facebook sign in and regular user/pass sign in.
If you are using WebView the problem is it doesn't support popup windows, and they are required by the auth flow. Got it to work by implementing popup support along the lines of https://stackoverflow.com/a/8022295.
private void setUpWebView() {
webView = new WebView(getContext());
webView.setWebChromeClient(new MyChromeClient());
final WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.setSupportMultipleWindows(true);
webView.loadUrl(url);
}
...
final class MyChromeClient extends WebChromeClient {
// Add new webview in same window
#Override
public boolean onCreateWindow(WebView view, boolean dialog,
boolean userGesture, Message resultMsg) {
WebView childView = new WebView(getContext());
childView.getSettings().setJavaScriptEnabled(true);
childView.setWebChromeClient(this);
childView.setLayoutParams(FILL);
mContent.addView(childView);
WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
transport.setWebView(childView);
resultMsg.sendToTarget();
return true;
}
// remove new added webview whenever onCloseWindow gets called for new webview.
#Override
public void onCloseWindow(WebView window) {
mContent.removeViewAt(mContent.getChildCount() - 1);
}
}
I have a SilverLight project, in the project I have a PDF document.
How to create a reference to the pdf document so it will open with a click on a HyperlinkButton? What should the build action be on the PDF document?
Thanks in advance.
I think, the trick with HyperlinkButton won't work, because you will navigate relate to silverlight project but not associated web project.
You can use file download. I recomend Interlink Upload Download.
Good luck.
You should not include it in the Silverlight project. Instead include it in the associated web project as standard web content. For example if you place it in the web project in a folder called "Documents" then your button will look like:-
<HyperlinkButton Content="LaunchPDF" TargetName="_blank" NavigateUri="/Documents/MyDoc.pdf" />
You can use ICommand:
ViewModel.cs:
private static string _ApplicationUrl;
public static string ApplicationUrl
{
get
{
if (_ApplicationUrl == null)
{
_ApplicationUrl = Application.Current.Host.Source.GetComponents(UriComponents.Scheme | UriComponents.Host | UriComponents.Port, UriFormat.UriEscaped);
//_ApplicationUrl = HtmlPage.Document.DocumentUri.GetComponents(UriComponents.Scheme | UriComponents.Host | UriComponents.Port, UriFormat.UriEscaped);
}
return _ApplicationUrl;
}
}
private RelayCommand<string> _WebUriCommand;
public RelayCommand<string> WebUriCommand
{
get
{
if (_WebUriCommand == null)
{
_WebUriCommand = new RelayCommand<string>((p) => { HtmlPage.Window.Navigate(new Uri(ApplicationUrl + p), "_blank"); });
}
return _WebUriCommand;
}
}
View.xaml:
<HyperlinkButton Command="{Binding WebUriCommand}" CommandParameter="/Documents/MyDoc.pdf" Content="Download"/>