Condividi tramite


Windows App SDK, guida alla distribuzione per app dipendenti da framework imballate con percorso esterno o non imballate.

Questo argomento fornisce indicazioni sulla distribuzione di app confezionate con un'origine esterna, o app non confezionate, che utilizzano Windows App SDK.

  • Queste app sono app desktop (non app UWP).
  • Possono essere scritti in un linguaggio .NET, ad esempio C#, o in C++.
  • Per l'interfaccia utente, possono usare WinUI 3, WPF o WinForms o un altro framework dell'interfaccia utente.

Panoramica

Gli sviluppatori di pacchetti con posizione esterna e app non in pacchetto sono responsabili della distribuzione dei pacchetti di runtime necessari Windows App SDK agli utenti finali. A tale scopo è possibile eseguire il programma di installazione o installare direttamente i pacchetti MSIX. Queste opzioni sono descritte in modo più dettagliato nella sezione Deploy Windows App SDK runtime di seguito.

Le app in pacchetto con posizione esterna e le app non in pacchetto hanno anche altri requisiti di runtime. È necessario inizializzare l'accesso al runtime di Windows App SDK usando la Bootstrapper API. Inoltre, l'API Dipendenze dinamiche può essere usata se l'app usa altri pacchetti framework a parte il Windows App SDK. Questi requisiti sono descritti in modo più dettagliato nella sezione Requisiti di runtime per le app in pacchetto con posizione esterna o non in pacchetto di seguito.

Prerequisiti

Prerequisiti aggiuntivi

  • Le versioni sperimentali e di anteprima del Windows App SDK richiedono che il trasferimento locale sia abilitato per installare il runtime.
    • Il sideloading viene abilitato automaticamente in Windows 10 versione 2004 e successive.

    • Se il computer di sviluppo o di distribuzione esegue Windows 11, verificare se il sideloading è abilitato:

      • Impostazioni>Privacy & sicurezza>Per sviluppatori. Assicurarsi che la modalità sviluppatore sia attivata.
    • Se il computer di sviluppo o il computer di distribuzione esegue Windows 10 versione 1909 o una versione precedente, verificate se il sideloading è abilitato:

      • Impostazioni>Aggiornamento & Sicurezza>Per sviluppatori>Usa le funzionalità per gli sviluppatori. Verificare che Sideload app o Modalità sviluppatore siano selezionate.
    • L'impostazione Modalità sviluppatore include il sideloading e altre funzionalità.

      Nota

      Se il computer è gestito in un ambiente aziendale, potrebbe essere presente un criterio che impedisce la modifica di queste impostazioni. In tal caso, se si riceve un errore quando tu o la tua app tentate di installare il runtime di Windows App SDK, contatta il tuo professionista IT per abilitare il sideloading o la Modalità Developer.

Distribuire Windows App SDK runtime

Nelle applicazioni confezionate con un percorso esterno e nelle applicazioni non confezionate sono disponibili due opzioni per distribuire il runtime di Windows App SDK:

Opzione 1: usare il programma di installazione

È possibile distribuire tutti i pacchetti di runtime Windows App SDK eseguendo il programma di installazione. Il programma di installazione è disponibile in Downloads per il Windows App SDK. Quando si esegue il programma di installazione (.exe), viene visualizzato un output simile al seguente:

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.

È possibile eseguire il programma di installazione senza interazione dell'utente e eliminare tutto l'output di testo con l'opzione --quiet:

WindowsAppRuntimeInstall.exe --quiet

È anche possibile scegliere di forzare l'aggiornamento dei pacchetti MSIX e arrestare eventuali processi Windows App SDK attualmente in esecuzione usando l'opzione --force. Questa funzionalità è stata introdotta nella versione 1.1.

WindowsAppRuntimeInstall.exe --force

Per visualizzare tutte le opzioni della riga di comando del programma di installazione, eseguire WindowsAppRuntimeInstall --h.

