WPF Webbrowser using multiple sessions when open more than once - wpf

We have a WPF webbrowser on one of our detail windows. The detail window gets opened when the user clicks on a search result so there can and will be multiple detail windows open with this webbrowser embedded. The URL is pointing to a Java based application that requires a license and is configured with NTLM to authenticate users.
The first open window is fine, but if you open more the java app gives an error that all licenses are used. In IE everything is fine, you can open multiple windows of this java app and work away.
Is there something I can configure on the webbrowser to use only one session and then clear everything when you close the main window?
**Edit: Note from the Vendor of the Java app that when a browser connects the JBoss server creates a JSessionID and that every other connection from that computer should use the same JSessionID even different browsers. The WPF control is doing something else because it is creating a session for every open view.
**Edit: The initial details I put are incorrect. The view that contains the browser control is a UserControl not a window.
**Edit: If I have no sessions and launch IE/firefox etc to open the Java app I can get a license and use the app. Now that I have a session if I try to use the WebBrowser control it will try to create a new session and I will get an error about the license. If I close the view and the browser windows and try to connect again I am again prompted with a license error as if the browser control is somehow not releasing that session.
I can post the code, but I don't see how that will help as its just a straightforward xaml insertion of the control with the source value set to the web page.

Is there a way you can separate each window/browsing session into a different appdomain?
http://msdn.microsoft.com/en-us/library/system.appdomain.aspx
On exit of the window, you could throw out that appdomain and the resources used within.

You can try and manually handle initial connectivity and then use NavigateToString to render the result. Something like this:
String responseString;
HttpWebRequest request = build you request, incorporate session token, etc
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (StreamReader reader = new StreamReader(response.GetResponseStream())) {
responseString = sr.ReadToEnd();
}
browser.NavigateToString(responseString);
EDIT:
Using cookies, source:
public partial class WebBrowserControl : Form
{
private String url;
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool InternetSetCookie(string lpszUrlName, string lbszCookieName, string lpszCookieData);
public WebBrowserControl(String path)
{
this.url = path;
InitializeComponent();
// set cookie
InternetSetCookie(url, "JSESSIONID", Globals.ThisDocument.sessionID);
// navigate
webBrowser.Navigate(url);
}
...
}

Related

Accessing cookies in WebView2 using PowerShell

Using the working example to start a WebView2 instance in PowerShell here: WebView2 in PowerShell Winform GUI
I noticed it maintains cookies nicely between sessions, just like 'normal' Edge. In some scenario's however, manually getting and/or setting cookies could be useful. A specific scenario I'm looking at is using WebView2 session cookies to create a WebDAV connection.
I tried creating a CookieManager like so:
$cookieManager = [Microsoft.Web.WebView2.Core.CoreWebView2CookieManager]
But $cookieManager then doesn't expose any methods to set/get cookies.
You should use the CookieManager property of the CoreWebView2 to obtain the cookie manager for a corresponding CoreWebView2. It will affect all CoreWebView2s that share the same user data folder.
$coreWebView2Initialized = {
# CookieManager only available after the CoreWebView2 property has been initialized.
$cookieManager = $webview.CoreWebView2.CookieManager;
$cookie = $cookieManager.CreateCookie("name", "value", "example.com", "/");
$cookieManager.AddOrUpdateCookie($cookie);
}
$webview.add_CoreWebView2InitializationCompleted($coreWebView2Initialized);

how to close application opened from Windows 10 c# wpf Launcher.LaunchUriAsync

I have created a demo which opens Windows 10 installed APP using Launcher.
private async void OpenApp()
{
var launchUri = new Uri("URL of Installed APP");
var success = await Launcher.LaunchUriAsync(launchUri);
b1 = success;
if (success)
{
// URI launched
}
else
{
// URI launch failed
}
}
For Example I have opened the windows settings application from Launcher. I want to close the same application from my WPF application after some interval of time.
Is it possible? Please let me know some solutions.
Short answer: No.
The LaunchUriAsync API just starts the default app associated with the URI scheme name for the specified URI and returns a bool that specifies whether the operation was successful. It doesn't give you any kind of reference back to the default app that was (maybe) opened so you cannot really close the app. There is no API to do this.
In WPF, you might be able to close a specific app by terminating the process:
Kill some processes by .exe file name
In UWP you are not allowed to kill a process though so then there is no way to close the app opened by the LaunchUriAsync API.

