Share via


Windows App SDK implementatiehandleiding voor frameworkafhankelijke apps die zijn verpakt met externe locatie of uitgepakt

Dit onderwerp bevat richtlijnen voor het implementeren van apps die zijn verpakt met een externe locatie of die zijn uitgepakt en die gebruikmaken van de Windows App SDK.

  • Dergelijke apps zijn desktop-apps (niet UWP-apps).
  • Ze kunnen worden geschreven in een .NET taal zoals C# of in C++.
  • Voor hun gebruikersinterface kunnen ze WinUI 3 of WPF of WinForms of een ander UI-framework gebruiken.

Overzicht

Ontwikkelaars van verpakte apps met externe locatie en uitgepakte apps zijn verantwoordelijk voor het implementeren van vereiste Windows App SDK runtimepakketten voor hun eindgebruikers. U kunt dit doen door het installatieprogramma uit te voeren of door de MSIX-pakketten rechtstreeks te installeren. Deze opties worden uitgebreid beschreven in de sectie Deploy Windows App SDK runtime hieronder.

Apps verpakt met externe locatie en apps zonder verpakking hebben ook extra runtimevereisten. U moet toegang tot de runtime van de Windows App SDK initialiseren met de Bootstrapper-API. Bovendien kan de API voor dynamische afhankelijkheden worden gebruikt als uw app gebruikmaakt van andere frameworkpakketten naast de Windows App SDK. Deze vereisten worden gedetailleerder beschreven in de Runtime-vereisten voor apps die zijn verpakt met externe locatie of uitgepakte sectie hieronder.

Vereiste voorwaarden

Aanvullende vereisten

  • Experimentele en preview-versies van de Windows App SDK vereisen dat sideloading is ingeschakeld om de runtime te installeren.
    • Sideloading wordt automatisch ingeschakeld op Windows 10 versie 2004 en hoger.

    • Als op uw ontwikkelcomputer of de implementatiecomputer Windows 11 wordt uitgevoerd, controleert u of sideloading is ingeschakeld:

      • Instellingen>Privacy en beveiliging>Voor ontwikkelaars. Zorg ervoor dat de instelling voor de ontwikkelaarsmodus is ingeschakeld.
    • Als uw ontwikkelcomputer of de implementatiecomputer draait op Windows 10 versie 1909 of een eerdere versie, controleer of sideloading is ingeschakeld:

      • Instellingen>Update en beveiliging>Voor ontwikkelaars>Gebruik functies voor ontwikkelaars. Controleer of Sideload-apps of ontwikkelaarsmodus is geselecteerd.
    • De instelling voor de ontwikkelaarsmodus bevat sideloading en andere functies.

      Opmerking

      Als de computer wordt beheerd in een bedrijfsomgeving, is er mogelijk een beleid dat verhindert dat deze instellingen worden gewijzigd. Als u in dat geval een foutmelding krijgt wanneer u of uw app de Windows App SDK runtime probeert te installeren, neemt u contact op met uw IT-professional om sideloading of Ontwikkelingsmodus in te schakelen.

Windows App SDK runtime implementeren

Apps verpakt met een externe locatie en niet-verpakte apps hebben twee opties om het Windows App SDK-runtime te implementeren.

Optie 1: het installatieprogramma gebruiken

U kunt alle Windows App SDK runtimepakketten implementeren door het installatieprogramma uit te voeren. Het installatieprogramma is beschikbaar op Downloads voor de Windows App SDK. Wanneer u het installatieprogramma (.exe) uitvoert, ziet u een uitvoer die er ongeveer als volgt uitziet:

Deploying package: Microsoft.WindowsAppRuntime.1.0_0.318.928.0_x64__8wekyb3d8bbwe
Package deployment result : 0x0

Deploying package: Microsoft.WindowsAppRuntime.1.0_0.318.928.0_x86__8wekyb3d8bbwe
Package deployment result : 0x0

Deploying package: MicrosoftCorporationII.WindowsAppRuntime.Main.1.0_0.318.928.0_x64__8wekyb3d8bbwe
Package deployment result : 0x0
Provisioning result : 0x0

Deploying package: Microsoft.WindowsAppRuntime.Singleton_0.318.928.0_x64__8wekyb3d8bbwe
Package deployment result : 0x0
Provisioning result : 0x0

Deploying package: Microsoft.WinAppRuntime.DDLM.0.318.928.0-x6_0.318.928.0_x64__8wekyb3d8bbwe
Package deployment result : 0x0
Provisioning result : 0x0

Deploying package: Microsoft.WinAppRuntime.DDLM.0.318.928.0-x8_0.318.928.0_x86__8wekyb3d8bbwe
Package deployment result : 0x0
Provisioning result : 0x0

All install operations successful.

U kunt het installatieprogramma uitvoeren zonder tussenkomst van de gebruiker en alle tekstuitvoer onderdrukken met de --quiet optie:

WindowsAppRuntimeInstall.exe --quiet

U kunt er ook voor kiezen om de MSIX-pakketten gedwongen bij te werken en alle momenteel actieve processen van de Windows App SDK stop te zetten met behulp van de optie --force. Deze functie wordt geïntroduceerd in 1.1.

WindowsAppRuntimeInstall.exe --force

Als u alle opdrachtregelopties van het installatieprogramma wilt zien, voert u het volgende uit WindowsAppRuntimeInstall --h.

Nadat de installatie is voltooid, kunt u uw verpakte app uitvoeren op een externe locatie of een uitgepakte app uitvoeren. Zie Tutorial: gebruik de bootstrapper-API in een app die is verpakt met een externe locatie of uitgepakt en gebruikmaakt van de Windows App SDK voor een voorbeeld van hoe je een app verpakt met een externe locatie of een uitgepakte app bouwt en uitvoert die gebruikmaakt van de Windows App SDK.

Koppel het Windows App SDK-installatieprogramma aan de installatie van uw app

Als u een aangepast installatieprogramma voor uw app hebt, kunt u het Windows App SDK installatieproces in het installatieproces van uw app koppelen. Het Windows App SDK-installatieprogramma biedt momenteel geen standaardgebruikersinterface, dus u moet koppelen met behulp van de aangepaste gebruikersinterface van uw installatie.

U kunt de Windows App SDK installatie op de achtergrond starten en volgen terwijl u uw eigen weergave van de voortgang van de installatie weergeeft met behulp van ShellExecute. Het Windows App SDK-installatieprogramma pakt de Windows App MSIX-bundel op de achtergrond uit en roept de methode PackageManager.AddPackageAsync aan om de installatie te voltooien. Dit is vergelijkbaar met andere runtime-installatieprogramma's die u mogelijk hebt gebruikt, zoals .NET, Visual C++of DirectX.

Zie de functie RunInstaller in de installer functional tests voor een codevoorbeeld dat laat zien hoe u het Windows App SDK-installatieprogramma uitvoert vanuit uw setup-programma.

Installatievoorbeeld

Zie het onderstaande voorbeeld om te zien hoe u het installatieprogramma start vanuit een Win32-installatieprogramma zonder een consolevenster te openen tijdens de installatie:

Probleemoplossingsproces

Retourcodes

De volgende tabel bevat de meest voorkomende retourcodes voor het Windows App SDK .exe-installatieprogramma. De retourcodes zijn hetzelfde voor alle versies van het installatieprogramma.

Retourcode Description
0x0 De installatie of provisioning van het pakket is voltooid.
0x80073d06 Een of meer pakketten kunnen niet worden geïnstalleerd.
0x80070005 Installatie of inrichting voor het hele systeem is niet mogelijk omdat de app niet wordt uitgevoerd met verhoogde bevoegdheden of omdat de gebruiker die de installatie uitvoert geen beheerdersbevoegdheden heeft.

Installatiefouten

Als het Windows App SDK installatieprogramma een fout retourneert tijdens de installatie, wordt er een foutcode geretourneerd die het probleem beschrijft.

Optie 2: Windows App SDK runtimepakketten rechtstreeks implementeren

Als alternatief voor het gebruik van het Windows App SDK-installatieprogramma voor implementatie aan eindgebruikers, kunt u de MSIX-pakketten handmatig implementeren via het programma of MSI van uw app. Deze optie kan het beste zijn voor ontwikkelaars die meer controle willen.

Zie install.cpp in de Windows App SDK-installatiecode voor een voorbeeld dat laat zien hoe uw installatieprogramma de MSIX-pakketten kan installeren.

Als u wilt controleren of de Windows App SDK al is geïnstalleerd (en zo ja, welke versie), kunt u controleren op specifieke pakketfamilies door PackageManager.FindPackagesForUserWithPackageTypes aan te roepen.

Vanuit een mediumIL (volledig vertrouwen) uitgepakt proces (zie toepassingselement), kunt u de volgende code gebruiken om te controleren op een pakket dat is geregistreerd bij de huidige gebruiker:

using Windows.Management.Deployment;

public class WindowsAppSDKRuntime
{
    public static IsPackageRegisteredForCurrentUser(
        string packageFamilyName,
        PackageVersion minVersion,
        Windows.System.ProcessorArchitecture architecture,
        PackageTypes packageType)
    {
        ulong minPackageVersion = ToVersion(minVersion);

        foreach (var p : PackageManager.FindPackagesForUserWithPackageTypes(
            string.Empty, packageFamilyName, packageType)
        {
            // Is the package architecture compatible?
            if (p.Id.Architecture != architecture)
            {
                continue;
            }

            // Is the package version sufficient for our needs?
            ulong packageVersion = ToVersion(p.Id.Version);
            if (packageVersion < minPackageVersion)
            {
                continue;
            }

            // Success.
            return true;
        }

        // No qualifying package found.
        return false;
    }

    private static ulong ToVersion(PackageVersion packageVersion)
    {
        return ((ulong)packageVersion.Major << 48) |
               ((ulong)packageVersion.Minor << 32) |
               ((ulong)packageVersion.Build << 16) |
               ((ulong)packageVersion.Revision);
    }
}

Voor het bovenstaande scenario is het aanroepen van FindPackagesForUserWithPackageTypes de voorkeur aan het aanroepen van FindPackagesForUser. Dat komt doordat u de zoekopdracht kunt beperken tot (voor dit voorbeeld), alleen framework- of hoofdpakketten. En dat vermijdt overeenkomende andere typen pakketten (zoals resource, optioneel of bundel) die niet van belang zijn voor dit voorbeeld.

Als u de huidige/aanroepende gebruikerscontext wilt gebruiken, stelt u de parameter userSecurityId in op een lege tekenreeks.

En nu wat informatie om u te helpen bepalen hoe u de functie aanroept in het bovenstaande codevoorbeeld. Een correct geïnstalleerde runtime bestaat uit meerdere pakketten die afhankelijk zijn van de CPU-architectuur van het systeem:

  • Op een x86-machine: Fwk=[x86], Main=[x86], Singleton=[x86], DDLM=[x86].
  • Op een x64-machine: Fwk=[x86, x64], Main=[x64], Singleton=[x64], DDLM=[x86, x64].
  • Op een arm64-machine: Fwk=[x86, x64, arm64], Main=[arm64], Singleton=[arm64], DDLM=[x86, x64, arm64].

Voor de Main - en Singleton-pakketten moet hun architectuur overeenkomen met de CPU-architectuur van het systeem; Bijvoorbeeld x64-pakketten op een x64-systeem. Voor het Framework-pakket kan een x64-systeem zowel x64- als x86-apps uitvoeren; Op dezelfde manier kan een arm64-systeem arm64-, x64- en x86-apps uitvoeren. Een DDLM-pakketcontrole is vergelijkbaar met een Framework-controle , behalve dat PackageType=main, en de packagefamilyname verschilt, en meer dan één (andere) packagefamilyname kan van toepassing zijn, vanwege het unieke naamgevingsschema van DDLM. Zie de specificatie MSIX-pakketten voor meer informatie. De controles zijn dus meer als volgt:

public static bool IsRuntimeRegisteredForCurrentUser(PackageVersion minVersion)
{
    ProcessorArchitecture systemArchitecture = DetectSystemArchitecture();

    return IsFrameworkRegistered(systemArchitecture, minVersion) &&
           IsMainRegistered(systemArchitecture, minVersion) &&
           IsSingletonRegistered(systemArchitecture, minVersion) &&
           IsDDLMRegistered(systemArchitecture, minVersion);
}

private static ProcecssorArchitecture DetectSystemArchitecture()
{
    // ...see the call to IsWow64Process2(), and how the result is used...
    // ...as per `IsPackageApplicable()` in
    // [install.cpp](https://github.com/microsoft/WindowsAppSDK/blob/main/installer/dev/install.cpp)
    // line 99-116...
    // ...WARNING: Use IsWow64Process2 to detect the system architecture....
    // ...         Other similar APIs exist, but don't give reliably accurate results...
}

private static bool IsFrameworkRegistered(ProcessorArchitecture systemArchitecture,
    PackageVersion minVersion)
{
    // Check x86.
    if (!IsPackageRegisteredForCurrentUser(
        global::Microsoft.WindowsAppSDK.Runtime.Packages.Framework.PackageFamilyName,
        minVersion, ProcessorArchitecture.X86,
        PackageTypes.Framework))
    {
        return false;
    }

    // Check x64 (if necessary).
    if ((systemArchitecture == ProcessorArchitecture.X64) || 
        (systemArchitecture == ProcessorArchitcture.Arm64))
    {
        if (!IsPackageRegisteredForCurrentUser(
            global::Microsoft.WindowsAppSDK.Runtime.Packages.Framework.PackageFamilyName,
            minVersion, ProcessorArchitecture.X64,
            PackageTypes.Framework))
        {
            return false;
        }
    }

    // Check arm64 (if necessary).
    if (systemArchitecture == ProcessorArchitcture.Arm64)
    {
        if (!IsPackageRegisteredForCurrentUser(
            global::Microsoft.WindowsAppSDK.Runtime.Packages.Framework.PackageFamilyName,
            minVersion, ProcessorArchitecture.Arm64,
            PackageTypes.Framework))
        {
            return false;
        }
    }

    return true;
}

private static bool IsMainRegistered(ProcessorArchitecture systemArchitecture,
    PackageVersion minVersion)
{
    return IsPackageRegisteredForCurrentUser(
        global::Microsoft.WindowsAppSDK.Runtime.Packages.Main.PackageFamilyName,
        minVersion,
        systemArchitecture,
        PackageTypes.Main);
}

private static bool IsSingletonRegistered(ProcessorArchitecture systemArchitecture,
    PackageVersion minVersion)
{
    return IsPackageRegisteredForCurrentUser(
        global::Microsoft.WindowsAppSDK.Runtime.Packages.Singleton.PackageFamilyName,
        minVersion,
        systemArchitecture,
        PackageTypes.Main);
}

private static bool IsDDLMRegistered(ProcessorArchitecture systemArchitecture,
    PackageVersion minVersion)
{
    // ...similar to IsFrameworkRegistered, but the packageFamilyName is more complicated...
    // ...and no predefined constant is currently available...
    // ...for more details, see
    // https://github.com/microsoft/WindowsAppSDK/blob/main/specs/Deployment/MSIXPackages.md.
}

De bovenstaande informatie en code hebben betrekking op het basisdetectiescenario. Om te detecteren of de runtime is ingericht voor alle gebruikers, of om het bovenstaande vanuit een app-container te doen, en/of dit vanuit een verpakt mediumIL-proces uit te voeren, is aanvullende logica nodig.

Uitrolscenario's