Al termine dell'installazione, è possibile eseguire la tua app pacchettizzata con posizione esterna o non pacchettizzata. Per un esempio di come compilare ed eseguire un pacchetto con un percorso esterno o un'app non in pacchetto che usa il Windows App SDK, vedere Tutorial: Usare l'API del programma di avvio automatico in un'app in pacchetto con percorso esterno o senza pacchetti che usa il Windows App SDK.

Concatenare il programma di installazione di Windows App SDK alla configurazione dell'app

Se hai un programma di installazione personalizzato per la tua app, puoi concatenare il processo di installazione Windows App SDK nel processo di installazione dell'app. Il programma di installazione Windows App SDK attualmente non fornisce un'interfaccia utente predefinita, quindi dovrai concatenare usando l'interfaccia utente personalizzata della configurazione.

È possibile avviare silenziosamente e tenere traccia dell'installazione del Windows App SDK mostrando la propria vista dello stato di avanzamento dell'installazione usando ShellExecute. Il programma di installazione Windows App SDK decomprime automaticamente il bundle MSIX Windows App e chiama il metodo PackageManager.AddPackageAsync per completare l'installazione. Questa operazione è molto simile ad altri programmi di installazione di runtime usati, ad esempio .NET, Visual C++o DirectX.

Per un esempio di codice che illustra come eseguire il programma di installazione di Windows App SDK dal programma di installazione, vedere la funzione RunInstaller nei test funzionali installer.

Esempio di programma di installazione

Vedere l'esempio seguente per vedere come avviare il programma di installazione da un programma di installazione Win32 senza aprire una finestra della console durante l'installazione:

Esempio di programma di installazione Explore

Risoluzione dei problemi

Codici di restituzione

Nella tabella seguente sono elencati i codici restituiti più comuni per il programma di installazione di Windows App SDK .exe. I codici restituiti sono gli stessi per tutte le versioni del programma di installazione.

Codice restituito Descrizione
0x0 L'installazione o il provisioning del pacchetto è stato completato correttamente.
0x80073d06 Impossibile installare uno o più pacchetti.
0x80070005 L'installazione o il provisioning a livello di sistema non è stato possibile perché l'app non è in esecuzione con privilegi elevati o l'utente che esegue l'installazione non dispone di privilegi di amministratore.

Errori di installazione

Se il programma di installazione Windows App SDK restituisce un errore durante l'installazione, restituirà un codice di errore che descrive il problema.

Opzione 2: Distribuire direttamente i pacchetti di runtime Windows App SDK

In alternativa all'uso del programma di installazione Windows App SDK per la distribuzione agli utenti finali, è possibile distribuire manualmente i pacchetti MSIX tramite il programma dell'app o un file MSI. Questa opzione può essere ideale per gli sviluppatori che vogliono avere un maggiore controllo.

Per un esempio che illustra come il programma di installazione può installare i pacchetti MSIX, vedere install.cpp nel codice del programma di installazione di Windows App SDK.

Per verificare se il Windows App SDK è già installato (e, in tal caso, quale versione), è possibile verificare la presenza di famiglie di pacchetti specifiche chiamando PackageManager.FindPackagesForUserWithPackageTypes.

Da un processo mediumIL (full trust) non impacchettato (vedere l'elemento Application), è possibile usare il codice seguente per verificare la presenza di un pacchetto registrato per l'utente corrente:

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);
    }
}

Per lo scenario precedente, chiamare FindPackagesForUserWithPackageTypes è preferibile a chiamare FindPackagesForUser. Ciò è dovuto al fatto che è possibile restringere la ricerca a (per questo esempio), solo framework o pacchetti principali. E questo evita la corrispondenza di altri tipi di pacchetti (ad esempio , risorsa, facoltativa o bundle) che non sono di interesse per questo esempio.

Per usare il contesto utente corrente/chiamante, impostare il parametro userSecurityId su una stringa vuota.