Application Insights for WPF Application

There is a WPF application written in Visual Studio.
Can I add Application Insights to this WPF app?
I would like to know how many times a button/tile is clicked. Since there are multiple installations
of the same application, I would like to know which button was clicked how many times from which user/installation. Can this be done with Application Insights?
Thanks
Avanti
While not listed as a supported app type this means there isn't default telemetry data collected/sent to application insights nor is there support for adding AI/creating an application insights resource. That being said it is possible to add to your WPF with a few manual steps so that you can track the specific scenarios you mention (like a button/tile click).
-From Visual studio add the "Application Insights API" NuGet to the project (.11 is the latest today).
This will add the Application Insights API reference and create an application insights configuration file to your project.
The applicationinsights.config file needs to be updated with your instrumentation key as follows:
<?xml version="1.0" encoding="utf-8"?>
<ApplicationInsights xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings" schemaVersion="2014-05-30">
<TelemetryChannel>
<DeveloperMode>false</DeveloperMode>
</TelemetryChannel>
<TelemetryModules>
<Add Type="Microsoft.ApplicationInsights.Tracing.DiagnosticsTelemetryModule, Microsoft.ApplicationInsights"/>
</TelemetryModules>
<InstrumentationKey>**your-instrumentation-key-guid**</InstrumentationKey>
</ApplicationInsights>
To create an application insights instrumentation key login to your azure subscription.
https://portal.azure.com
Click + to create an Application Insights resource.
Then choose the properties tile on the application insights blade and copy the Instrumentation key and add it to your applicationinsights.config file.
Now in your WPF app you can use the Application Insights sdk as described here: http://blogs.msdn.com/b/visualstudioalm/archive/2014/10/21/application-insights-sdk-0-11-0-prerelease.aspx
your events will be visible in the diagnostic search blade which can be selected on the application insights blade.
Note: telemetry is batched locally for 1 min before being sent to the service unless > 500 telemetry events are queued at which point they are sent.
https://azure.microsoft.com/en-us/documentation/articles/app-insights-windows-desktop/
An official link from Microsoft on how to add Application Insights to a Windows Forms application. From the link:
In Azure - portal.azure.com
Create an Application Resource. ::New / Developer Services / Application Insights.
Notice the instrumentation key generated, grab a copy and set it aside, we'll need it when we configure your application.
In Your Application
NuGet - Add 'Application Insights API'
Configure your TelemetryClient.
I'm using MvvmCross in a WPF application, on startup I create a single TelemetryClient that I re-use throughout the application.
var telemetryClient = new TelemetryClient();
telemetryClient.InstrumentationKey = "your key here from Azure";
telemetryClient.Context.Session.Id = Guid.NewGuid().ToString();
telemetryClient.Context.User.AccountId = Username;
telemetryClient.Context.Component.Version = Settings.Default.Version;
telemetryClient.TrackEvent("Application Start");
Mvx.RegisterSingleton<TelemetryClient>(telemetryClient);
Record an event/screen/exception, etc
Any time 'something happens' I'll resolve the TelemetryClient and record the event. This is just like any other Application Insights implementation with regards to tracking and recording.
As an example -
//Resolve the telemetry client
readonly TelemetryClient telemetryClient = Mvx.Resolve<TelemetryClient>();
//Record a page View with some extra information
var pageviewTelemetry = new PageViewTelemetry("Observations");
pageviewTelemetry.Properties.Add("Breadcrumb", breadcrumb);
telemetryClient.TrackPageView(pageviewTelemetry);
//Track an event
var eventTelemetry = new EventTelemetry("Observation Saved");
eventTelemetry.Properties.Add("Saved Observation", observation);
telemetryClient.TrackEvent(eventTelemetry);
//Track an exception
try
{
// do work here
}
catch (Exception ex)
{
telemeteryClient.TrackException(ex);
}
Flush on Application Exit
Application Insights for Windows Desktop applications does not automatically gather/send anything. As a developer one needs to force a flush at application exit.
private void PowerButton_OnClick(object sender, RoutedEventArgs e)
{
var tc = Mvx.Resolve<TelemetryClient>();
if (null != tc)
{
tc.Flush(); // only for desktop apps
}
Application.Current.Shutdown();
}
Or setup an RxTimer to flush on a schedule...I decided to flush every 30 minutes:
var observable = Observable.Interval(new TimeSpan(0, 0, 30, 0));
observable.Subscribe(_ => Application.Current.Dispatcher.Invoke(new Action(() =>
{
var tc = Mvx.Resolve<TelemetryClient>();
if (null != tc)
{
tc.Flush(); // only for desktop apps
Console.WriteLine("Flush TC");
}
})));
FYI - As of 0.17.0 of the Application Insights API NuGet Package if you are offline the flush call doesn't hang, but appears to. Online, the call completes immediately, offline there is a solid 5 second pause before the call completes.
Application Insights (AI) for desktop applications is being deprecated in favor of HockeyApp. It's not overly mature yet, but it works (events essentially reach the same place AI events go).
For example, here's how it looks in RoslynPad (a WPF C# Editor):
using Microsoft.HockeyApp;
//In your initialization method:
var hockeyClient = (HockeyClient)HockeyClient.Current;
hockeyClient.Configure(HockeyAppId)
.RegisterCustomDispatcherUnhandledExceptionLogic(OnUnhandledDispatcherException)
.UnregisterDefaultUnobservedTaskExceptionHandler();
var platformHelper = (HockeyPlatformHelperWPF)hockeyClient.PlatformHelper;
platformHelper.AppVersion = _currentVersion.ToString();
hockeyClient.TrackEvent("App Start");
//sometime later:
hockeyClient.TrackEvent("Something happened");
EDIT Looks like the following NuGet package is required in order for this to work properly: https://www.nuget.org/packages/HockeySDK.WPF.TelemetryWorkaround (see https://github.com/bitstadium/HockeySDK-Windows/pull/88).

read list items from sharepoint 2010 server to silverlight web application (cross-domain)

on one server i have www with silverlight web application. In a diffrent place in the world is the secound server with sharepoint 2010 fondation. While client connects to www server, the silverloght web application goes to him, and then trying to read list elements from sharepoint. On client desktop comes Windows - login window, after client provide username and the password, application can read the list items.
Question:
how to login IN THIS CASE from silverlight application without user prompt.
part of my code (reads only list infromation):
SilverlightApplication2.listsWebService.ListsSoapClient lws = new SilverlightApplication2.listsWebService.ListsSoapClient();
public MainPage()
{
InitializeComponent();
lws.GetListCompleted += new EventHandler<listsWebService.GetListCompletedEventArgs>(lws_GetListCompleted);
lws.GetListAsync("PagesContent");
}
void lws_GetListCompleted(object sender, listsWebService.GetListCompletedEventArgs e)
{
deltaValue.Text = e.Result.Value;
}
It can be very confusing when solving Silverlight auth in Sharepoint. I know this is possible when using Forms authentication, through web service called autentication.asmx.
With Windows authentication, I always used current logged user (which is SL default behavior).
I don't know if that can be changed from inside SL..
Here is one article that may help...
Sorry for such answer... :)

Can silverlight detect or communicate across browser instances?

User starts up a silverlight application in their browser by navigating to a given URL.
User then opens another browser and starts up the same silverlight application by navigating to the same URL.
Can the second instance of the application detect that there is already an instance running on the same computer?
Can it detect itself if both applications are running within the same browser instance?
I would expect the answer to be 'no' but thought that i would ask it anyway. Otherwise i believe that i will have to setup a webservice and have each instance register itself and send requests to other instances from the same IP. does that sound reasonable?
I think you may be looking for LocalMessageSender and LocalMessageReceiver. I believe these are new classes in Silverlight 3 allowing two Silverlight applications running on the same local computer to communicate.
More detail: Communication Between Local Silverlight-Based Applications (msdn)
This will work, I've done it myself. This code from the Microsoft site demonstrates how you set up a LocalMessage 'receiver". If it throws an error, it is because another instance of the Silverlight app is already running.
public Receiver()
{
InitializeComponent();
LocalMessageReceiver messageReceiver =
new LocalMessageReceiver("receiver",
ReceiverNameScope.Global, LocalMessageReceiver.AnyDomain);
messageReceiver.MessageReceived += messageReceiver_MessageReceived;
try
{
messageReceiver.Listen();
}
catch (ListenFailedException)
{
output.Text = "Cannot receive messages." + Environment.NewLine +
"There is already a receiver with the name 'receiver'.";
}
}
I think you're right you can't do it cross-application, but you can do it within a single browser instance using cookies or Isolated Storage.

Resources