Folyamatközi kommunikáció (IPC)

Ez a témakör a Windows App SDK asztali alkalmazások és más Win32-alkalmazások közötti folyamatközi kommunikáció (IPC) különböző módjait ismerteti. Mivel Windows App SDK asztali alkalmazások teljes megbízhatóságú Win32-folyamatokként futnak, közvetlen hozzáféréssel rendelkeznek az operációs rendszerszintű IPC-mechanizmusokhoz. Egyes mechanizmusok további követelményeket támasztanak az alkalmazások MSIX-sel való csomagolásakor, ahogy az az alábbi szakaszokban is látható.

Alkalmazásszolgáltatások

Az appszolgáltatások lehetővé teszik az alkalmazások számára, hogy olyan szolgáltatásokat tegyenek elérhetővé, amelyek a háttérben elfogadják és visszaadják a primitívek tulajdonságcsomagjait (ValueSet). A gazdag objektumok akkor továbbíthatók, ha szerializálva vannak.

Az alkalmazásszolgáltatások futtathatók háttérfeladatként vagy az előtérben futó alkalmazáson belül.

Note

Az appszolgáltatások csomagidentitású, csomagolt alkalmazást igényelnek. Ezek az MSIX-csomagolást használó Windows App SDK-alkalmazások számára érhetők el.

Az alkalmazásszolgáltatások kis mennyiségű adat megosztására használhatók, ahol nincs szükség közel valós idejű késésre.

COM

A COM egy elosztott objektumorientált rendszer olyan bináris szoftverkomponensek létrehozására, amelyek képesek egymással kölcsönhatásba lépni és kommunikálni. Fejlesztőként a COM használatával hozhat létre újrahasználható szoftverösszetevőket és automatizálási rétegeket egy alkalmazáshoz. A COM-összetevők lehetnek folyamatban vagy folyamaton kívül, és ügyfél- és kiszolgálómodellen keresztül kommunikálhatnak. A folyamaton kívüli COM-kiszolgálókat régóta használják objektumközi kommunikációra.

A runFullTrust képességgel rendelkező csomagolt alkalmazások a csomagjegyzéken keresztül regisztrálhatják a folyamaton kívüli COM-kiszolgálókat az IPC-hez. Ezt csomagolt COM-nak nevezzük.

Windows App SDK asztali alkalmazások teljes megbízhatósági folyamatként futnak, így közvetlenül a Windows Beállításjegyzéken keresztül is regisztrálhatnak és használhatnak COM-kiszolgálókat, akárcsak a hagyományos Win32-alkalmazások.

Filesystem

BroadFileSystemAccess

A csomagolt alkalmazások a broadFileSystemAccess korlátozott képesség deklarálásával a széles fájlrendszeren keresztül végezhetnek IPC-t. Ez a képesség Windows.Storage API-k és Win32 FromApp API-k számára hozzáférést biztosít a teljes fájlrendszerhez.

Alapértelmezés szerint a csomagolt alkalmazások fájlrendszeren keresztüli IPC-jének korlátozása az ebben a szakaszban ismertetett egyéb mechanizmusokra korlátozódik.

PublisherCacheFolder

A PublisherCacheFolder lehetővé teszi, hogy a csomagolt alkalmazások deklarálják a jegyzékben lévő mappákat, amelyeket ugyanaz a közzétevő megoszthat más csomagokkal.

A megosztott tármappa a következő követelményekkel és korlátozásokkal rendelkezik:

  • A megosztott tárolómappában lévő adatokról nem készül biztonsági mentés, és nem vándorolnak a felhasználóval.
  • A felhasználó törölheti a megosztott tármappa tartalmát.
  • A megosztott tármappával nem oszthat meg adatokat a különböző közzétevők alkalmazásaiban.
  • A megosztott tármappával nem oszthat meg adatokat a különböző felhasználók között.
  • A megosztott tármappa nem rendelkezik verziókezeléssel.

Ha több alkalmazást tesz közzé, és egy egyszerű mechanizmust keres az adatok megosztására közöttük, akkor a PublisherCacheFolder egy egyszerű fájlrendszer-alapú lehetőség.

Csövek

A csövek egyszerű kommunikációt tesznek lehetővé egy csőkiszolgáló és egy vagy több cső-ügyfél között.