E ora alcune informazioni utili per decidere come chiamare la funzione nell'esempio di codice precedente. Un runtime installato correttamente è costituito da più pacchetti che dipendono dall'architettura della CPU del sistema:

  • In un computer x86: Fwk=[x86], Main=[x86], Singleton=[x86], DDLM=[x86].
  • In un computer x64: Fwk=[x86, x64], Main=[x64], Singleton=[x64], DDLM=[x86, x64].
  • Su una macchina arm64: Fwk=[x86, x64, arm64], Main=[arm64], Singleton=[arm64], DDLM=[x86, x64, arm64].

Per i pacchetti Main e Singleton , l'architettura deve corrispondere all'architettura della CPU del sistema, ad esempio pacchetti x64 in un sistema x64. Per il pacchetto Framework , un sistema x64 può eseguire app x64 e x86. Analogamente, un sistema arm64 può eseguire app arm64, x64 e x86. Un controllo del pacchetto DDLM è simile a un controllo framework, ad eccezione del fatto che PackageType=main, e il packagefamilyname differisce, e più di un packagefamilyname (diverso) può essere applicabile a causa dello schema di denominazione univoco di DDLM. Per ulteriori informazioni, consultare la specifica dei pacchetti MSIX. I controlli sono quindi più simili a questi:

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.
}

Le informazioni e il codice precedenti illustrano lo scenario di rilevamento di base. Per rilevare se il runtime è provisionato per tutti gli utenti, oppure per eseguire l'operazione da un contenitore di applicazione e/o da un processo mediumIL impacchettato, è necessario logica aggiuntiva.

Scenari di distribuzione

  • Installing the Windows App SDK Runtime system-wide: l'installazione a livello di sistema modifica il computer per tutti gli utenti, inclusi i nuovi utenti aggiunti in futuro. Se l'app è in esecuzione con privilegi elevati e l'utente che esegue l'installazione disponde di privilegi di amministratore, il programma di installazione registrerà i pacchetti MSIX a livello di sistema chiamando ProvisionPackageForAllUsersAsync. Se la registrazione a livello di sistema ha esito negativo, l'installazione verrà eseguita solo per l'utente corrente che esegue l'installazione. In un ambiente aziendale gestito, l'amministratore IT deve essere in grado di effettuare il provisioning per tutti come al solito.

  • Architecture ridistribuite dal programma di installazione di Windows App SDK: il programma di installazione di Windows App SDK è disponibile nelle architetture x86, x64 e Arm64. Ogni versione del programma di installazione include i pacchetti MSIX solo per l'architettura specifica per cui è denominato. Ad esempio, se si esegue il x86WindowsAppRuntimeInstall.exe su un dispositivo x64 o Arm64, il programma di installazione x86 distribuisce su tale dispositivo esclusivamente i pacchetti per l'architettura x86.

  • Tutti i pacchetti MSIX Windows App SDK sono già installati nel computer: i pacchetti MSIX vengono installati in un percorso a livello di sistema con una sola copia su disco. Se un'app tenta di installare il Windows App SDK quando tutte le dipendenze del pacchetto MSIX sono già installate nel computer, l'installazione non viene eseguita.

  • One o più pacchetti MSIX Windows App SDK non sono installati nel computer: quando si distribuisce il Windows App SDK, provare sempre a installare tutti i pacchetti MSIX (framework, main, singleton, DDLM) per assicurarsi che tutte le dipendenze siano installate ed evitare interruzioni dell'esperienza dell'utente finale.

Requisiti di runtime per le app impacchettate con sorgente esterna o non impacchettate

Le app confezionate con posizione esterna o non confezionate hanno requisiti di runtime aggiuntivi per utilizzare il runtime di Windows App SDK. Ciò comporta il riferimento e l'inizializzazione del pacchetto di Windows App SDK Framework in fase di esecuzione. Inoltre, l'API Dipendenze dinamiche può essere usata per fare riferimento ad altri pacchetti di framework all'esterno del Windows App SDK.

