WindowsAppSDK icon indicating copy to clipboard operation
WindowsAppSDK copied to clipboard

Support "ms-app" URI schema to activate applications

Open DrusTheAxe opened this issue 5 years ago • 6 comments

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

DrusTheAxe avatar Oct 14 '20 21:10 DrusTheAxe

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?

jonwis avatar Oct 14 '20 22:10 jonwis

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

DrusTheAxe avatar Oct 14 '20 22:10 DrusTheAxe

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?

jevansaks avatar Oct 15 '20 04:10 jevansaks

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 in is SxS manifest, "C:\Foo\Bar\calc.exe" could launch it

  • 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.

DrusTheAxe avatar Oct 15 '20 17:10 DrusTheAxe

There is already one available that is

shell:appsfolder\PackageFamilyName!EntryPoint

driver1998 avatar Jan 30 '21 08:01 driver1998

I also want to be a member of Microsoft :four_leaf_clover:

ghost avatar Mar 06 '21 06:03 ghost