Tag Archives: Win32

Configure your app to start at log-in

For a long time, desktop PC users have been able to configure Win32 apps to start at startup or user log-in. This has also been possible for Desktop Bridge apps since the Windows 10 Anniversary Update (v10.0.14393.0). We’ve now extended this feature to allow regular Universal Windows Apps to take part in this also. This is available in Insider builds from Build 16226 onwards, along with the corresponding SDK. In this post, we’ll look at the code changes you need to make in your manifest and in your App class to handle the startup scenario, and how your app can work with the user to respect their choices.

Here’s a sample app, called TestStartup – the app offers a button to request enabling the startup behavior, and reports current status. Typically, you’d put this kind of option into a settings page of some kind in your app.

The first thing to note is that you must use the windows.startupTask Extension in your app manifest under the Extensions node, which is a child of the Application node. This is documented here. The same Extension declaration is used for both Desktop Bridge and regular UWP apps – but there are some differences.

  • Desktop Bridge is only available on Desktop, so it uses a Desktop-specific XML namespace. The new UWP implementation is designed for use generally on UWP, so it uses a general UAP namespace (contract version 5) – although to be clear, it is currently still only actually available on Desktop.
  • The Desktop Bridge EntryPoint must be “Windows.FullTrustApplication,” whereas for regular UWP it is the fully-qualified namespace name of your App class.
  • Desktop Bridge apps can set the Enabled attribute to true, which means that the app will start at startup without the user having to manually enable it. Conversely, for regular UWP apps this attribute is ignored, and the feature is implicitly set to “disabled.” Instead, the user must first launch the app, and the app must request to be enabled for startup activation.
  • For Desktop Bridge apps, multiple startupTask Extensions are permitted, each one can use a different Executable. Conversely, for regular UWP apps, you would have only one Executable and one startupTask Extension.
Desktop Bridge App UWP App

xmlns:desktop="http://schemas.microsoft.com/
appx/manifest/desktop/windows10"


xmlns:uap5="http://schemas.microsoft.com/
appx/manifest/uap/windows10/5"


<desktop:Extension
  Category="windows.startupTask"
  Executable="MyDesktopBridgeApp.exe"
  EntryPoint="Windows.FullTrustApplication">
  <desktop:StartupTask
    TaskId="MyStartupId"
    Enabled="false"
    DisplayName="Lorem Ipsum" />
</desktop:Extension>


<uap5:Extension
  Category="windows.startupTask"
  Executable="TestStartup.exe"
  EntryPoint="TestStartup.App">
  <uap5:StartupTask
    TaskId="MyStartupId"
    Enabled="false"
    DisplayName="Lorem Ipsum" />
</uap5:Extension>

For both Desktop Bridge apps and regular UWP apps, the user is always in control, and can change the Enabled state of your startup app at any time via the Startup tab in Task Manager:

Also for both app types, the app must be launched at least once before the user can change the Disabled/Enabled state. This is potentially slightly confusing: if the user doesn’t launch the app and then tries to change the state to Enabled in Task Manager, this will seem to be set. However, if they then close Task Manager and re-open it, they will see that the state is still Disabled. What’s happening here is that Task Manager is correctly persisting the user’s choice of the Enabled state – but this won’t actually allow the app to be activated at startup unless and until the app is launched at least once first – hence the reason it is reported as Disabled.

In your UWP code, you can request to be enabled for startup. To do this, use the StartupTask.GetAsync method to initialize a StartupTask object (documented here) – passing in the TaskId you specified in the manifest – and then call the RequestEnableAsync method. In the test app, we’re doing this in the Click handler for the button. The return value from the request is the new (possibly unchanged) StartupTaskState.


async private void requestButton_Click(object sender, RoutedEventArgs e)
{
    StartupTask startupTask = await StartupTask.GetAsync("MyStartupId");
    switch (startupTask.State)
    {
        case StartupTaskState.Disabled:
            // Task is disabled but can be enabled.
            StartupTaskState newState = await startupTask.RequestEnableAsync();
            Debug.WriteLine("Request to enable startup, result = {0}", newState);
            break;
        case StartupTaskState.DisabledByUser:
            // Task is disabled and user must enable it manually.
            MessageDialog dialog = new MessageDialog(
                "I know you don't want this app to run " +
                "as soon as you sign in, but if you change your mind, " +
                "you can enable this in the Startup tab in Task Manager.",
                "TestStartup");
            await dialog.ShowAsync();
            break;
        case StartupTaskState.DisabledByPolicy:
            Debug.WriteLine(
                "Startup disabled by group policy, or not supported on this device");
            break;
        case StartupTaskState.Enabled:
            Debug.WriteLine("Startup is enabled.");
            break;
    }
}

Because Desktop Bridge apps have a Win32 component, they run with a lot more power than regular UWP apps generally. They can set their StartupTask(s) to be Enabled in the manifest and do not need to call the API. For regular UWP apps, the behavior is more constrained, specifically:

  • The default is Disabled, so in the normal case, the user must run the app at least once explicitly – this gives the app the opportunity to request to be enabled.
  • When the app calls RequestEnableAsync, this will show a user-prompt dialog for UWP apps (or if called from a UWP component in a Desktop Bridge app from the Windows 10 Fall Creators Update onwards).
  • StartupTask includes a Disable method. If the state is Enabled, the app can use the API to set it to Disabled. If the app then subsequently requests to enable again, this will also trigger the user prompt.
  • If the user disables (either via the user prompt, or via the Task Manager Startup tab), then the prompt is not shown again, regardless of any requests from the app. The app can of course devise its own user prompts, asking the user to make manual changes in Task Manager – but if the user has explicitly disabled your startup, you should probably respect their decision and stop pestering them. In the sample code above, the app is responding to DisabledByUser by popping its own message dialog – you can obviously do this if you want, but it should be emphasized that there’s a risk you’ll just annoy the user.
  • If the feature is disabled by local admin or group policy, then the user prompt is not shown, and startup cannot be enabled. The existing StartupTaskState enum has been extended with a new value, DisabledByPolicy. When the app sees DisabledByPolicy, it should avoid re-requesting that their task be enabled, because the request will never be approved until the policy changes.
  • Platforms other than Desktop that don’t support startup tasks also report DisabledByPolicy.