  • De Windows App SDK-runtime systeemwijd installeren: Een systeemwijde installatie wijzigt de computer voor alle gebruikers, inclusief nieuwe gebruikers die in de toekomst worden toegevoegd. Als de app wordt uitgevoerd met verhoogde bevoegdheden en de gebruiker die de installatie uitvoert, beheerdersbevoegdheden heeft, registreert het installatieprogramma de MSIX-pakketten in het hele systeem door provisionPackageForAllUsersAsync aan te roepen. Als de registratie voor het hele systeem niet lukt, wordt de installatie alleen uitgevoerd voor de huidige gebruiker die de installatie uitvoert. In een beheerde enterprise-omgeving moet de IT-beheerder op de gebruikelijke manier voor iedereen kunnen inrichten.

  • Architectures opnieuw gedistribueerd door het Windows App SDK-installatieprogramma: het installatieprogramma voor Windows App SDK is beschikbaar in de x86, x64 en Arm64 architecturen. Elke versie van het installatieprogramma bevat de MSIX-pakketten voor alleen de specifieke architectuur waarvoor deze een naam heeft. Als u bijvoorbeeld het x86WindowsAppRuntimeInstall.exe op een x64- of Arm64-apparaat uitvoert, wordt dat x86 installatieprogramma alleen op dat apparaat geïmplementeerd voor de pakketten voor de x86-architectuur.

  • Alle Windows App SDK MSIX-pakketten zijn al geïnstalleerd op de computer: MSIX-pakketten worden geïnstalleerd op een systeembrede locatie met slechts één kopie op schijf. Als een app probeert de installatie van de Windows App SDK wanneer alle MSIX-pakketafhankelijkheden al op de computer zijn geïnstalleerd, wordt de installatie niet uitgevoerd.

