WindowsAppSDK
WindowsAppSDK copied to clipboard
Support "ms-app" URI schema to activate applications
Proposal: Support "ms-app" URI schema to activate applications
Summary
Add support for a new "ms-app:" URI schema to support launching an app via URI, equivalent to how one can do it via ActivateApplication().
The new "ms-app" URI scheme should support many of the options supported by Windows.System.Launcher.LaunchUriAsync(), e.g. LauncherOptions.FallbackUri.
Rationale
Many mechanisms support executing a URI - ShellExecute(), Win-R, TaskManager File/Run, CMD.EXE command line, etc. But there's no support for launching an application via URI, with all the power and functionality of ActivateApplication
shellappsfolder: is a partial workaround but faces severe functional limitations. It's also not available on all Windows platforms; ms-app: should be.
Applications can declare their own custom protocol but ShellExecute("somescheme://foo/bar") has no way to common way to express AO_NOSPLASHSCREEN, LauncherOptions.FallbackUri, .DisplayApplicationPicker, TeatAsUntrusted or other options available through ActivateApplication and LaunchUriAsync.
Scope
| Capability | Priority |
|---|---|
| Support a new protocol for app activation (suggestion: "ms-app") | Must |
| Support all parameters available via ActivateApplication | Must |
| Support applicable options available via LauncherOptions | Should |
Important Notes
Potential URI design for ms-app scheme:
ms-app://appid?options
where
- appid = Application User Model ID i.e. the application to activate
- options = ActivateApplication.options and LauncherOptions express as query parameters e.g.
ms-app://somepkgname_1234567890abc!App?designmode&splashscreen=0&errorui=0&TreatAsUntrusted=1
Open Questions
What LauncherOptions are important for an ms-app: protocol to support? e.g. FallbackUri
Also, how do unpackaged apps play into this? Do they contribute data to a key somewhere, like a progid maybe? What sources of data does ms-app consult when trying to bind a target?
Also, how do unpackaged apps play into this? Do they contribute data to a key somewhere, like a progid maybe? What sources of data does ms-app consult when trying to bind a target?
What's an "app" in the not-packaged world? Anything AppResolver can identify?
AppResolver is the only rational answer I can think of for not-packaged apps, but I'm open to suggestions
Does this solve the problem of being able to launch apps "from the command line"? I know in some contexts I can launch URLs and things from CMD / PowerShell but this doesn't work through CreateProcess right? I'm not sure if the goal here is just to make it possible to launch apps or close the gap with what non-AppX app's can do just by being launched by their .exe and parameters on the command line.
And while we're on the subject of app activation, for scripting scenarios being able to "wait" for an app to launch and then exit (like start /wait) is real handy. Does that work for scheme activation today?
Does this solve the problem of being able to launch apps "from the command line"?
Yes. "ms-app://Microsoft.WindowsCalculator_8wekyb3d8bbwe" would launch calculator
Alternatives today:
1: IF calculator defines a protocol, "calc:///" could launch it.
- Requires each app to define a protocol
- Requires each app to implement code handling Protocol activation
- No unified syntax. Each app will (try to) define a unique protocol
- 2+ apps defining a protocol (why LauncherOptions.TargetApplicationPackageFamilyName was invented, to ensure e.g. Facebook could launch "fb://home" and ensure it only launched the Facebook application, not the Facepage or other apps the declare the fb: protocool)
2: IF calculator defines an AppExecutionAlias, "calc.exe" could launch it
- Requires each app to define an AppExecutionAlias. Most don't. You the user have no ability to add that
- 2+ apps defining the same AppExecutionAlias e.g. 'paint' (why Settings has a page to let you choose the winner amongst collisions)
3: IF calculator defines
- Requires each app to declare
in a SxS manifest. Most don't. You the user have no ability to add that - Requires Windows 10.0.19041.0 aka May 2020 Update aka 20H1
- Not supported for Universal apps
Folks are looking at ways to make any app activatable via its EXE but package updates changes the pkgdir so you'd need to rely on an volatile absolute path (alternative 3 suffers the same weakness). The ms-app: solution relies on stable identifier that Windows resolves to the actual app when necessary (all problems in computer science are solved with another layer of indirection...).
Simplest case is ms-app://appid but we could extend it for more convenience, e.g. ms-app:///?name=calc would look for packages where Name=calc (similar to Get-AppxPackage) and launch the match (or throw up the usual chooser dialog if >1 match). Could add other criteria to the Query for more expansive matching
I know in some contexts I can launch URLs and things from CMD / PowerShell but this doesn't work through CreateProcess right?
That...gets complicated. Historically, yes, ShellExecute was a layer on top of CreateProcess that did more than CreateProcess. That line's blurred a bit over the years, e.g. CreateProcess("foo.exe") works even if foo.exe is an AppExecutionAlias by relying on assistance from ShellExecute (or at least parts of the plumbing). I don't know if CreateProcess("ms-app://...") would work today or if not, if it would require changes or how extensive (or even if wise at all). @andreww-msft do you know more?
I'm not sure if the goal here is just to make it possible to launch apps or close the gap with what non-AppX app's can do just by being launched by their .exe and parameters on the command line
Personally? Both.
"wait" for an app to launch and then exit (like
start /wait) is real handy. Does that work for scheme activation today?
Protocol activation is historically fire-and-forget action. "START /WAIT http://microsoft.com" doesn't wait for me but there is LaunchUriForResultsAsync() to get blocking wait semantics but I think it relies on application cooperation. Could possibly solve via a new LauncherOptions.Wait and ShellExecuteEx options, or maybe some other creative solution. Something worth considering.
There is already one available that is
shell:appsfolder\PackageFamilyName!EntryPoint
I also want to be a member of Microsoft :four_leaf_clover: