Reputation: 4849
I am trying to activate my app from its own share contract (please - don't comment about whether or not this is okay to do from a Certification point of view... The app activation is done through a button on the share contract UI and will not happen unless the user proactively it. I am asking about the technical issue here, not about the user experience side of things - thanks!!)
The way I have it is set up is like this:
this.m_shareOperation.ReportStarted();
// ....
this.m_shareOperation.ReportCompleted();
await Launcher.LaunchUriAsync(new Uri("se-myapp:///something"));
Everything seems to work fine - the Activation event/override fires, the app actually activates and shows up, but then, AFTER my OnActivated code completes, the following error shows up:
The operation cannot be completed because the window is being closed. (Exception from HRESULT: 0x802A0201)
What can I do to make this work? Any idea?
The callstack where this appears is this (no user code, does not get handled by the UnhandledException event)...
mscorlib.dll!System.Threading.Tasks.AwaitTaskContinuation.ThrowAsyncIfNecessary.AnonymousMethod__1(object s) + 0x33 bytes mscorlib.dll!System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(object state) + 0x3e bytes mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0xa7 bytes mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x16 bytes mscorlib.dll!System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() + 0x60 bytes mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() + 0x149 bytes mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() + 0x5 bytes [Native to Managed Transition]
Upvotes: 1
Views: 1006
Reputation: 4849
The solution is fairly simple, if somewhat old school (though fully supported by WinRT)...
Step 0: Define a named event you are going to use in your app:
public static EventWaitHandle GetActivationEvent()
{
EventWaitHandle sync = new EventWaitHandle(false, EventResetMode.ManualReset, Constants.ActivationEventName);
return sync;
}
Step 1: In the OnActivate() override, get that event and set it:
using (var sync = Utils.GetActivationEvent())
{
sync.Set();
}
Step 2: From the share target, activate yourself in the following way:
using (EventWaitHandle sync = Utils.GetActivationEvent())
{
await Launcher.LaunchUriAsync(new Uri(String.Format("my-protocol:///?id={0}&operation={1}", id, op)));
await Task.Run(() => sync.WaitOne(5000));
this.m_shareOperation.ReportCompleted();
}
That's it. This will make sure Windows does not get confused and whines about the app closing and opening at the same time.
Upvotes: 2
Reputation: 31823
You can't.
Unfortunately, you are attempting to mix things that are not meant to be mixed. If you create a custom protocol activation for your app, then calling the uri that contains the protocol will launch your app. The share charm will only activate apps that have a share target contract. No exceptions.
Here's a little more information on protocol activation. You might find it useful: http://blog.jerrynixon.com/2012/10/walkthrough-using-windows-8-custom.html
Upvotes: 0