4

I would like to use my MAUI app to launch a separate background service on the platform that it's running on. This background service makes use of gRPC to receive data from a server when the MAUI app itself is not running. I understand that it's highly platform-dependent, so for the sake of argument, let's pretend we're doing this exclusively on Windows.

My strategy was to include the background service .exe with the .MSIX being used to install the app on the computer by simply adding the .exe to the Platform/Windows folder so that it deploys with the app. However, I can't use C# to find out where that .exe file is. WPF has a "special" folder that directs me to the Program Files folder on any system, and then C# would launch that .exe as a Windows Service. I can't find MAUI's equivalent, since MAUI's FileSystem class does not allow this.

Maybe my strategy is not the correct one. What is a good strategy for deploying background services with a MAUI app, if not this one?

Thanks!

The Don
  • 343
  • 2
  • 13
  • 1
    Does this help? https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/invoke-platform-code – Dan Friedman Jun 26 '22 at 16:10
  • @DanFriedman Thank you for your response. Not quite -- the issue is being able to find and launch a .exe file in the same directory as the app, or launch a background service that works even when the app is closed. – The Don Jun 27 '22 at 11:31
  • Just to clarify, my thought was that if you could do it with WPF, then maybe being able to use platform specific code might allow you to access the APIs that you need (that are outside of MAUI's FileSystem). Sorry if it doesn't help, I haven't tried this. – Dan Friedman Jun 27 '22 at 14:39
  • Understandable, although MAUI apps install in a different directory that's locked to the end-user even with elevated privileges. So even if I could use the platform-specific code, it probably wouldn't let me access the .exe for the background service. – The Don Jun 27 '22 at 15:40

1 Answers1

3

First off:

I understand that it's highly platform-dependent,

This is the case but, surprisingly...

It is possible to add a Windows service that is also installed when installing the MSIX.

First off you want to add a project to your solution, because the Maui application as off this writing does not run natively without a bunch of trouble. So lets say you another project using the net6.0 console application template. Then add a main function looking like this:

// See https://aka.ms/new-console-template for more information
using static System.Net.Mime.MediaTypeNames;
using System.Diagnostics;

namespace AppService
{
    static class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            if (args[0] == "/service")
            {
                // Service logic
            }
        }
    }
}

Make sure to set the startup object to AppService.Program

Now add the added project as a project reference in the MAUI project.

Maui requires all added project to be self-contained so you need to add this to the csproj of the AppService project.

<SelfContained>True</SelfContained>
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>

Now to make sure the Service is installed you need to add some instructions to the Package.appxmanifest. This file is found in the Maui platform specific folder.

Add the namespace to the Package element:

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

Add the service details to the Application element:

  <Extensions>
    <desktop6:Extension
      Category="windows.service"      
      Executable="AppService.exe"
      EntryPoint="AppService.Program">
      <desktop6:Service
        Name="AppManager"
        StartupType="auto"
        StartAccount="localSystem"
        Arguments="/service"
      >
      </desktop6:Service>
    </desktop6:Extension>
  </Extensions>

Add the required capabilities to the Capabilities element:

  <Capabilities>
    <rescap:Capability Name="runFullTrust" />
    <rescap:Capability Name="allowElevation" />
    <rescap:Capability Name="packagedServices" />
    <rescap:Capability Name="localSystemServices" />
  </Capabilities>

And that is it.

Funonly
  • 818
  • 1
  • 8
  • 22
  • This is great, Thank you! Is there any literature or a good reference that I can read on this subject? I would like to learn more on the explanation behind this solution. – The Don Aug 25 '22 at 12:13
  • 1
    @TheDon I got this solution pasted from very small bits and pieces and some good old trial and error. Couldn't find any tutorials or instructions. When I started on this I first found your question so just figured I paste here what worked from me. So I mean the only real links I can recommend is: The [MSIX package manifest schema reference](https://learn.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/schema-root) And the Maui docs, but this holds nothing specific. The Installer docs is embarrassingly short. – Funonly Aug 26 '22 at 08:12