Jump to content
Microsoft Windows Bulletin Board

Making the app single-instanced (Part 3)


Guest Jingwei Zhang, Program Manager

Recommended Posts

Guest Jingwei Zhang, Program Manager
Posted

Single-instanced apps only allow one instance of the app running at a time. WinUI apps are multi-instanced by default. They allow you to launch multiple instances of the same app at one time, which we call multiple instances. However, you may implement single-instancing based on the use case of your app. Attempting to launch a second instance of a single-instanced app will only result in the first instance’s main window being activated instead. This tutorial demonstrates how to implement single-instancing. By the end of this section, you will be able to: 1. Turn off XAML’s generated Program code 2. Define customized MAIN method for redirection 3. Test single-instancing via app deployment

[HEADING=2]Turn off XAML’s generated Program code[/HEADING]

We need to check for redirection as early as possible, and before creating any windows. To do this, we must define the symbol “DISABLE_XAML_GENERATED_MAIN” in the project build properties.

  1. Double-click on the project name in Solution Explorer:
  2. Define the DISABLE_XAML_GENERATED_MAIN symbol below

DrumPad:

 

DISABLE_XAML_GENERATED_MAIN

 

 

DISABLE_XAML_GENERATED_MAIN

 

 

DISABLE_XAML_GENERATED_MAIN

 

 

DISABLE_XAML_GENERATED_MAIN

 

 

DISABLE_XAML_GENERATED_MAIN

 

 

DISABLE_XAML_GENERATED_MAIN

 

[HEADING=2]Define a customized Program class with a Main method[/HEADING]

A customized Program.cs file is created instead of running the default Main method because it enables the app to check for redirection, which is not what WinUI apps default to doing.

  1. Navigate to Solution Explorer -> Right-click on the project name -> Add -> New Item
  2. Under Visual C# Items -> Code -> Class -> Name it Program.cs -> Add

NOTE: Your project should look like this: Picture1.png-BLOG-3.thumb.png.5ba017cfe5caed3a8b3360c12d708fe6.png 3. Add the following namespaces: Program.cs:

using System.Threading;

using Microsoft.UI.Dispatching;

using Microsoft.Windows.AppLifecycle;

using Windows.ApplicationModel.Activation;

using Windows.Storage;

4. Replace the empty class Program with following: Program.cs:

{

[sTAThread]

static async Task Main(string[] args)

{

WinRT.ComWrappersSupport.InitializeComWrappers();

bool isRedirect = await DecideRedirection();

if (!isRedirect)

{

Microsoft.UI.Xaml.Application.Start((p) =>

{

var context = new DispatcherQueueSynchronizationContext(

DispatcherQueue.GetForCurrentThread());

SynchronizationContext.SetSynchronizationContext(context);

new App();

});

}

 

return 0;

}

}

NOTE: Main determines if it should redirect or launch a new app instance via DecideRedirection(); 5. Define DecideRedirection() below the Main method: Program.cs:

private static async Task DecideRedirection()

{

bool isRedirect = false;

AppActivationArguments args = AppInstance.GetCurrent().GetActivatedEventArgs();

ExtendedActivationKind kind = args.Kind;

AppInstance keyInstance = AppInstance.FindOrRegisterForKey("randomKey");

 

if (keyInstance.IsCurrent) {

keyInstance.Activated += OnActivated;

}

else {

isRedirect = true;

await keyInstance.RedirectActivationToAsync(args);

}

return isRedirect;

}

 

NOTE: DecideRedirection determines if the app has been registered by registering a key that represents your app instance. Based on the result of key registration, it infers if there is a current app instancing running; therefore, whether or not to redirect or allow the app to launch for the first time 6. Define the helper method OnActivated(), below the DecideRedirection method: Program.cs:

private static void OnActivated(object sender, AppActivationArguments args)

{

ExtendedActivationKind kind = args.Kind;

}

[HEADING=2]Testing single-instancing via app deployment[/HEADING]

Up until now, we have been testing our app by running the solution debugger. We can only have one debugger running at once. Therefore, it prevents us from knowing whether the app is single-instanced because we can’t debug the same project solution twice at the same time. To test, we will deploy the application. After deploying, we can launch the app from the desktop like how you would with Microsoft Word.

  1. Navigate to Solution Explorer -> Right-click on the project name -> Deploy
  2. Open the start menu and click on the search field
  3. Type “DrumPad” (or your app’s name) in the search field
  4. Click on the app icon from the search result to launch the app
  5. Repeat steps 2 to 4 to launch the same app again and see if another instance pops up

[HEADING=2]Result[/HEADING]

Picture2.gif-BLOG-3.thumb.gif.84644da7c16aeab62c457ec9f593ff4f.gif

[HEADING=2]Wrapping up[/HEADING]

  • In part 1, we learned how to use WinUI 3 controls to create the app’s visual layer.
  • In part 2, we introduced the concepts of dark mode and windowing.
  • In part 3, we enforced single-instancing for our app.

All the code we have covered from the blog series is on GitHub, with branches for the different steps. The main branch is the most comprehensive. The other branches are intended to show you how the app architecture evolved.

[HEADING=2]Further learning[/HEADING]

Here are some links to check out with resources on building for WinUI 3 apps with WinAppSDK. Don’t stop learning! More examples:

Official documentation:

Now that you have the basic app built, you can easily add other controls from the WinUI 3 Controls Gallery and experiment other cool WinAppSDK features to enhance your Windows apps!

 

Continue reading...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...