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.
Related
I have a service that is is self hosted in a WPF application. Also I have a WPF client and a xamarin android client that use the WCF client to consume the service.
I have realize that I can call with no problems from the WPF client, but from android client I only can call 2 times, later the application stop responding and after a time, I get a timeout exception.
I have read threads that say that I have to close the client proxy to solve the problem, because the number of connections are limited in the server, but this doesn't solve the problem. In fact, I have tried to no close the proxy in the WPF application and I don't have problems and I have tried to close the proxy in the android application, in the finally try/catch and in a using block, in both cases the application stops responding.
I try the solutions in threads like this and this, but they doesn't solve my problem.
The code is the following:
WPF client:
int _numeroLlamadas = 0;
GestorAplicacionesServiceProxy _proxy = new GestorAplicacionesServiceProxy();
private void BtnTest_Click(object sender, RoutedEventArgs e)
{
txtResultado.Text = _proxy.GetData(2);
_numeroLlamadas = _numeroLlamadas + 1;
txtNumeroLlamadas.Text = _numeroLlamadas.ToString();
}
In this case I have a counter to know how many times I can call to the service, and I don't have problems to call 20, 30, 40... times.
In the android application I have this code in the click event of a button:
using (GestorAplicacionesServiceProxy miProxy = new GestorAplicacionesServiceProxy(_binding, _endPointAddress))
{
string miResultado = miProxy.GetData(2);
Toast.MakeText(this, "Hola", ToastLength.Short).Show();
}
In this case I use a using block to dispose the proxy when I finish to use it. But I only can call 2 times and in the next call, the application throw a timeout exception.
The service, the instance context mode is per call.
How the WPF client works fine and the android application isn't, I was thinking that perhaps it is because the android application has different considerations.
Thanks.
I am developing a Line-of-Business app for a client. The client specified the devices that were supposed to be used (some Dell tablet with Windows 8.1). Now, that the development is almost done and we were ready to release the first phase of the application, the client informed us that they have changed their mind and all those Dell tablets will run windows 10. I upgraded one tablet that I used for development and testing to Windows 10 as well. The tablet uses a RESTful Web API to access data stored in a repository. Obviously, the URL of the Web API must be configured in the settings of the app before the app can retrieve any data from the repository.
So I create the App Package to sideload the app on the tablet. The installation works properly, the app starts well for the first time. I go into the settings, set the URL and close the app.
When I try to restart, the app gets stuck showing the Splash Screen. If I try to access the Settings, I am informed that the settings for my app are not available at that time. The only way to get out of this is to uninstall the app and reinstall it again.
This is the code I use to save and retrieve the settings:
public void SaveSetting<T>(string settingName, T value)
{
ApplicationData.Current.LocalSettings.Values[settingName] = value;
}
public T GetSetting<T>(string settingName)
{
var localSettings = ApplicationData.Current.LocalSettings.Values;
if (localSettings.ContainsKey(settingName))
{
var value = localSettings[settingName];
if (value is T)
{
return (T)value;
}
}
// else, in all other cases
return default(T);
}
An interesting thing I noticed is that sometimes, depending on what I try to save in the settings, the app starts. For example, I was playing with it and tried to save some garbage instead of the correct URL. So instead of "http://x.x.x.x:nnnnn" I saved "a". The app started correctly, I got past the splash screen but obviously, I couldn't get any data.
Any ideas as to what exactly is happening? Did the access method for local settings change in Windows 10?
I have been scratching my head over this for the past couple of days. Initially, I thought it is a matter of permissions to create the Local Settings file, so I dedicated a lot of energy trying to find a solution from that perspective. However, as I said, if I dump some garbage in the settings, it works, so it's not a matter of permissions. Could it be that and IP address like "x.x.x.x" needs to be saved in a different way than as a string?
Any advice would be highly appreciated.
TIA,
Eddie
After I added some logging to my application I was able to prove that the app had no issues reading the settings. It's what it tried to do with them that it did not work. The URL read from the settings was correct but when the app tried to make calls to the Web API, the calls threw an exception and the app stopped working. So this shouldn't have been a question in the first place.
Thanks, Eddie
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).
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);
}
...
}
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.