A névtelen csöveket és a nevesített csöveket a következő korlátozások támogatják:

  • Alapértelmezés szerint a csomagolt alkalmazásokban lévő elnevezett csövek csak az ugyanazon a csomagon belüli folyamatok között támogatottak, kivéve, ha egy folyamat teljes megbízhatóságú.
  • A nevesített csövek a megnevezett objektumok megosztására vonatkozó irányelveknek megfelelően oszthatók meg a csomagok között.
  • A csomagolt alkalmazásokban a csőnévnek tartalmaznia kell a LOCAL\ elemet (például: \\.\pipe\LOCAL\<pipename>). A LOCAL\ szegmens hatóköre a hívó bejelentkezési munkamenetére terjed ki, és az MSIX-csomagba csomagolt alkalmazásokhoz szükséges. .NET API-k, például a(z) NamedPipeServerStream használatakor csak a(z) LOCAL\<pipename> részt adja át — a(z) \\.\pipe\ előtagot a rendszer belsőleg kezeli.

A Windows App SDK asztali alkalmazásai teljes megbízhatóságú folyamatokként futnak, ezért ugyanazon csomagra vonatkozó korlátozás nélkül hozhatnak létre és használhatnak névvel ellátott csatornákat. Ha azonban egy másik csomagolt alkalmazással kommunikál, amely nem rendelkezik teljes megbízhatósággal, a fenti korlátozások továbbra is érvényesek.