  • One of meer van de Windows App SDK MSIX-pakketten zijn niet geïnstalleerd op de computer: wanneer u de Windows App SDK implementeert, probeert u altijd alle MSIX-pakketten (framework, main, singleton, DDLM) te installeren om ervoor te zorgen dat alle afhankelijkheden zijn geïnstalleerd en u onderbreking van de eindgebruikerservaring voorkomt.

Runtimevereisten voor apps die zijn verpakt met externe locatie of uitgepakt

Apps die zijn verpakt met een externe locatie of uitgepakt, hebben extra runtimevereisten voor het gebruik van de Windows App SDK runtime. Dit omvat het verwijzen naar en initialiseren van het Windows App SDK Framework-pakket tijdens runtime. Daarnaast kan de API voor dynamische afhankelijkheden worden gebruikt om te verwijzen naar andere frameworkpakketten buiten de Windows App SDK.

De Windows App SDK runtime gebruiken

Apps die zijn verpakt bij externe locatie en uitgepakte apps moeten de Bootstrapper-API aanroepen om de Windows App SDK tijdens uitvoeringstijd te gebruiken. Dit is vereist voordat de app Windows App SDK functies zoals WinUI, App Lifecycle, MRT Core en DWriteCore kan gebruiken. Een bootstrapper-onderdeel maakt het mogelijk voor apps die zijn verpakt met externe locatie en voor uitgepakte apps om deze belangrijke taken uit te voeren.

  • Zoek en laad het Windows App SDK framework-pakket in de pakketgrafiek van de app.
  • Initialiseer de Dynamic Dependency Lifetime Manager (DDLM) voor het Windows App SDK frameworkpakket. Het doel van de DDLM is om het onderhoud van het Windows App SDK framework-pakket te voorkomen terwijl het wordt gebruikt door een app die met externe componenten is verpakt of een uitgepakte app.

De eenvoudigste manier om de Windows App SDK runtime te laden voor verpakte apps met externe locatie en uitgepakte apps is door de eigenschap <WindowsPackageType>None</WindowsPackageType> in uw projectbestand (.csproj of .vcxproj) in te stellen. U kunt de bootstrapper-API ook rechtstreeks aanroepen in de opstartcode van uw app voor meer controle over de initialisatie. Zie voor meer informatie Gebruik de Windows App SDK runtime voor apps die zijn verpakt met externe locatie of uitgepakt en Tutorial: Gebruik de bootstrapper-API in een app die is verpakt met externe locatie of uitgepakt die gebruikmaakt van de Windows App SDK.

Met ondersteuning voor dynamische afhankelijkheden kunnen pakketten met externe locatie en uitgepakte apps hun bestaande implementatiemechanisme behouden, zoals MSI of een installatieprogramma, en kunnen ze gebruikmaken van de Windows App SDK in hun toepassing. Dynamische afhankelijkheden kunnen worden gebruikt door verpakte apps, verpakte apps met een externe locatie en uitgepakte apps; hoewel ze voornamelijk bedoeld zijn voor gebruik door verpakte apps met een externe locatie en uitgepakte apps.

Er is één DDLM voor elke versie en architectuur van het Windows App SDK framework-pakket. Dit betekent dat u op een x64 computer mogelijk zowel een x86 als een x64 versie van de DDLM hebt ter ondersteuning van apps van beide architecturen.

Verwijzen naar andere frameworkpakketten met behulp van de API voor dynamische afhankelijkheden

Als u functies wilt gebruiken in andere frameworkpakketten buiten de Windows App SDK (bijvoorbeeld DirectX), kunnen zowel verpakte als niet-verpakte apps de API voor dynamische afhankelijkheden aanroepen. Naast het bootstrapper-onderdeel biedt de Windows App SDK ook een bredere set C/C++-functies en WinRT-klassen die de dynamic dependency API implementeren. Deze API is ontworpen om dynamisch te verwijzen naar elk frameworkpakket tijdens runtime.

Zie MSIX-frameworkpakketten dynamisch gebruiken vanuit uw desktop-app en het voorbeeld van dynamische afhankelijkheden voor meer informatie

.winmd-bestanden implementeren op de doelcomputer

Samen met uw app raden we u aan om windows-metagegevensbestanden (.winmd) te implementeren. Metagegevens kunnen tijdens runtime worden gebruikt door verschillende API's en gedragingen, en het ontbreken ervan kan de functionaliteit beperken of onderbreken. Metagegevens kunnen bijvoorbeeld worden gebruikt om objecten te marshallen over de grenzen van appartementen; en de noodzaak om te marshallen kan afhankelijk zijn van de machineprestaties. Omdat er geen deterministische manier is om te weten of u metagegevens nodig hebt, moet u implementeren .winmd, tenzij u uiterst bezorgd bent over de grootte.