Where a request triggers a user-consent prompt (UWP apps only), the message includes the DisplayName you specified in your manifest. This prompt is not shown if the state is DisabledByUser or DisabledByPolicy.

If your app is enabled for startup activation, you should handle this case in your App class by overriding the OnActivated method. Check the IActivatedEventArgs.Kind to see if it is ActivationKind.StartupTask, and if so, case the IActivatedEventArgs to a StartupTaskActivatedEventArgs. From this, you can retrieve the TaskId, should you need it. In this test app, we’re simply passing on the ActivationKind as a string to MainPage.


protected override void OnActivated(IActivatedEventArgs args)
{
    Frame rootFrame = Window.Current.Content as Frame;
    if (rootFrame == null)
    {
        rootFrame = new Frame();
        Window.Current.Content = rootFrame;
    }

    string payload = string.Empty;
    if (args.Kind == ActivationKind.StartupTask)
    { 
        var startupArgs = args as StartupTaskActivatedEventArgs;
        payload = ActivationKind.StartupTask.ToString();
    }

    rootFrame.Navigate(typeof(MainPage), payload);
    Window.Current.Activate();
}

Then, the MainPage OnNavigatedTo override tests this incoming string and uses it to report status in the UI.


protected override void OnNavigatedTo(NavigationEventArgs e)
{
    string payload = e.Parameter as string;
    if (!string.IsNullOrEmpty(payload))
    {
        activationText.Text = payload;

        if (payload == "StartupTask")
        {
            requestButton.IsEnabled = false;
            requestResult.Text = "Enabled";
            SolidColorBrush brush = new SolidColorBrush(Colors.Gray);
            requestResult.Foreground = brush;
            requestPrompt.Foreground = brush;
        }
    }
}

Note that when your app starts at startup, it will start minimized in the taskbar. In this test app, when brought to normal window mode, the app reports the ActivationKind and StartupTaskState:

Using the windows.startupTask manifest Extension and the StartupTask.RequestEnableAsync API, your app can be configured to start at user log-in. This can be useful for apps which the user expects to use heavily, and the user has control over this – but it is still a feature that you should use carefully. You should not use the feature if you don’t reasonably expect the user to want it for your app – and you should avoid repeatedly prompting them once they’ve made their choice. The inclusion of a user-prompt puts the user firmly in control, which is an improvement over the older Win32 model.

Sample Code here.

Calling WinRT Components from a Win32 process via the Desktop Bridge

In today’s post, we are covering another step you can take on your journey across the Desktop Bridge: specifically migrating business logic to Windows Runtime Components, aka WinRT Components. Previously, Windows only supported calling OS provided WinRT components from Win32 applications. Any attempt to call user-defined (aka 3rd party) WinRT components would fail because the Win32 application did not have package identity, and thus there was no way to register the component with the system at installation time, nor any way for the system to find the component at runtime.

This limitation is solved because Win32 applications on the Desktop Bridge now have identity and are registered with the OS, including any Windows Runtime Components that are part of the package. In the Windows 10 Fall Creators Update, the Desktop Bridge supports this functionality, including support for both In-Process Servers and Out-Of-Process Servers.

Code sharing – Why WinRT Components vs other options

There are many different ways to share code in your application, so what you choose depends upon your scenarios. At a high level, here are a few ways as they relate to UWP and the Desktop Bridge:

  • DLLs – for scenarios that require in-proc code performance and do not need cross-language interoperability
  • WinRT Components – for cross-language interoperability, or support out-of-process activation for reliability
  • .Net library – for scenarios that work in-proc and all clients are managed developers, including PCLs or .Net Standard libraries