Elnevezett cső – példa (C#)

Az alábbi példa egy teljes elnevezett csőkiszolgálót és ügyfélalkalmazást mutat be két konzolalkalmazás formájában. Mivel a Windows App SDK asztali alkalmazásai teljes megbízhatóságú folyamatok, az elnevezett csöveken keresztüli folyamatközi kommunikáció különleges képességek vagy manifestbejegyzések nélkül is működik.

A példa kipróbálásához hozzon létre két konzolalkalmazás-projektet (amelyek célja a net8.0-windows, és a ImplicitUsings engedélyezve van), majd először futtassa a kiszolgálót, ezután a klienst egy külön terminálban.

Csőszerver — létrehoz egy névvel ellátott csövet, és visszaküldi az üzeneteket a kliensnek:

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.");

Csőügyfél – csatlakozik a kiszolgálóhoz, és felhasználói bemenetet küld:

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.");

Mindkét alkalmazás futtatásakor az ügyfél olyan üzeneteket küld, amelyeket a kiszolgáló visszahangzik, megerősítve a folyamatközi kommunikációt két teljes megbízhatóságú asztali folyamat között, speciális konfiguráció nélkül.

Registry

A Beállításjegyzék használata IPC-hez általában nem javasolt, de a meglévő kód esetén támogatott. A csomagolt alkalmazások csak azokhoz a beállításkulcsokhoz férhetnek hozzá, amelyekhez hozzáféréssel rendelkeznek.

A csomagolt asztali alkalmazások (lásd : MSIX-csomag létrehozása a kódból) a beállításjegyzék virtualizálását használják, hogy a globális beállításjegyzék-írások az MSIX-csomagban lévő privát hive-ben legyenek tárolva. Ez lehetővé teszi a forráskódok kompatibilitását, miközben minimalizálja a globális beállításjegyzékre gyakorolt hatást, és IPC-hez használható az ugyanabban a csomagban lévő folyamatok között. Ha a beállításjegyzéket kell használnia, ezt a modellt részesíti előnyben a globális beállításjegyzék módosítása helyett.

RPC

Az RPC használható a csomagolt alkalmazások Win32 RPC-végponthoz való csatlakoztatásához, feltéve, hogy a csomagolt alkalmazás megfelelő képességekkel rendelkezik az RPC-végpont ACL-einek megfelelően.

Az egyéni képességek lehetővé teszik az OEM-ek és az IHV-k számára, hogy tetszőleges képességeket határozzanak meg, az RPC-végpontjaikhoz ezek alapján hozzáférés-vezérlést rendeljenek, majd megadják ezeket a képességeket a jogosult ügyfélalkalmazásoknak. A teljes mintaalkalmazásért tekintse meg a CustomCapability mintát.

Az RPC-végpontok ACLed típusúak is lehetnek adott csomagolt alkalmazásokhoz, így a végponthoz való hozzáférés csak ezekre az alkalmazásokra korlátozható anélkül, hogy az egyéni képességek felügyeleti többletterhelése kellene. A DeriveAppContainerSidFromAppContainerName API használatával levezethet egy SID-azonosítót egy csomagcsalád nevéből, majd a CustomCapability mintában bemutatott módon ACL-t alkalmazhat az RPC-végponton ezzel a SID-del.

Megosztott memória

A fájlleképezéssel megoszthat egy fájlt vagy memóriát két vagy több folyamat között az alábbi korlátozásokkal:

  • Alapértelmezés szerint a csomagolt alkalmazások fájlleképezései csak az ugyanabban a csomagban lévő folyamatok között támogatottak, kivéve, ha egy folyamat teljes megbízhatóságú.
  • A fájlleképezések a megnevezett objektumok megosztására vonatkozó irányelveket követve oszthatók meg a csomagok között.

Windows App SDK asztali alkalmazások teljes megbízhatósági folyamatként futnak, így korlátozás nélkül hozhatnak létre és használhatnak megosztott memóriafájl-leképezéseket. Ha egy másik, nem teljes megbízhatósággal rendelkező csomagolt alkalmazással kommunikál, használja a névvel ellátott objektumok megosztásában leírt ACL-megközelítést.

A megosztott memória nagy mennyiségű adat hatékony megosztásához és manipulálásához ajánlott.

Loopback

A loopback az a folyamat, amelynek során a localhoston (a loopback-címen) figyelő hálózati kiszolgálóval kommunikálunk.

A biztonság és a hálózatelkülönítés fenntartása érdekében az IPC-hez tartozó visszacsatolási kapcsolatok alapértelmezés szerint le vannak tiltva a csomagolt alkalmazások esetében. A képességek és a manifesztumtulajdonságok használatával engedélyezheti a loopback-kapcsolatokat a megbízható csomagolt alkalmazások között.

  • A visszacsatolási kapcsolatokban részt vevő összes csomagolt alkalmazásnak deklarálnia kell a képességet a privateNetworkClientServercsomagjegyzékekben.
  • Két csomagolt alkalmazás loopbacken keresztül kommunikálhat egymással, ha a csomagjegyzékükben deklarálják a LoopbackAccessRules elemet.
    • Minden alkalmazásnak fel kell sorolnia a másikat a LoopbackAccessRulesben. Az ügyfél "out" szabályt deklarál a kiszolgálóhoz, a kiszolgáló pedig "in" szabályokat deklarál a támogatott ügyfelek számára.

Note

Az ezekben a szabályokban szereplő alkalmazások azonosításához szükséges csomagcsalád neve a Visual Studio csomagjegyzék-szerkesztőjében található a fejlesztési idő alatt, a Partnerközponton keresztül a Microsoft Store közzétett alkalmazásokhoz, vagy a Get-AppxPackage PowerShell parancson keresztül a már telepített alkalmazásokhoz.

A csomagolatlan alkalmazások és szolgáltatások nem rendelkeznek csomagidentitással, ezért nem deklarálhatók a LoopbackAccessRulesben. A csomagolt alkalmazásokat úgy konfigurálhatja, hogy visszacsatoláson keresztül csatlakozzanak a kicsomagolt alkalmazásokhoz és szolgáltatásokhoz aCheckNetIsolation.exekeresztül, de ez csak olyan mellékbetöltési vagy hibakeresési helyzetekben lehetséges, ahol helyi hozzáféréssel rendelkezik a géphez, és rendszergazdai jogosultságokkal rendelkezik.

  • Ha egy csomagolt alkalmazás csomagolatlan alkalmazáshoz vagy szolgáltatáshoz csatlakozik, futtassa CheckNetIsolation.exe LoopbackExempt -a -n=<PACKAGEFAMILYNAME> a visszacsatolási kivétel hozzáadását a csomagolt alkalmazáshoz.
  • Ha egy csomagolatlan alkalmazás vagy szolgáltatás egy csomagolt alkalmazáshoz csatlakozik, futtassa CheckNetIsolation.exe LoopbackExempt -is -n=<PACKAGEFAMILYNAME> , hogy a csomagolt alkalmazás bejövő visszacsatolási kapcsolatokat fogadhasson.

Note

A(z) CheckNetIsolation.exe-n kapcsolójához szükséges csomagcsaládnév fejlesztés során a Visual Studio csomagjegyzék-szerkesztőjében, a Microsoft Store-on keresztül közzétett alkalmazások esetében a Partner Center felületén, illetve a már telepített alkalmazásoknál a Get-AppxPackage PowerShell-paranccsal található meg.

IPC-mechanizmus kiválasztása

Az alábbi táblázat összefoglalja az IPC-mechanizmusokat és azok legjobb használati eseteit:

Mechanizmus Legjobb a számára Requirements
Alkalmazásszolgáltatások Kis adatcsere tulajdonságcsomagokkal Csomagolt alkalmazás csomagidentitással
COM Újrafelhasználható összetevők, automatizálási rétegek Nincs (Win32) vagy csomagjegyzék (csomagolt COM)
Névvel ellátott csövek Streamalapú kétirányú kommunikáció Nincs teljes megbízhatóságú alkalmazások esetén
Megosztott memória Nagy adatmennyiség, nagy teljesítmény Nincs teljes megbízhatóságú alkalmazásokhoz
RPC Elosztott ügyfél-/kiszolgálóprogramok Az ACL-nek engedélyeznie kell a hozzáférést
Registry Régi kódkompatibilitás Új kódhoz nem ajánlott
Loopback Hálózati protokollok (TCP/UDP) privateNetworkClientServer a csomagolt alkalmazások képessége