Skip to main content

Overview

UninstallOptions provides control over package uninstallation behavior when calling UninstallPackageAsync.

Class Definition

runtimeclass UninstallOptions
{
    UninstallOptions();
    
    // Version (not currently used)
    PackageVersionId PackageVersionId;
    
    // Uninstall behavior
    PackageUninstallMode PackageUninstallMode;
    String LogOutputPath;
    String CorrelationData;
    
    // Advanced options
    Boolean Force;
    PackageUninstallScope PackageUninstallScope;
}

Properties

PackageVersionId

PackageVersionId
PackageVersionId
Not currently used. The installed version is always uninstalled.
This property is reserved for future use. Uninstall always targets the CatalogPackage.InstalledVersion.

PackageUninstallMode

PackageUninstallMode
PackageUninstallMode
default:"Default"
Controls uninstaller UI behavior.
Values:
  • Default - Uninstaller’s default experience (may show UI)
  • Silent - Suppress UI where possible
  • Interactive - Show full uninstaller UI
// Silent uninstallation (no UI)
var options = new UninstallOptions()
{
    PackageUninstallMode = PackageUninstallMode.Silent
};

// Interactive uninstallation
var interactiveOptions = new UninstallOptions()
{
    PackageUninstallMode = PackageUninstallMode.Interactive
};

// Default (uninstaller decides)
var defaultOptions = new UninstallOptions()
{
    PackageUninstallMode = PackageUninstallMode.Default
};

PackageUninstallScope

PackageUninstallScope
PackageUninstallScope
default:"Any"
Specifies uninstall scope (currently only applicable to MSIX packages).
Values:
  • Any - Use default uninstall behavior
  • User - Uninstall for current user only (MSIX only)
  • System - Uninstall for all users (MSIX only)
// Uninstall for current user only
var options = new UninstallOptions()
{
    PackageUninstallScope = PackageUninstallScope.User
};

// Uninstall system-wide (requires admin for MSIX)
var systemOptions = new UninstallOptions()
{
    PackageUninstallScope = PackageUninstallScope.System
};
PackageUninstallScope currently only affects MSIX packages. For other installer types, this setting is ignored.

LogOutputPath

LogOutputPath
String
Path to write uninstallation log file.
var logPath = Path.Combine(
    Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
    "WinGet", "Logs", $"uninstall-{DateTime.Now:yyyyMMdd-HHmmss}.log"
);

var options = new UninstallOptions()
{
    LogOutputPath = logPath
};

Console.WriteLine($"Uninstall log will be written to: {logPath}");

Force

Force
Boolean
default:"false"
Force uninstallation, bypassing non-security related checks.
var options = new UninstallOptions()
{
    Force = true // Override non-critical failures
};

CorrelationData

CorrelationData
String
JSON-encoded correlation data returned in result.
using System.Text.Json;

var correlationData = new
{
    SessionId = Guid.NewGuid().ToString(),
    Operation = "uninstall",
    Timestamp = DateTime.UtcNow
};

var options = new UninstallOptions()
{
    CorrelationData = JsonSerializer.Serialize(correlationData)
};

var result = await manager.UninstallPackageAsync(package, options);

// Retrieve correlation data from result
Console.WriteLine($"Correlation: {result.CorrelationData}");

Complete Example

Finding and Uninstalling a Package

using Microsoft.Management.Deployment;
using System;
using System.Threading.Tasks;

async Task UninstallPackageByIdAsync(string packageId)
{
    var manager = new PackageManager();
    
    // Get installed packages catalog
    var catalogRef = manager.GetLocalPackageCatalog(
        LocalPackageCatalog.InstalledPackages
    );
    
    var connectResult = await catalogRef.ConnectAsync();
    if (connectResult.Status != ConnectResultStatus.Ok)
    {
        Console.WriteLine($"Failed to connect to catalog: {connectResult.Status}");
        return;
    }
    
    // Search for installed package
    var findOptions = new FindPackagesOptions();
    findOptions.Selectors.Add(new PackageMatchFilter()
    {
        Field = PackageMatchField.Id,
        Value = packageId,
        Option = PackageFieldMatchOption.Equals
    });
    
    var findResult = await connectResult.PackageCatalog.FindPackagesAsync(findOptions);
    
    if (findResult.Status != FindPackagesResultStatus.Ok)
    {
        Console.WriteLine($"Search failed: {findResult.Status}");
        return;
    }
    
    if (findResult.Matches.Count == 0)
    {
        Console.WriteLine($"Package '{packageId}' is not installed");
        return;
    }
    
    var package = findResult.Matches[0].CatalogPackage;
    var installedVersion = package.InstalledVersion;
    
    Console.WriteLine($"Found: {package.Name}");
    Console.WriteLine($"Installed Version: {installedVersion.Version}");
    Console.WriteLine($"\nUninstalling...");
    
    // Configure uninstall options
    var uninstallOptions = new UninstallOptions()
    {
        PackageUninstallMode = PackageUninstallMode.Silent,
        LogOutputPath = Path.Combine(
            Path.GetTempPath(),
            $"uninstall-{packageId}-{DateTime.Now:yyyyMMdd-HHmmss}.log"
        )
    };
    
    // Uninstall with progress tracking
    var operation = manager.UninstallPackageAsync(package, uninstallOptions);
    
    operation.Progress = (op, progress) =>
    {
        Console.WriteLine($"State: {progress.State}");
        
        if (progress.UninstallationProgress > 0)
        {
            Console.WriteLine($"Progress: {progress.UninstallationProgress * 100:F1}%");
        }
    };
    
    var result = await operation;
    
    // Check result
    if (result.Status == UninstallResultStatus.Ok)
    {
        Console.WriteLine("\nUninstallation successful!");
        
        if (result.RebootRequired)
        {
            Console.WriteLine("A reboot is required to complete the uninstallation.");
        }
    }
    else
    {
        Console.WriteLine($"\nUninstallation failed: {result.Status}");
        Console.WriteLine($"HRESULT: 0x{result.ExtendedErrorCode:X8}");
        
        if (result.Status == UninstallResultStatus.UninstallError)
        {
            Console.WriteLine($"Uninstaller Error Code: 0x{result.UninstallerErrorCode:X}");
        }
        
        Console.WriteLine($"\nCheck log file: {uninstallOptions.LogOutputPath}");
    }
}

// Usage
await UninstallPackageByIdAsync("Microsoft.PowerToys");

UninstallResult

runtimeclass UninstallResult
{
    String CorrelationData { get; };
    Boolean RebootRequired { get; };
    UninstallResultStatus Status { get; };
    HRESULT ExtendedErrorCode { get; };
    UInt32 UninstallerErrorCode { get; };
}

UninstallResultStatus

Values:
  • Ok - Uninstallation successful
  • BlockedByPolicy - Blocked by group policy
  • CatalogError - Catalog error
  • InternalError - Internal error
  • InvalidOptions - Invalid options provided
  • UninstallError - Uninstaller failed
  • ManifestError - Manifest error
var result = await manager.UninstallPackageAsync(package, options);

switch (result.Status)
{
    case UninstallResultStatus.Ok:
        Console.WriteLine("Success!");
        break;
        
    case UninstallResultStatus.UninstallError:
        Console.WriteLine($"Uninstaller failed with code: 0x{result.UninstallerErrorCode:X}");
        break;
        
    case UninstallResultStatus.BlockedByPolicy:
        Console.WriteLine("Blocked by group policy");
        break;
        
    default:
        Console.WriteLine($"Failed: {result.Status}");
        Console.WriteLine($"HRESULT: 0x{result.ExtendedErrorCode:X8}");
        break;
}

if (result.RebootRequired)
{
    Console.WriteLine("\nA system reboot is required.");
}

UninstallProgress

struct UninstallProgress
{
    PackageUninstallProgressState State;
    Double UninstallationProgress;
}

PackageUninstallProgressState

Values:
  • Queued - Uninstall is queued but not active
  • Uninstalling - Uninstallation in progress
  • PostUninstall - Cleanup actions in progress
  • Finished - Operation completed
operation.Progress = (op, progress) =>
{
    switch (progress.State)
    {
        case PackageUninstallProgressState.Queued:
            Console.WriteLine("Queued...");
            break;
            
        case PackageUninstallProgressState.Uninstalling:
            Console.WriteLine($"Uninstalling... {progress.UninstallationProgress * 100:F1}%");
            break;
            
        case PackageUninstallProgressState.PostUninstall:
            Console.WriteLine("Cleaning up...");
            break;
            
        case PackageUninstallProgressState.Finished:
            Console.WriteLine("Finished");
            break;
    }
};

Common Scenarios

Silent Uninstallation

var options = new UninstallOptions()
{
    PackageUninstallMode = PackageUninstallMode.Silent
};

Uninstall with Logging

var options = new UninstallOptions()
{
    PackageUninstallMode = PackageUninstallMode.Silent,
    LogOutputPath = @"C:\Logs\uninstall.log"
};

Force Uninstallation

var options = new UninstallOptions()
{
    PackageUninstallMode = PackageUninstallMode.Silent,
    Force = true
};

User-Scoped MSIX Uninstall

var options = new UninstallOptions()
{
    PackageUninstallMode = PackageUninstallMode.Silent,
    PackageUninstallScope = PackageUninstallScope.User
};

Build docs developers (and LLMs) love