Usare il runtime di Windows App SDK

Le applicazioni confezionate con posizione esterna e le applicazioni non confezionate devono chiamare la Bootstrapper API per utilizzare il Windows App SDK in fase di esecuzione. Questa operazione è necessaria prima che l'app possa usare Windows App SDK funzionalità come WinUI, Ciclo di vita dell'app, MRT Core e DWriteCore. Un componente bootstrapper consente alle app confezionate con una posizione esterna e alle app non confezionate di eseguire queste importanti attività:

  • Trovare e caricare il pacchetto framework di Windows App SDK nel grafo del pacchetto dell'applicazione.
  • Inizializzare il Gestore del Ciclo di Vita delle Dipendenze Dinamiche (DDLM) per il pacchetto del framework Windows App SDK. Lo scopo del DDLM è impedire la manutenzione del pacchetto framework Windows App SDK mentre è in uso da un pacchetto con percorso esterno o un'app non pacchettizzata.

Il modo più semplice per caricare il runtime di Windows App SDK per i pacchetti con percorso esterno e app non in pacchetto consiste nell'impostare la proprietà <WindowsPackageType>None</WindowsPackageType> nel file di project (con estensione csproj o .vcxproj). È anche possibile chiamare l'API del programma di avvio automatico direttamente nel codice di avvio dell'app per un maggiore controllo sull'inizializzazione. Per altri dettagli, vedere Utilizzare il runtime di Windows App SDK per app confezionate con una posizione esterna o non confezionate e Tutorial: Utilizzare l'API bootstrapper in un'app confezionata con una posizione esterna o non confezionata che utilizza il Windows App SDK.

Il supporto delle dipendenze dinamiche consente ad app con pacchetto con ubicazione esterna e app non impacchettate di mantenere il meccanismo di distribuzione esistente, come MSI o qualsiasi programma di installazione, e di sfruttare il Windows App SDK nelle loro applicazioni. Le dipendenze dinamiche possono essere usate nelle app in pacchetto, nelle app in pacchetto con posizione esterna e nelle app non in pacchetto; anche se sono principalmente destinate ad essere utilizzate dalle app in pacchetto con posizione esterna e dalle app non in pacchetto.

Per ogni versione e architettura del pacchetto framework di Windows App SDK è disponibile un DDLM. Ciò significa che su un x64 computer, potresti avere sia una versione x86 che una versione x64 del DDLM a supportare app di entrambe le architetture.

Fare riferimento ad altri pacchetti framework usando l'API delle dipendenze dinamiche

Se si vogliono usare funzionalità in altri pacchetti di framework al di fuori del Windows App SDK (ad esempio DirectX), le app impacchettate con percorso esterno e quelle non impacchettate possono chiamare l'API delle dipendenze dinamiche. Oltre al componente del programma di avvio automatico, il Windows App SDK fornisce anche un set più ampio di funzioni C/C++ e classi WinRT che implementano l'API di dipendenza dynamic dependency API. Questa API è progettata per fare riferimento a qualsiasi pacchetto framework in modo dinamico in fase di runtime.

Per ulteriori informazioni, consultare l'uso dei pacchetti framework MSIX in modo dinamico dall'app desktop e l'esempio delle Dipendenze Dinamiche.

Distribuire file .winmd nel computer di destinazione

Insieme all'app, consigliamo di procedere e distribuire i file Windows Metadata (.winmd). I metadati possono essere usati da varie API e comportamenti in fase di runtime; la loro assenza può limitare o interromperne le funzionalità. Ad esempio, i metadati possono essere utilizzati per effettuare il marshalling degli oggetti tra apartment; e la necessità di effettuare il marshalling può dipendere dalle prestazioni della macchina. Poiché non esiste un modo deterministico per sapere se sono necessari metadati, è consigliabile distribuire .winmd a meno che non si sia estremamente preoccupati per le dimensioni.