Edit

Share via


Using winapp CLI with .NET

Note

This guide works for most .NET project types. The steps have been tested with both console and UI-based projects like WPF.

This guide demonstrates how to use the winapp CLI with a .NET application to debug with package identity and package your application as an MSIX.

Package identity is a core concept in the Windows app model. It allows your application to access specific Windows APIs (like Notifications, Security, AI APIs, etc.), have a clean install/uninstall experience, and more.

Prerequisites

  1. .NET SDK: Install the .NET SDK:

    winget install Microsoft.DotNet.SDK.10 --source winget
    
  2. winapp CLI: Install the winapp tool via winget:

    winget install Microsoft.winappcli --source winget
    

1. Create a new .NET app

Start by creating a simple .NET console application:

dotnet new console -n dotnet-app
cd dotnet-app

Run it to make sure everything is working:

dotnet run

2. Update code to check identity

First, update your project file to target a specific Windows SDK version. Open dotnet-app.csproj and change the TargetFramework:

<TargetFramework>net10.0-windows10.0.26100.0</TargetFramework>

Now replace the contents of Program.cs:

using Windows.ApplicationModel;

try
{
    var package = Package.Current;
    var familyName = package.Id.FamilyName;
    Console.WriteLine($"Package Family Name: {familyName}");
}
catch (InvalidOperationException)
{
    Console.WriteLine("Not packaged");
}

3. Run without identity

dotnet run

You should see "Not packaged".

4. Initialize project with winapp CLI

The winapp init command automatically detects .csproj files and runs a .NET-specific setup:

winapp init

When prompted:

  • Package name: Press Enter to accept the default
  • Publisher name: Press Enter to accept the default or enter your name
  • Description: Press Enter to accept the default or enter a description
  • Version: Press Enter to accept 1.0.0.0
  • Entry point: Press Enter to accept the default (dotnet-app.exe)
  • Windows App SDK setup: Select Stable, Preview, or Experimental

This command:

  • Updates the TargetFramework in your .csproj to a supported Windows TFM (if needed)
  • Adds Microsoft.WindowsAppSDK and Microsoft.Windows.SDK.BuildTools NuGet package references
  • Creates appxmanifest.xml and Assets folder for your app identity

Note

Unlike native/C++ projects, the .NET flow does not create a winapp.yaml file. NuGet packages are managed directly via your .csproj. Use dotnet restore to restore packages after cloning.

5. Debug with identity

  1. Build the executable:

    dotnet build -c Debug
    
  2. Apply debug identity:

    winapp create-debug-identity .\bin\Debug\net10.0-windows10.0.26100.0\dotnet-app.exe
    
  3. Run the executable (do not use dotnet run as it might rebuild):

    .\bin\Debug\net10.0-windows10.0.26100.0\dotnet-app.exe
    

You should see:

Package Family Name: dotnet-app_12345abcde

Automating debug identity (optional)

Add this target to your .csproj file:

<Target Name="ApplyDebugIdentity" AfterTargets="Build" Condition="'$(Configuration)' == 'Debug'">
    <Exec Command="winapp create-debug-identity &quot;$(TargetDir)$(TargetName).exe&quot;"
          WorkingDirectory="$(ProjectDir)"
          IgnoreExitCode="false" />
</Target>

6. Using Windows App SDK

If you ran winapp init, Microsoft.WindowsAppSDK was already added as a NuGet package reference. Update Program.cs to use the Windows App Runtime API:

using Windows.ApplicationModel;

class Program
{
    static void Main(string[] args)
    {
        try
        {
            var package = Package.Current;
            var familyName = package.Id.FamilyName;
            Console.WriteLine($"Package Family Name: {familyName}");

            var runtimeVersion = Microsoft.Windows.ApplicationModel.WindowsAppRuntime.RuntimeInfo.AsString;
            Console.WriteLine($"Windows App Runtime Version: {runtimeVersion}");
        }
        catch (InvalidOperationException)
        {
            Console.WriteLine("Not packaged");
        }
    }
}

7. Package with MSIX

  1. Build for release:

    dotnet build -c Release
    
  2. Generate a development certificate:

    winapp cert generate --if-exists skip
    
  3. Package and sign:

    winapp pack .\bin\Release\net10.0-windows10.0.26100.0 --manifest .\appxmanifest.xml --cert .\devcert.pfx
    
  4. Install the certificate (run as administrator):

    winapp cert install .\devcert.pfx
    
  5. Install by double-clicking the generated .msix file.

Tip

  • The Microsoft Store signs the MSIX for you, no need to sign before submission.
  • You may need separate MSIX packages for each architecture: dotnet build -c Release -r win-x64 or dotnet build -c Release -r win-arm64.

Automating MSIX packaging (optional)

Add this target to your .csproj:

<Target Name="PackageMsix" AfterTargets="Build" Condition="'$(Configuration)' == 'Release'">
    <Exec Command="winapp pack &quot;$(TargetDir.TrimEnd('\'))&quot; --cert &quot;$(ProjectDir)devcert.pfx&quot;"
          WorkingDirectory="$(ProjectDir)"
          IgnoreExitCode="false" />
</Target>