Authoring new code or moving code into a Windows Runtime Component allows code reuse between the AppContainer and Win32 processes in the same package. While you can reuse existing DLLs in your AppContainer process by calling LoadPackageLibrary by moving to a Windows Runtime Component, you gain greater reusability because of better language interoperability (Native C/C++, managed code with C# & VB and Javascript) and Visual Studio integration across all your projects. Additionally, WinRT components support an out-of-process activation model that enables greater robustness for your app.

How does it work?

Because applications on the Desktop Bridge have a manifest, the registration entries for the WinRT Component are the same as you would use for a UWP application – by using the InProcessServer and OutOfProcessServer extensions. These extensions register the ActivatableClassId and its implementation binary with your package, so when your application attempts to activate the class, the system can find it.

In-Process Servers

This feature now allows developers to easily share code between Win32 apps and UWP apps running in AppContainer that can be loaded In-Proc. The component is built the same, e.g. Create a new WinRT Component project in VS, and the registration in the manifest is exactly the same as for UWP in-process servers. Because there is no manifest schema change required, developers can use existing toolsets in VS2015 or VS2017 to build In-Proc servers, but these solutions can only deploy to a machine running the latest flights of the Fall Creators Update.

Below is an example of an in-proc registration for a C++ WinRT Component, where CPPSimpleMathWinRT.dll is a native implementation of the SimpleMath class.


    <Extension Category="windows.activatableClass.inProcessServer">
      <InProcessServer>
        <Path>CPPSimpleMathWinRT.dll</Path>
        <ActivatableClass ActivatableClassId="SimpleMathWinRT.SimpleMath" ThreadingModel="both" />
      </InProcessServer>
    </Extension>

Below, you’ll see a simple Winforms Calculator sample that leverages a C++ WinRT Component for its math engine.

And this is what it looks like at runtime:

Sample with a C++/CX WinRT Component: https://github.com/Microsoft/DesktopBridgeToUWP-Samples/tree/master/Samples/WinFormsWinRTComponent

Sample with a C# WinRT Component: https://github.com/Microsoft/DesktopBridgeToUWP-Samples/tree/master/Samples/WinformsManagedWinRTComponent

Out-Of-Process servers

The registration of an OOP server for an application using the Desktop Bridge extensions is very familiar to developers who have registered servers before in UWP. However, there are details to clarify and limitations to be aware of. While OOP servers allow you to share code between your Win32 and AppContainer processes, there are limitations on sharing data between clients — that is reflected in the instancing model of the server. It all depends on your application’s needs as to which instancing model you should leverage.

The instancing behavior of a server is determined by the claims on the process token, specifically whether or not a call to NTCompareToken() for the calling process and a running instance of the server returns true. If they match, then existing instance of the server is used. If they are different, then a new instance of the server is started.

One of the key claims is the app identity. Apps in UWP are defined in the manifest and in most UWP applications submitted to the Store, there is only one App. But on the Desktop Bridge you can have more than one. Another key claim is the trust level of the calling process. On the Desktop Bridge, the package itself is declared with the runFullTrust capability, <rescap:Capability Name=”runFullTrust” />, which allows one or apps to be declared with the FullTrust entrypoint, EntryPoint=”Windows.FullTrustApplication”. Apps using the FullTrust entrypoint can call any API they want. Usually this is your main Win32/.Net executable. I’ll refer to these applications as FullTrust apps.

If you do not have this entrypoint, then the application is running in a lower trust level, called Base Trust, and has additional restrictions in a sandboxed environment called AppContainer, which is typical for an app when you create a UWP app in Visual Studio. These different trust levels result in different claims on the process tokens, and the result is a different instance of the server.  This model is called ActivateAsActivator, or AAA. An example of this registration is provided below, and you’ll note that it is the exactly same as what you’d provide for a UWP application; there is nothing new here for using this instancing model to access the server from your Win32 code:


    &amp;lt;Extension Category=&amp;quot;windows.activatableClass.outOfProcessServer&amp;quot;&amp;gt;
      &amp;lt;OutOfProcessServer ServerName=&amp;quot;Microsoft.SDKSamples.Kitchen.OvenServer&amp;quot; &amp;gt;
        &amp;lt;Path&amp;gt;Microsoft.SDKSamples.Kitchen.exe&amp;lt;/Path&amp;gt;
        &amp;lt;Instancing&amp;gt;singleInstance&amp;lt;/Instancing&amp;gt;
        &amp;lt;ActivatableClass ActivatableClassId=&amp;quot;Microsoft.SDKSamples.Kitchen.Oven&amp;quot; /&amp;gt;
      &amp;lt;/OutOfProcessServer&amp;gt;
    &amp;lt;/Extension&amp;gt;

While the ActivateAsActivator model allows you to share code, creating a separate instance of the server per client can be heavy weight. To mitigate this, UWP introduced a concept called ActivateAsPackage (AAP), which provides a single instancing behavior for servers in the package. This is reflected in the new attribute IdentityType=”activateAsPackage” on the <OutOfProcessServer> element.

There is a limitation in the AAP model however, as you must specify which trust boundary you want the server to run in. The server must be registered for use by the AppContainer processes, or for use by the FullTrust processes. If you want to use the server in both the FullTrust and AppContainer processes, you’ll need to build and register two servers with separate server names and class names, as those names need to be unique per package. To register the server for use by your FullTrust process, a new attribute RunFullTrust=”true” has been added. If you want the server to be used by your AppContainer processes, leave the attribute out.

Both new attributes are under the xmlns:uap5=”http://schemas.microsoft.com/appx/manifest/uap/windows10/5” namespace. An example registration is provided below showing both Win32 and UWP server registrations:

AAP Registration of server for use by Win32, aka FullTrust, processes:


    &amp;lt;Extension Category=&amp;quot;windows.activatableClass.outOfProcessServer&amp;quot;&amp;gt;
      &amp;lt;OutOfProcessServer ServerName=&amp;quot;Microsoft.SDKSamples.Kitchen.OvenServer&amp;quot; uap5:IdentityType=&amp;quot;activateAsPackage&amp;quot; uap5:RunFullTrust=&amp;quot;true&amp;quot;&amp;gt;
        &amp;lt;Path&amp;gt;Microsoft.SDKSamples.Kitchen.exe&amp;lt;/Path&amp;gt;
        &amp;lt;Instancing&amp;gt;singleInstance&amp;lt;/Instancing&amp;gt;
        &amp;lt;ActivatableClass ActivatableClassId=&amp;quot;Microsoft.SDKSamples.Kitchen.Oven&amp;quot; /&amp;gt;
      &amp;lt;/OutOfProcessServer&amp;gt;
    &amp;lt;/Extension&amp;gt;

AAP registration of server for use by UWP processes:


    &amp;lt;Extension Category=&amp;quot;windows.activatableClass.outOfProcessServer&amp;quot;&amp;gt;
      &amp;lt;OutOfProcessServer ServerName=&amp;quot;Microsoft.SDKSamples.Kitchen.OvenServerUWP&amp;quot; uap5:IdentityType=&amp;quot;activateAsPackage&amp;quot;&amp;gt;
        &amp;lt;Path&amp;gt;Microsoft.SDKSamples.KitchenUWP.exe&amp;lt;/Path&amp;gt;
        &amp;lt;Instancing&amp;gt;singleInstance&amp;lt;/Instancing&amp;gt;
        &amp;lt;ActivatableClass ActivatableClassId=&amp;quot;Microsoft.SDKSamples.Kitchen.OvenUWP&amp;quot; /&amp;gt;
      &amp;lt;/OutOfProcessServer&amp;gt;
    &amp;lt;/Extension&amp;gt;

The sample uses the AAP scenario and shows two C# Winforms apps using a OOP WinRT Component, resulting in only one instance of the server executable. The WinRT Component is a modified version of the WRLOutOfProcessWinRTComponent sample from the Universal Windows Samples on github. In this example, both client call the server and call the BakeBread() method. You’ll see from the TaskManager that there is only one instance of the Server.

GitHub link: https://github.com/Microsoft/DesktopBridgeToUWP-Samples/tree/master/Samples/WinformsOutOfProcessWinRTComponent

Visual Studio Support

It’s worth calling out a couple details and workarounds in projects created for this solution. First of all, Visual Studio currently does not allow you to add project references from a WinRT Component project to a Win32/.Net project.  You can work around this by unloading the Win32/.Net project and adding the project reference to the project file directly, e.g.:


  &amp;lt;ItemGroup&amp;gt;
    &amp;lt;ProjectReference Include=&amp;quot;..ServerWRLOutOfProcessWinRTComponent_server.vcxproj&amp;quot; /&amp;gt;
  &amp;lt;/ItemGroup&amp;gt;

While this adds the reference, you will see a warning in Visual Studio, as this was not previously supported by the OS. We are working with Visual Studio to improve this in a future release, but for now you can ignore the warning.

Second, the samples are using a UWP JavaScript project to handle the app packaging. This technique is noted in the Desktop Bridge Packaging with Visual Studio documentation, and works as a reasonable solution until Visual Studio adds future support. The benefit of this approach is that you can add a reference from your WinRT component to the JavaScript project, and then the Visual Studio build system adds appropriate registrations for package dependencies, including VCLibs and .NetNative, as well as the <InProcessServer> extensions. Visual Studio does not support adding registrations for <OutOfProcessServer> registrations, so you’ll need to add those manually to the manifest

Metadata Based Marshaling – No more Proxy/Stub DLLs!

Finally, in the <OutOfProcessServer> example, we take advantage of the Metadata Based Marshalling feature (MBM) that was introduced in the Windows 10 Anniversary Update (Windows 10 version 1607). This feature has not gotten much attention, but it means that WinRT Component developers do not need to author a proxy/stub class, saving them time and tedious work. This is possible because the WinMD is deployed with the application, and thus the system can identify and marshal the types cross-process for the developer. You will notice that the server code in this example does not include the proxy project nor binaries.

Conclusion

With Windows Runtime Components and the Desktop Bridge, developers can take another step on their journey to migrate business logic to UWP. Windows Runtime Components provide code re-use that can work with either FullTrust processes or UWP processes, and they allow greater interop cross language.

For more information on the Desktop Bridge, please visit the Windows Dev Center.

Ready to submit your app to the Windows Store? Let us know!

Command-Line Activation of Universal Windows Apps

As we continue to close the gap between Win32 and Universal Windows Apps, one of the features we’ve recently introduced is the ability to activate a UWA from a command line and pass the app arbitrary command-line arguments. This is available to Insiders from build 16226.

This feature builds on the App Execution Alias extension already available for Desktop Bridge apps. To use this feature in a UWA, there are two key additions to your app:

  • Add an appExecutionAlias extension to your app manifest.
  • Override OnActivated and handle the incoming arguments.

For the manifest entry, you first need to declare the XML namespace for the AppExecutionAlias element:


&amp;lt;Package
  xmlns=&amp;quot;http://schemas.microsoft.com/appx/manifest/foundation/windows10&amp;quot;
  xmlns:mp=&amp;quot;http://schemas.microsoft.com/appx/2014/phone/manifest&amp;quot;
  xmlns:uap=&amp;quot;http://schemas.microsoft.com/appx/manifest/uap/windows10&amp;quot;
  xmlns:uap5=&amp;quot;http://schemas.microsoft.com/appx/manifest/uap/windows10/5&amp;quot; 
  IgnorableNamespaces=&amp;quot;uap mp uap5&amp;quot;&amp;gt;

The AppExecutionAlias is declared as an Extension within your Application. This is quite simple and almost the same as for a Desktop Bridge app:


&amp;lt;Application ...&amp;gt;
      
  &amp;lt;Extensions&amp;gt;
      &amp;lt;uap5:Extension 
        Category=&amp;quot;windows.appExecutionAlias&amp;quot; 
        Executable=&amp;quot;MyCompany.Something.Another.exe&amp;quot; 
        EntryPoint=&amp;quot; MyCompany.Something.Another.App&amp;quot;&amp;gt;
        &amp;lt;uap5:AppExecutionAlias&amp;gt;
          &amp;lt;uap5:ExecutionAlias Alias=&amp;quot;MyApp.exe&amp;quot; /&amp;gt;
        &amp;lt;/uap5:AppExecutionAlias&amp;gt;
      &amp;lt;/uap5:Extension&amp;gt;
  &amp;lt;/Extensions&amp;gt;

&amp;lt;/Application&amp;gt;

The Executable is the name of your UWA app EXE, and the EntryPoint is the fully qualified name of your App class. The ExecutionAlias is the name that users will type in at the command-line: This can be any arbitrary name, and it must end with “.exe.” You should choose a meaningful alias that you can reasonably expect the user to associate with your app. Note that if you choose an alias that conflicts with an app that is already installed, your alias won’t be used. Similarly, if your app is installed first, and then the user installs another app later that declares the same alias – then your app will take precedence. The rule here is that the first one wins.

The manifest entry is obviously the same for VB and C++ projects, but for a JavaScript web app, it’s slightly different. Instead of Executable, you specify a StartPage, and you don’t specify EntryPoint at all:


&amp;lt;Extensions&amp;gt;
    &amp;lt;uap5:Extension 
      Category=&amp;quot;windows.appExecutionAlias&amp;quot; 
      StartPage=&amp;quot;index.html&amp;quot;&amp;gt;
      &amp;lt;uap5:AppExecutionAlias&amp;gt;
        &amp;lt;uap5:ExecutionAlias Alias=&amp;quot;MyApp.exe&amp;quot; /&amp;gt;
      &amp;lt;/uap5:AppExecutionAlias&amp;gt;
    &amp;lt;/uap5:Extension&amp;gt;
&amp;lt;/Extensions&amp;gt;

For the OnActivated override, the first thing to do is to check the ActivationKind – this is standard practice if your app supports multiple activation kinds (file associations, custom protocols and so on). In this scenario, if the ActivationKind is CommandLineLaunch, the incoming IActivatedEventArgs will be an object of type CommandLineActivatedEventArgs. From this, you can get the CommandLineActivationOperation, and from this in turn, you can get the Arguments string. You also get the CurrentDirectoryPath, which is the directory current when the command-line activation request was made. This is typically not the install location of the app itself, but could be any arbitrary path.


async protected override void OnActivated(IActivatedEventArgs args)
{
    switch (args.Kind)
    {
        case ActivationKind.CommandLineLaunch:
            CommandLineActivatedEventArgs cmdLineArgs = 
                args as CommandLineActivatedEventArgs;
            CommandLineActivationOperation operation = cmdLineArgs.Operation;
            string cmdLineString = operation.Arguments;
            string activationPath = operation.CurrentDirectoryPath;

It’s important to remember that the command-line arguments are supplied by the caller, which means that you have no control over them. You should treat these arguments as untrustworthy and parse them very carefully. They might not have any malicious intent, but they could easily be badly formed, so you need to allow for this.

After the initial checks, you can create a window as normal, and optionally pass in the (parsed and validated) command-line arguments – or some data extracted from the arguments – to that window.


            Frame rootFrame = Window.Current.Content as Frame;
            if (rootFrame == null)
            {
                rootFrame = new Frame();
                Window.Current.Content = rootFrame;
            }
            rootFrame.Navigate(typeof(MainPage), 
                string.Format(&amp;quot;CurrentDirectory={0}, Arguments={1}&amp;quot;,
                activationPath, cmdLineString));
            Window.Current.Activate();

Finally, in your page’s OnNavigatedTo, you can retrieve the payload from the event args, and use the information in any way you like:


protected override void OnNavigatedTo(NavigationEventArgs e)
{
    string cmdLineString = e.Parameter as string;
}

When you build and run the app on your dev machine – or when the end user installs your app – the  alias is registered. From that point, the user can go to a command line and activate your app.

Note that by “command line,” we mean any common command line mechanism such as cmd.exe,  powershell.exe, Windows-R and so on. Here’s a slightly more sophisticated example in which the app implements a custom parser to construct command-payload tuples from the command-line arguments:


protected override void OnActivated(IActivatedEventArgs args)
{
    switch (args.Kind)
    {
        case ActivationKind.CommandLineLaunch:
            CommandLineActivatedEventArgs cmdLineArgs = 
                args as CommandLineActivatedEventArgs;
            CommandLineActivationOperation operation = cmdLineArgs.Operation;
            string cmdLineString = operation.Arguments;
            string activationPath = operation.CurrentDirectoryPath;

            Frame rootFrame = Window.Current.Content as Frame;
            if (rootFrame == null)
            {
                rootFrame = new Frame();
                Window.Current.Content = rootFrame;
            }

            ParsedCommands parsedCommands = 
                CommandLineParser.ParseUntrustedArgs(cmdLineString);
            if (parsedCommands != null &amp;amp;&amp;amp; parsedCommands.Count &amp;gt; 0)
            {
                foreach (ParsedCommand command in parsedCommands)
                {
                    switch (command.Type)
                    {
                        case ParsedCommandType.SelectItem:
                            rootFrame.Navigate(typeof(SelectItemPage), command.Payload);
                            break;
                        case ParsedCommandType.LoadConfig:
                            rootFrame.Navigate(typeof(LoadConfigPage), command.Payload);
                            break;
                        case ParsedCommandType.Unknown:
                            rootFrame.Navigate(typeof(HelpPage), cmdLineString);
                            break;
                    }
                }
            }
            else
            {
                rootFrame.Navigate(typeof(MainPage));
            }

            Window.Current.Activate();
            break;
    }
}

The app’s logic uses these more structured commands to navigate to different pages and handle the payload in different ways. The point is that you can define whatever argument options and payload rules you like in your app.

A common scenario is testing: You can activate your app with a defined set of values for each test run – for example, to start on a particular page with boundary values set for key items – or to start a game at a particular level, with values set for player attributes, enemy count, damage levels, fuel and weaponry and so on.

If the data you provide is too long or too complex for command-line arguments, you can supply a filename on the command-line which the app can then load. One option is to include such files as content in your package (and most likely strip them out before building your release build). You can also create the files at any time later, so long as you put them in a location to which the app has access. If you want to avoid showing any filepicker UX in your app, the simplest option is to put the files in the install location for the app, which would be somewhere like %userprofile%AppDataLocalPackages<Package ID>LocalState.

You should also allow for incoming arguments that are badly formed or otherwise unrecognized:

And a reasonable UX here would be to navigate to a page where you show the user the correct usage options:

Also, bear in mind that the UWP platform has a single-instance app model. This means that your app can be running, and you can then continue to execute command-line activation requests at any point thereafter. Each activation will result in a call into OnActivated. This is unlikely to be useful in end-user scenarios of course – but it can be a useful debugging/profiling strategy during development.

Command-line activation of UWAs is just one example of how we’re gradually closing the gaps between traditional Win32 development and UWA development. This feature brings you yet another missing piece from the old world that you can now leverage in your modern apps.

Calling Windows 10 APIs From a Desktop Application

In today’s post, we’re covering how PC software can leverage the rich functionality of Windows 10. This is valuable background for the upcoming post “Adding UWP Features to Your Existing PC Software with the Desktop Bridge,” which will go into even more detail on the topic in the coming days.

So here’s a question that generates a lot of confusion. Can PC software written in WPF, WinForms or MFC access the Windows 10 APIs used by the Universal Windows Platform (UWP)?

The answer is yes. There are some exceptions to this rule (and we’ll go over how to find them), but in general you can access the Windows 10 APIs. Or put a different way, there are no secret APIs being kept away from Windows developers.

How to access the Windows 10 APIs from WPF

You can access the Windows 10 APIs from a pre-existing WPF project. To do so, go to your Solution Explorer window and …

  1. Right click on References. Select “Add Reference…” from the context menu. On the left of the Reference Manager, choose Browse and find the following file: C:Program Files (x86)Windows Kits10UnionMetadatawinmd. Add it to your project as a reference. Note: You will need to change the filter to “All Files”.
  1. Right click on References. Select “Add Reference…” from the context menu. On the left of the Reference Manager, go to Browse and find the directory “C:Program Files (x86)Reference AssembliesMicrosoftFramework.NETCorev4.5”. Add Runtime.WindowsRuntime.dll to your project.

Let’s say I want to make my WPF application location aware by calling on the Geolocator class in the Windows 10 Windows.Devices.Geolocation API. I can now do this and even use the asynchronous pattern common in UWP. Classes and methods I commonly think of as UWP code are now interweaved with classes and methods from WPF. In the example show below, I take my latitude and longitude from Geolocator and display it in a WPF MessageBox.


private async void Button_Click(object sender, RoutedEventArgs e)
{
    var locator = new Windows.Devices.Geolocation.Geolocator();
    var location = await locator.GetGeopositionAsync();
    var position = location.Coordinate.Point.Position;
    var latlong = string.Format(&amp;quot;lat:{0}, long:{1}&amp;quot;, position.Latitude, position.Longitude);
    var result = MessageBox.Show(latlong);
}

How do I know which APIs are available?

As mentioned above, there are exceptions to the rule that Windows 10 APIs are accessible from PC software. The first big exception concerns XAML UI APIs. The XAML framework in UWP is different from the one in WPF and you really don’t want to be mixing them up, anyways.

The second set of APIs that you can’t use are ones that depend on an app’s package identity. UWP apps have package identities while PC software does not. Package identity information can be found in the app manifest file.

How do you determine which Windows 10 APIs require a package identity and which do not? The easiest way is to refer to this MSDN topic.

Unlocking even more APIs

There’s actually a way to provide PC software with a package identity. The Desktop Bridge lets you package PC software for deployment in the Windows Store. As part of this process, you create an app manifest file for it, effectively giving it a package identity.


&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;
&amp;lt;Package xmlns=&amp;quot;http://schemas.microsoft.com/appx/manifest/foundation/windows10&amp;quot; 
         xmlns:uap=&amp;quot;http://schemas.microsoft.com/appx/manifest/uap/windows10&amp;quot;     
    &amp;lt;Identity Name=&amp;quot;YOUR-APP-GUID-90cd-a7cdf2e0a180&amp;quot; 
              Publisher=&amp;quot;CN=YOUR COMPANY&amp;quot; 
              Version=&amp;quot;1.x.x.x&amp;quot; /&amp;gt;
&amp;lt;/Package&amp;gt;

If you package your PC software for the Windows Store using Desktop Bridge, then most of the APIs you couldn’t previously use, because they require a package identity, will be available to you. APIs that depend on CoreWindow will still be a problem. However, once you have a desktop bridge package, you can add a UWP component (that runs in a separate app container process), and call literally any UWP API from there.

A quicker way to get at those Windows 10 APIs

But say you don’t want to deploy to the Windows Store at the moment and just want to use some of those Windows 10 APIs. How do you get to them from your app?

There’s a NuGet package for that. It’s called UwpDesktop and is written by Vladimir Postel and Lucian Wischik. If you want to examine the source code, it is maintained on GitHub.

For demonstration purposes, let’s build a console app based on a 2012 article by Scott Hanselman on using WinRT APIs (partly to show how much easier it is to do today). After creating a new desktop console application, insert the original code from 2012 into the Main method in Program.cs.


    static void Main(string[] args)
        {
            LightSensor light = LightSensor.GetDefault();
            if (light != null)
            {
                uint minReportInterval = light.MinimumReportInterval;
                uint reportInterval = minReportInterval &amp;gt; 16 ? minReportInterval : 16;
                light.ReportInterval = reportInterval;

                light.ReadingChanged += (s, a) =&amp;gt;
                {
                    Console.WriteLine(String.Format(&amp;quot;There was light! {0}&amp;quot;, a.Reading.IlluminanceInLux));
                };
            }

            while (Console.ReadLine() != &amp;quot;q&amp;quot;) { }

        }

This code sadly will not compile because .NET 4.5 doesn’t know what the LightSensor class is, as shown below.

Here’s how we fix that. Install the UWPDesktop package to your project using the NuGet Package Manager.

Back in Program.cs, add the following using directive to the top of the file:


using Windows.Devices.Sensors;

Next … well, actually that’s all it took. The app works now (assuming you have a light sensor attached to your computer).

And that’s the quick way to go about using Windows 10 APIs in a managed app.

How to access the Windows 10 APIs from C++

Calling Window 10 APIs isn’t just for managed code. You’ve also always been able to call them from C++ native apps.

Start by creating a new C++ Win32 application project. Alternatively, open a pre-existing C++ windows application project. Right click on your project and select Properties to bring up the configuration window. There are just four steps required to configure your application to make Windows 10 API calls.

  • Select the Configuration Properties > C/C++ > General node in the left pane. Set the Consume Windows Runtime Extension property to Yes.

  • In the same window, edit the Additional #using Directories property, adding the following entries:
    • C:Program Files (x86)Microsoft Visual Studio 14.0VCvcpackages;
    • C:Program Files (x86)Windows Kits10UnionMetadata;
    • C:Program Files (x86)Windows Kits10ReferencesWindows.Foundation.UniversalApiContract1.0.0.0;
    • C:Program Files (x86)Windows Kits10ReferencesWindows.Foundation.FoundationContract1.0.0.0;

  • Select the Configuration Properties > C/C++ > Code Generation node in the left pane. Set the Enable Minimal Rebuild property to No.

  • Last of all, select the Configuration Properties > General node and pick your Target Windows 10 version. Click OK to save your configuration settings.

Now you can start calling Windows APIs. Let’s finish off this app with something easy – calling the Launcher API from the C++ menubar.

Add the following using directives to the top of your project’s main CPP file:


using namespace std;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::System;
Include the header ROApi.h in your stdafx.h file.
// C RunTime Header Files
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;malloc.h&amp;gt;
#include &amp;lt;memory.h&amp;gt;
#include &amp;lt;tchar.h&amp;gt;

// TODO: reference additional headers your program requires here
#include &amp;quot;ROApi.h&amp;quot;
Initialize Windows::Foundation in your program’s entry point.
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: Place code here.
    Windows::Foundation::Initialize();
}

Initialize Windows::Foundation in your program’s entry point.


int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: Place code here.
    Windows::Foundation::Initialize();
}

By default the Help menu only has one entry for About, so you will need to add a new button. Define the button in your Resource.h file:

#define IDM_SETTINGS  106

Then edit the *.rc file to add a new button for settings, in order to launch the Windows 10 Settings app.


IDC_HELLOWORLDWIN32TOUWP MENU
BEGIN
    POPUP &amp;quot;&amp;amp;File&amp;quot;
    BEGIN
        MENUITEM &amp;quot;E&amp;amp;xit&amp;quot;,           IDM_EXIT
    END
    POPUP &amp;quot;&amp;amp;Help&amp;quot;
    BEGIN
        // add settings item to help menu around Line 47
        MENUITEM &amp;quot;&amp;amp;Settings ...&amp;quot;,   IDM_SETTINGS
        MENUITEM &amp;quot;&amp;amp;About ...&amp;quot;,      IDM_ABOUT

    END
END

Finally, override the callbacks for the menubar buttons to make them call the Windows 10 Launcher instead of whatever they are supposed to do.


LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
    {
        int wmId = LOWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        {
        case IDM_SETTINGS:
            Launcher::LaunchUriAsync(ref new Uri(L&amp;quot;ms-settings://&amp;quot;));
            break;
        case IDM_ABOUT:
            Launcher::LaunchUriAsync(ref new Uri(L&amp;quot;https://blogs.windows.com/buildingapps//&amp;quot;));
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
    }
    break;
    }
}

Clicking on Help > About will bring up the Windows 10 Settings app, while clicking on File > Exit will bring you to this blog (admittedly not a good design, but it makes its point).

Let’s go one level deeper. There are many C++ applications and games out there that use alternative build tools and alternative build processes. Many of them continue to target older versions of Windows because this is what their customers are using. How can these application developers gradually move over to the Windows 10 APIs without abandoning their Windows 7 clients?

Reusing the same steps above for building a Windows executable, one could build a DLL to encapsulate any Windows 10 calls one might need, isolating them from the rest of the application. Let’s call this new DLL UWPFeatures.dll.


void Game::UpdateTile(int score, int hiScore)
{
    HINSTANCE hinstLib;
    UPDATETILE UpdateTileProc;
    BOOL fFreeResult;

    hinstLib = LoadLibrary(TEXT(&amp;quot;UWPFeatures.dll&amp;quot;));
    if (NULL != hinstLib)
    {
        UpdateTileProc = (UPDATETILE)GetProcAddress(hinstLib, &amp;quot;UpdateTile&amp;quot;);
        if (NULL != UpdateTileProc)
        {
            (UpdateTileProc)(score, hiScore);
        }
        fFreeResult = FreeLibrary(hinstLib);
    }
}

Then in the original application, method calls should check to see if the UWPFeatures.dll is packaged with the application (which will be true for Windows 10 installs). If it is present, it can be loaded dynamically and called. If it isn’t present, then the original call is made instead. This provides a quick pattern for not only accessing the Windows 10 APIs from pre-existing C++ games and applications, but also for doing it in a way that doesn’t require heavy reworking of the current base code.

Wrapping up

It has sometimes been claimed that Windows 10 has secret APIs that are only accessible through UWP apps. In this post, we demonstrated that this is not the case and also went over some of the ins and outs of using Windows 10 APIs in both managed and native desktop apps. You will find links below to even more reference materials on the subject.

Did you find this post helpful? Please let us know in the comments below—and also let us know if there’s anything else you’d like us to dig into for you about this topic.

Want to go a step further? Be sure to come back next week for our next blog, where we go into more detail about adding a UWP feature to your existing PC software with the Desktop Bridge.

Welcoming Developers to Windows 10

Today, I had the honor of speaking to thousands of our development partners at the Build conference about our plans to make Windows 10 the most attractive development platform ever. It is always thrilling to see so many developers excited about Microsoft – and this year, about Windows 10. If you weren’t able to attend or watch it live, you can watch the keynote here later this afternoon once it’s posted.

Windows 10 on One Billion Devices

Today we shared our bold goal –to see Windows 10 on one billion devices within two to three years of Windows 10’s availability – the first platform version, in any ecosystem, to be available on one billion devices. We will accomplish this by delivering Windows 10 with a free upgrade offer, making it easy for customers and businesses to upgrade quickly, and with great new devices (which we haven’t discussed yet ).

Windows 10 Device Family

Windows Store for Consumers, Businesses, and Developers

Today, we shared more details on what the Windows Store will offer to end-users, businesses, and developers. Developers will be able to write an application once and distribute it to the entire Windows 10 device family, making discovery, purchasing and updating easy for customers.

For end-users, apps in the Windows Store will install and uninstall easily, and the Store will support a range of global payment methods on all Windows devices – including the largest carrier billing footprint of any ecosystem, supporting 90 carriers, to help people around the world who don’t have credit cards, but do have phones.

For businesses, the Windows Store enables admins to highlight apps for their employees, distribute select apps from the Windows Store and private line-of-business apps to their employees, and use business payment methods like purchase orders.

For developers, we announced several new capabilities coming to Windows 10:

  1. Carrier billing across all Windows 10 devices, which from our phone experience, increases purchases in emerging markets by 8x
  2. Updated Windows 10 Microsoft Advertising SDK with support for video ads and install tracking
  3. In-app purchase subscription support
  4. New Windows Store Affiliate Program

Windows Store in Windows 10.

Universal Windows Platform Innovation

With the Universal Windows Platform, developers can now create a single application for the full range of Windows 10 devices. The platform’s UX controls automatically adapt to different screen sizes, and the developer can then tailor applications to unique capabilities of each device. The platform enables developers to integrate Cortana and Xbox Live into their applications, offer trusted commerce, embrace natural user input, create holograms, and more.

The Universal Windows Platform enables Continuum. Previously, we’ve demonstrated how Universal Windows apps and the Windows shell transition seamlessly between tablet and PC modes. Today, we showed how Universal Windows apps and Continuum for phones enables a screen to become like a PC.*

The Universal Windows Platform enables applications to become holograms. Today we shared our progress over the last 100 days since announcing Microsoft HoloLens – the world’s first, and only, fully untethered holographic computer powered by Windows 10. Today, we shared how HoloLens is helping Trimble and its customers visualize building designs in the context of real world objects and landscapes, giving them the ability to walk around designs while clients view them remotely and see street side how a building is going to look. And how medical students at Case Western Reserve University and Cleveland Clinic learn procedures without ever picking up a scalpel!

Many partners are building amazing apps on the Universal Windows Platform. Today, we demoed USA Today and WeChat. Other partners onboard include Disney, Netflix, and King to name just a few.

Partners developingg Universal Windows apps

Windows 10 Welcomes All Developers and Their Code

Windows has always embraced a variety of technologies to build apps. At Build last year, we detailed our support for open source and popular middleware partners, open sourced .NET, and announced native Cordova support in Visual Studio.

Today, we announced four new SDKs, enabling developers to start with an existing code base, integrate with the Universal Windows Platform capabilities, and then distribute their new application through the Windows Store to the one billion Windows 10 devices. The code bases enabled by these SDKs are:

  1. Web sites
  2. .NET and Win32
  3. Android Java/C++
  4. iOS Objective C

Today, we announced that Adobe will bring their Photoshop Elements and Premier Elements apps to the Windows Store, leveraging the new SDK for Win32 applications. We look forward to more of the current 16 million Win32 applications growing their distribution through the Windows Store.

Today, we also shared that King has already used the Objective C SDK to bring Candy Crush Saga to Windows Phone. The app came to market quickly with very few code modifications, and has earned a 4.5 average rating.

New tools for developers to integrate with the Universal Windows Platform capabilities

Microsoft Edge

Today we announced the name of our new browser, Microsoft Edge. We chose the name Microsoft Edge as it reflects our commitment to developers to deliver a browser that lives at the edge of modern web standards and security. Microsoft Edge is a browser built for doing, with built-in note taking and sharing; a reading pane for no distractions; and integration with Cortana. We showcased how Microsoft Edge will offer developers better discoverability of their apps and our plans for future extensibility with JavaScript and HTML. You can see more about Microsoft Edge in this video.

Begin Developing Today!

We’re excited that we’re well on our way to making Windows 10 available this summer. Most of the features that we have shared today will be available at launch; others will roll out later this year. The beauty of launching Windows 10 as a service means we can deliver new technology as soon as it is ready.

New tools for Universal Windows app development will be available later today at this location. I welcome you to join the Windows Insider Program to get the latest tech previews of Windows 10 as they become available, including the latest build for PCs, which will also be available later today.

I’m excited to see what you create!

*Hardware requirements will apply.