I have a universal Windows 10 app where I use
var token = await WebAuthenticationBrowser.AuthenticateAsync(...)
to authenticate user against facebook. It all works fine in a common scenario when it's just the foreground app. However when I add a BackgroundMediaPlayer, start music playback and communication between foreground and background, calling
var token = await WebAuthenticationBrowser.AuthenticateAsync(...)
actually kills my foreground app. When user finishes the authentication in the broker, he is taken back to the app - but it was killed and is re-instantiated. This of course means that awaiting AuthenticateAsync() doesn't produce any results, because it's a new instance of the app.
I would understand this behavior when calling WebAuthenticationBrowser.AuthenticateAndContinue() which was introduced in WP8.1, but this API has been deprecated in UWP.
So my questions are - is this expected behavior (app being killed and relaunched)? If so, how do I get the token from WebAuthenticationBroker during app relaunch?
Here is a sample project to reproduce (with exact steps in a txt file): https://t.co/XtmESd9o5r
Here is a video running the sample (first launch the broker without BackgroundMediaPlayer running, then with it running): http://youtu.be/VcZXBOTiD1Y
I started a conversation about this in twitter: https://twitter.com/lancewmccarthy/status/685152844849262593 but so far the only help I got was to "check the activation kind" with this link: https://msdn.microsoft.com/en-us/library/windows/apps/windows.applicationmodel.activation.activationkind.aspx.
The link describes activationKind has "WebAuthenticationBrokerContinuation", but
1) that's only for Windows Phone, not Windows 10
2) when you run the sample, you will never receive it. Only "Launched", with previousExecutionState "Terminated"
Related
As part of some work I need to get done for Windows 10, I have written a code in C# that essentially detects every minute whether a PC is in screen saver mode or not, and it writes to a table in MySQL the relevant status ("PC in use" if the screen saver is off, "available PC" if the screen saver is on).
I did this using (full link if required - https://www.codeproject.com/Articles/17067/Controlling-The-Screen-Saver-With-C):
// Returns TRUE if the screen saver is actually running
public static bool GetScreenSaverRunning( )
{
bool isRunning = false;
SystemParametersInfo( SPI_GETSCREENSAVERRUNNING, 0,
ref isRunning, 0 );
return isRunning;
}
The code works flawlessly in console application mode (I made a loop to test it out over a minute with a check up on screen save status every 10 seconds), this means in MySQL the status was set correctly every time, depending on the screen save status at the moment of the check up.
The problem occurs when I use this code for a windows service. The service is installed correctly, the log on tab is set on Local System (I also tried with the logged in user instead, same results) and I allow the service to interact with the desktop, just in case, but the difference here is that no matter if the PC enters screen save or not, it always returns false on GetScreenSaverRunning(), thus setting the status of the PC in MySQL as "PC in use", even if the screen saver is on at the moment of check up.
I get the sense that the problem isn't in the code itself, since it works without any issues as a console application, but perhaps something behind the scenes. I tried to search here and on many other websites, haven't found anything related to such a problem.
Does anyone have any idea at all what might be the issue? Any help and/or suggestions will be greatly appreciated!
Thank you in advance.
(I could post the code if required, but it is pretty much straight forward and the main part of it, controlling the screen save detection, is taken from the website mentioned above, afterwards it's a simple if (GetScreenSaverRunning() == true) )
Ever since Vista, Services are barred from a Interactive Session. Even if they run under the same rights, they do not get a interactive Session. I would guess that is getting in the way here.
While you can overwrite this behavior in the Service settings, this is not adviseable for new code. Consider making this a Background Task started by the Task Sheduler instead.
Because the windows service runs in different session then the windows logon. You can't interact with the desktop related services unless you run the windows service in win logon session. There used to be an option in Windows service manager where you can set the properties to "Interact with desktop session" but I don't think that ever worked.
There's a work around to run the windows service using the win logo session.
See this helper class that can get the current logged on user session and interact with the desktop services. https://github.com/murrayju/CreateProcessAsUser/blob/master/ProcessExtensions/ProcessExtensions.cs
I'm trying to use an in-process background task to get notifications of a Bluetooth LE device. However, the following code hangs at the last line and does not return:
var bldr = new BackgroundTaskBuilder();
bldr.Name = guid.ToString("N");
var trigger = new GattCharacteristicNotificationTrigger(ch);
bldr.SetTrigger(trigger);
bldr.Register();
Getting the notifications of the device works when using the event-based model in the application. Also, registering the task with a TimeTrigger works, so the declaration in the app manifest is ok.
The computer runs the Creators Update, but the UWP is set to require the Anniversary update as a minimum.
We've had the same issue with UWP app on windows 10 mobile. It was resolved after we had updated windows 10 mobile to build 10.0.15230.0.
This hang on Register issue for GattCharacteristicNotificationTrigger was identified and fixed thanks to this question. The fix was released in build 15228 as a servicing build to the Creator's Update of the OS.
Similar to this question which invokes the Windows 10 store to allow a user to write a review or rate an app, I'd also like to be able to invoke the Windows 10 Feedback app and allow users to provide feedback there.
I cannot seem to find much information on:
How this works in general. Can any old app use this service? (I
notice it just kind of shows whatever apps I have running)
How to invoke the Windows Feedback app with my package id
In short - not that I can see.
Other apps are invoked via protocol activation. I haven't seen this documented for the feedback app though so I have to err on the side of 'we haven't made this available yet' (I'm still checking though)
Here's an overall guide to the process http://blog.jerrynixon.com/2012/10/walkthrough-using-windows-8-custom.html?m=1
When I look in the registry under HKEY_CLASSES_ROOT\Extensions\ContractId\Windows.Protocol I see (shortened a tad)
[HKEY_CLASSES_ROOT\Extensions\ContractId\Windows.Protocol\PackageId\Microsoft.WindowsFeedback...\ActivatableClassId\App.AppX7eaybq6p4x7d4jgd6w6jk7r5dg6yhmbf.mca\CustomProperties]
"Name"="windows-feedback"
So - give that a try via launching windows-feedback
If I do Windows Key-R (run): windows-feedback://
it works fine so this should work:
var uri = new Uri(#"windows-feedback://");
var success = await Windows.System.Launcher.LaunchUriAsync(uri);
if (success)
{
// URI launched
}
else
{
// URI launch failed
}
Update
I've done some searching and it seems the magic parameter there is
windows-feedback:?contextid=522
That launches the NFL feedback for example. This is a predetermined number - I'm not sure how one gets on this list though.
When the BackgroundAudioTask for my app is cancelled by other app on Windows Phone 8.1 which also uses BackgroundAudioTask, when I go back into my app, it will no longer play audio in the background. It will play fine when the app is running but if it is suspended - the background audio also stops.
The steps to reproduce this issue are:
I launch the Windows Phone 8.1 app which has a BackgroundAudioTask & everything works fine. I that start another app, for example the Music player, that uses a BackgroundAudioTask it will cancel the BackgroundAudioTask of my app.
When I launch my app for the second time, I want to re-register my BackgroundAudioTask so that it will behave as it did originally.
In Package.appxmanifest I have the following:
<Extensions>
<Extension Category="windows.backgroundTasks" EntryPoint="WindowsPhoneBackgroundAudioTask.BackgroundAudioTask">
<BackgroundTasks>
<Task Type="audio" />
</BackgroundTasks>
</Extension>
</Extensions>
When I first run the application the Run method will be called and I add a Deferral to the task to make sure it is kept alive even when I close my application:
public void Run(IBackgroundTaskInstance taskInstance)
{
setupDeferral = taskInstance.GetDeferral();
}
When I start the music player from another application my BackgroundAudioTask Cancelled event is called (If I don't do setupDeferral.Complete() here my application will crash):
private void Task_Canceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
setupDeferral.Complete();
}
When I open my app how do I recreate my BackgroundAudioTask? The problem is the Run method is never called again so I can't setup the Deferral again. Music will now play fine in the app, but as soon as I navigate away from the app the music will stop.
I tried manually re-registering the task in App.xaml.cs in the App_Resuming event with this code:
var taskBuilder = new BackgroundTaskBuilder();
taskBuilder.Name = "BackgroundAudioTask";
taskBuilder.TaskEntryPoint = typeof(WindowsPhoneBackgroundAudioTask.BackgroundAudioTask).FullName;
BackgroundTaskRegistration task = taskBuilder.Register();
The above code will throw and InvalidArgumentException because it does not have a Trigger setup. I don't want it to have a trigger. I just want to start the background task immediately.
Is there a way to manually instruct the OS to run the background audio again or a way to handle cancelled background audio better?
I know this is really old - but maybe someone will come across it. You actually don't need to register the task at all.
In the case of background audio, all you need to do is call
BackgroundMediaPlayer.Current
And it will fire up the task, and then your code will get the deferral.
I too had this same issue. The Background Audio Task wasn't starting playback once it was cancelled - either due to 5 minutes of inactivity, or due to another app. I was referring the sample code given by Microsoft here.
After hours of searching on the internet, I didn't find a solution. Then, digging in my code further, I found out that when the task is cancelled, the BackgroundMediaPlayer.Current.CurrentState becomes MediaPlayerState.Closed.
Hence, in order to restart the task/background audio playback, just set a source to the BackgroundMediaPlayer.Current again. In the sample code, this media player object is referenced using a variable named mediaPlayer inside the PlaylistManager project component.
Although the sample has a piece of code to restart playback once the task is cancelled, it does not work.
I have a windows service called MainService, which is used to monitor SubServices. The SubServices are actually some console applications and started by the MainService via Process.Start() method. Example code:
var subServiceProcess = Process.Start(subService.ServicePath);
The SubServices work perfectly until one of them needs to start another desktop application like the MainService does. Example code:
var desktopApplicationProcess = Process.Start(desktopApplicationPath);
The desktopApplicationProcess is created and we can see it in the taskmanager. However, its GUI doesn't show.
I've tried to run the sub service manually, and then the desktop runs correctly. So, I guess this is caused by that the sub service is started by the MainService.
Can anybody give me some sugguestion?
Thanks a lot~
Have you allowed the Service to interact with the desktop?