Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo argomento illustra vari modi per eseguire la comunicazione interprocesso (IPC) tra SDK per app di Windows app desktop e altre applicazioni Win32. Poiché SDK per app di Windows app desktop vengono eseguite come processi Win32 completamente attendibili, hanno accesso diretto a tutti i meccanismi IPC a livello di sistema operativo. Alcuni meccanismi hanno requisiti aggiuntivi quando le app vengono incluse in pacchetti con MSIX, come indicato nelle sezioni seguenti.
Servizi app
I servizi delle app consentono alle applicazioni di esporre servizi che accettano e restituiscono raccolte di proprietà di tipi primitivi (ValueSet) in esecuzione in background. Gli oggetti complessi possono essere trasmessi se vengono serializzati.
I servizi app possono essere eseguiti sia fuori processo come attività in background, sia nel processo all'interno dell'applicazione in primo piano.
Note
I servizi delle app richiedono un'app pacchettizzata dotata di identità del pacchetto. Sono disponibili per le app SDK per app di Windows che usano il pacchetto MSIX.
I servizi app sono usati meglio per la condivisione di piccole quantità di dati, in cui non è necessaria la latenza quasi in tempo reale.
COM
COM è un sistema distribuito orientato agli oggetti per la creazione di componenti software binari che possono interagire e comunicare. Gli sviluppatori usano COM per creare componenti software riutilizzabili e livelli di automazione per un'applicazione. I componenti COM possono essere in fase di elaborazione o fuori processo e possono comunicare tramite un modello client e server . I server COM out-of-process sono stati usati da tempo come mezzo per la comunicazione tra oggetti.
Le applicazioni in pacchetto dotate della funzionalità runFullTrust possono registrare server COM out-of-process per l'IPC mediante il manifest del pacchetto. Questa operazione è nota come COM in pacchetto.
SDK per app di Windows le app desktop vengono eseguite come processi completamente attendibili, in modo da poter anche registrare e usare i server COM direttamente tramite il Registro di sistema Windows, proprio come le tradizionali applicazioni Win32.
Filesystem
BroadFileSystemAccess
Le applicazioni pacchettizzate possono effettuare IPC usando il file system esteso dichiarando la funzionalità con restrizioni broadFileSystemAccess. Questa funzionalità consente alle API Windows.Storage e alle API Win32 FromApp di accedere al file system esteso.
Per impostazione predefinita, IPC tramite il file system per le applicazioni in pacchetto è limitato agli altri meccanismi descritti in questa sezione.
PublisherCacheFolder
PublisherCacheFolder consente alle applicazioni in pacchetto di dichiarare cartelle nel manifesto che possono essere condivise con altri pacchetti dallo stesso editore.
La cartella di archiviazione condivisa presenta i requisiti e le restrizioni seguenti:
- I dati nella cartella di archiviazione condivisa non vengono sottoposti a backup o a roaming.
- L'utente può cancellare il contenuto della cartella di archiviazione condivisa.
- Non è possibile usare la cartella di archiviazione condivisa per condividere i dati tra applicazioni di server di pubblicazione diversi.
- Non è possibile usare la cartella di archiviazione condivisa per condividere i dati tra utenti diversi.
- La cartella di archiviazione condivisa non ha la gestione delle versioni.
Se si pubblicano più applicazioni e si sta cercando un semplice meccanismo per condividere i dati tra di essi, PublisherCacheFolder è un'opzione semplice basata su file system.
Tubi
Le pipe consentono una semplice comunicazione tra un server pipe e uno o più client pipe.
Le pipe anonime e le pipe denominate sono supportate con i seguenti vincoli:
- Per impostazione predefinita, le named pipe nelle applicazioni in pacchetto sono supportate solo tra processi all'interno dello stesso pacchetto, a meno che un processo non sia completamente attendibile.
- Le named pipe possono essere condivise tra pacchetti seguendo le linee guida per la condivisione di oggetti denominati.
- Le named pipe nelle app pacchettizzate devono includere
LOCAL\nel nome della pipe, ad esempio\\.\pipe\LOCAL\<pipename>. Il segmentoLOCAL\limita la pipe alla sessione di accesso dell'utente chiamante ed è necessario per le app pacchettizzate con MSIX. Quando si utilizzano API .NET comeNamedPipeServerStream, passare solo la parteLOCAL\<pipename>: il prefisso\\.\pipe\è gestito internamente.
Le app desktop di SDK per app di Windows vengono eseguite come processi attendibili, quindi possono creare e usare pipe denominate senza la restrizione del medesimo pacchetto. Tuttavia, se stai comunicando con un'altra app in pacchetto che non ha attendibilità totale, i vincoli precedenti si applicano ancora.
Esempio di una named pipe (C#)
Nell'esempio seguente viene illustrato un server named pipe completo e un client come due applicazioni console. Poiché SDK per app di Windows le app desktop sono processi con attendibilità totale, la named pipe IPC funziona senza funzionalità speciali o voci di manifesto.
Per provare questo esempio, creare due progetti di app console (con destinazione net8.0-windowsImplicitUsings abilitata) ed eseguire prima il server, quindi il client in un terminale separato.
Server di pipe — crea una pipe con nome e rinvia i messaggi al client:
using System.Text;
string PipeName = @"LOCAL\WinAppSdkIpcDemo";
Console.WriteLine("Named Pipe Server");
Console.WriteLine($" Process ID: {Environment.ProcessId}");
Console.WriteLine($" User: {Environment.UserName}");
Console.WriteLine($" Pipe: \\\\.\\pipe\\{PipeName}");
Console.WriteLine();
using var server = new System.IO.Pipes.NamedPipeServerStream(
PipeName,
System.IO.Pipes.PipeDirection.InOut,
maxNumberOfServerInstances: 1,
System.IO.Pipes.PipeTransmissionMode.Message,
System.IO.Pipes.PipeOptions.Asynchronous);
Console.WriteLine("Waiting for client...");
await server.WaitForConnectionAsync();
Console.WriteLine("Client connected!");
byte[] buffer = new byte[4096];
while (server.IsConnected)
{
try
{
int bytesRead = await server.ReadAsync(buffer);
if (bytesRead == 0) break;
string received = Encoding.UTF8.GetString(buffer, 0, bytesRead);
Console.WriteLine($" Received: \"{received}\"");
if (received.Equals("QUIT", StringComparison.OrdinalIgnoreCase))
break;
// Echo the message back with the server's process ID
string reply = $"Echo from PID {Environment.ProcessId}: {received}";
await server.WriteAsync(Encoding.UTF8.GetBytes(reply));
await server.FlushAsync();
}
catch (IOException)
{
break;
}
}
Console.WriteLine("Done.");
Client pipe : si connette al server e invia l'input dell'utente:
using System.Text;
string PipeName = @"LOCAL\WinAppSdkIpcDemo";
Console.WriteLine("Named Pipe Client");
Console.WriteLine($" Process ID: {Environment.ProcessId}");
Console.WriteLine();
using var client = new System.IO.Pipes.NamedPipeClientStream(
serverName: ".",
pipeName: PipeName,
System.IO.Pipes.PipeDirection.InOut,
System.IO.Pipes.PipeOptions.Asynchronous);
Console.WriteLine("Connecting...");
await client.ConnectAsync(timeout: 5000);
client.ReadMode = System.IO.Pipes.PipeTransmissionMode.Message;
Console.WriteLine("Connected! Type messages (or QUIT to exit):");
byte[] buffer = new byte[4096];
while (true)
{
Console.Write("> ");
string? input = Console.ReadLine();
if (string.IsNullOrEmpty(input)) continue;
await client.WriteAsync(Encoding.UTF8.GetBytes(input));
await client.FlushAsync();
if (input.Equals("QUIT", StringComparison.OrdinalIgnoreCase))
break;
int bytesRead = await client.ReadAsync(buffer);
string response = Encoding.UTF8.GetString(buffer, 0, bytesRead);
Console.WriteLine($" <- {response}");
}
Console.WriteLine("Done.");
Quando si eseguono entrambe le applicazioni, il client invia messaggi restituiti dal server, confermando la comunicazione tra processi desktop con attendibilità completa senza alcuna configurazione speciale.
Registry
L'utilizzo del Registro di sistema per IPC è in genere sconsigliato, ma è supportato per il codice esistente. Le applicazioni in pacchetto possono accedere solo alle chiavi del Registro di sistema a cui dispongono dell'autorizzazione per l'accesso.
Le app desktop in pacchetto (vedere Creazione di un pacchetto MSIX dal codice) sfruttano la virtualizzazione del Registro di sistema in modo che le scritture globali del Registro di sistema siano contenute in un hive privato all'interno del pacchetto MSIX. Ciò consente la compatibilità del codice sorgente riducendo al minimo l'impatto globale del Registro di sistema e può essere usato per IPC tra processi nello stesso pacchetto. Se è necessario usare il Registro di sistema, questo modello è preferibile rispetto alla modifica del Registro di sistema globale.
RPC
Rpc può essere usato per connettere un'applicazione in pacchetto a un endpoint RPC Win32, a condizione che l'applicazione in pacchetto abbia le funzionalità corrette per corrispondere agli elenchi di controllo di accesso nell'endpoint RPC.
Le funzionalità personalizzate consentono agli OEM e agli IHV di definire funzionalità arbitrarie, ACL con loro gli endpoint RPC e quindi concedere tali funzionalità alle applicazioni client autorizzate. Per un'applicazione di esempio completa, vedere l'esempio CustomCapability .
Gli endpoint RPC possono anche essere protetti tramite ACL per specifiche applicazioni pacchettizzate, in modo da limitare l'accesso all'endpoint esclusivamente a tali applicazioni senza richiedere l'onere di gestione di capacità personalizzate. È possibile usare l'API DeriveAppContainerSidFromAppContainerName per derivare un SID da un nome di famiglia di pacchetti e quindi ACL l'endpoint RPC con il SID, come illustrato nell'esempio CustomCapability .
Memoria condivisa
Il mapping dei file può essere usato per condividere un file o una memoria tra due o più processi con i vincoli seguenti:
- Per impostazione predefinita, le mappature di file nelle applicazioni pacchettizzate sono supportate solo tra processi dello stesso pacchetto, a meno che un processo non sia a attendibilità totale.
- I mapping dei file possono essere condivisi tra pacchetti seguendo le linee guida per la condivisione di oggetti denominati.
Le app desktop di SDK per app di Windows vengono eseguite come processi a piena attendibilità, quindi possono creare e usare mapping di file per la memoria condivisa senza restrizioni. Quando si comunica con un'altra app in pacchetto che non ha attendibilità totale, usare l'approccio ACL descritto nella condivisione di oggetti denominati.
La memoria condivisa è consigliata per condividere e modificare in modo efficiente grandi quantità di dati.
Loopback
Il loopback consiste nel comunicare con un server in rete in ascolto su localhost (l'indirizzo di loopback).
Per mantenere la sicurezza e l'isolamento della rete, le connessioni loopback per IPC vengono bloccate per impostazione predefinita per le applicazioni in pacchetto. È possibile abilitare le connessioni loopback tra applicazioni in pacchetto attendibili usando funzionalità e proprietà del manifesto.
- Tutte le applicazioni in pacchetto che partecipano alle connessioni loopback devono dichiarare la
privateNetworkClientServerfunzionalità nei manifesti del pacchetto. - Due applicazioni in pacchetto possono comunicare tramite loopback dichiarando LoopbackAccessRules all'interno dei manifesti del pacchetto.
- Ogni applicazione deve elencare l'altra nella proprietà LoopbackAccessRules. Il client dichiara una regola "out" per il server e il server dichiara le regole "in" per i client supportati.
Note
Il nome della famiglia di pacchetti necessario per identificare un'applicazione in queste regole è disponibile tramite l'editor del manifesto del pacchetto in Visual Studio durante lo sviluppo, tramite il Centro per i partner per le applicazioni pubblicate tramite il Microsoft Store o tramite il comando PowerShell Get-AppxPackage per le applicazioni già installate.
Le applicazioni e i servizi non in pacchetto non dispongono dell'identità del pacchetto, quindi non possono essere dichiarati in LoopbackAccessRules. È possibile configurare un'applicazione in pacchetto per connettersi tramite loopback con applicazioni e servizi non in pacchetto tramite CheckNetIsolation.exe, ma questo è possibile solo per gli scenari di sideload o debug in cui si dispone dell'accesso locale al computer e si dispone dei privilegi di amministratore.
- Se un'applicazione in pacchetto si connette a un'applicazione o a un servizio non in pacchetto, eseguire
CheckNetIsolation.exe LoopbackExempt -a -n=<PACKAGEFAMILYNAME>per aggiungere un'esenzione di loopback per l'applicazione in pacchetto. - Se un'applicazione o un servizio non in pacchetto si connette a un'applicazione in pacchetto, eseguire
CheckNetIsolation.exe LoopbackExempt -is -n=<PACKAGEFAMILYNAME>per consentire all'applicazione in pacchetto di ricevere connessioni loopback in ingresso.- CheckNetIsolation.exe deve essere in esecuzione in modo continuo mentre l'applicazione in pacchetto è in ascolto delle connessioni.
Note
Il nome della famiglia di pacchetti richiesto per il -n flag di CheckNetIsolation.exe è reperibile tramite l'editor del manifesto del pacchetto in Visual Studio durante lo sviluppo, tramite il Centro per i partner per le applicazioni pubblicate tramite il Microsoft Store o tramite il comando PowerShell Get-AppxPackage per le applicazioni già installate.
Scegliere un meccanismo IPC
La tabella seguente riepiloga i meccanismi IPC e i relativi casi d'uso migliori:
| Meccanismo | Migliore per | Requirements |
|---|---|---|
| Servizi app | Scambio di dati di piccole dimensioni con contenitori di proprietà | App pacchettizzata con identità di pacchetto |
| COM | Componenti riutilizzabili, livelli di automazione | Nessuno (Win32) o manifest del pacchetto (COM pacchettizzato) |
| Named Pipes | Comunicazione bidirezionale basata su flusso | Nessuno per le app con attendibilità totale |
| Memoria condivisa | Dati di grandi dimensioni, prestazioni elevate | Nessuno per le app con attendibilità totale |
| RPC | Programmi client/server distribuiti | Le ACL devono consentire l'accesso |
| Registry | Compatibilità del codice legacy | Sconsigliato per il nuovo codice |
| Loopback | Protocolli basati sulla rete (TCP/UDP) |
privateNetworkClientServer funzionalità per le app in pacchetto |