Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом разделе описываются различные способы выполнения межпроцессного взаимодействия (IPC) между классическими приложениями, использующими Windows App SDK, и другими приложениями Win32. Поскольку классические приложения Windows App SDK выполняются как полностью доверенные процессы Win32, они имеют прямой доступ ко всем механизмам межпроцессного взаимодействия на уровне ОС. Некоторые механизмы имеют дополнительные требования, когда приложения упаковываются с помощью MSIX, как описано в разделах ниже.
Услуги для приложений
Службы приложений позволяют приложениям предоставлять службы, принимаюющие и возвращающие пакеты свойств примитивов (ValueSet) в фоновом режиме. Сложные объекты можно передавать, если они были сериализованы.
Службы приложений могут выполняться либо вне процесса как фоновая задача, либо в процессе в приложении переднего плана.
Note
Для служб приложений необходимо упакованное приложение с идентификатором пакета. Они доступны для Windows App SDK приложений, использующих упаковку MSIX.
Службы приложений лучше всего подходят для обмена небольшими объемами данных, когда не требуется почти мгновенный отклик.
КОМ
COM — это распределённая объектно-ориентированная система для создания двоичных программных компонентов, которые могут взаимодействовать друг с другом и обмениваться данными. Разработчик использует COM для создания повторно используемых компонентов программного обеспечения и уровней автоматизации для приложения. Компоненты COM могут находиться в процессе или вне процесса, и они могут взаимодействовать с помощью клиентской и серверной модели. Внепроцессные COM-серверы уже давно используются в качестве средства для обмена данными между объектами.
Упакованные приложения с возможностью runFullTrust могут регистрировать COM-серверы вне процесса для межпроцессного взаимодействия (IPC) в манифесте пакета. Это называется packaged COM.
Классические приложения Windows App SDK запускаются как полностью доверенные процессы, поэтому они также могут регистрировать и использовать COM-серверы непосредственно через реестр Windows, как и традиционные приложения Win32.
Filesystem
BroadFileSystemAccess
Упакованные приложения могут выполнять IPC с помощью широкой файловой системы, объявляя ограниченную broadFileSystemAccess возможность. Эта возможность предоставляет API Windows.Storage и API Win32 FromApp широкий доступ к файловой системе.
По умолчанию IPC через файловую систему для упакованных приложений ограничен другими механизмами, описанными в этом разделе.
PublisherCacheFolder
PublisherCacheFolder позволяет упакованным приложениям объявлять папки в манифесте, к которым можно предоставить общий доступ другим пакетам того же издателя.
Общая папка хранилища имеет следующие требования и ограничения:
- Данные в общей папке хранилища не резервируются или перемещаются.
- Пользователь может очистить содержимое общей папки хранилища.
- Общую папку хранилища нельзя использовать для совместного использования данных между приложениями из разных издателей.
- Вы не можете использовать общую папку хранилища для совместного использования данных между разными пользователями.
- В общей папке хранилища нет управления версиями.
Если вы публикуете несколько приложений и ищете простой механизм для обмена данными между ними, то PublisherCacheFolder — это простой вариант на основе файловой системы.
Трубы
Каналы обеспечивают простой обмен данными между сервером канала и одним или несколькими клиентами канала.
Анонимные каналы и именованные каналы поддерживаются со следующими ограничениями:
- По умолчанию именованные каналы в упакованных приложениях поддерживаются только между процессами в пределах одного пакета, если только один из процессов не является процессом с полным доверием.
- Именованные каналы можно совместно использовать между пакетами, следуя рекомендациям по совместному использованию именованных объектов.
- Имена именованных каналов в упакованных приложениях должны содержать
LOCAL\в имени канала (например,\\.\pipe\LOCAL\<pipename>). СегментLOCAL\определяет канал сеанса входа вызывающего абонента и требуется для приложений, упакованных в MSIX. При использовании API .NET, напримерNamedPipeServerStream, передавайте только частьLOCAL\<pipename>— префикс\\.\pipe\обрабатывается внутри системы.
Классические приложения Windows App SDK запускаются как процессы с полным доверием, поэтому они могут создавать и использовать именованные каналы без ограничения на принадлежность к тому же пакету. Однако если вы взаимодействуете с другим упакованным приложением, которое не имеет полного доверия, ограничения, указанные выше, по-прежнему применяются.
Пример именованного канала (C#)
В следующем примере демонстрируется полный пример сервера и клиента именованного канала в виде двух консольных приложений. Поскольку настольные приложения Windows App SDK работают как процессы с полным доверием, межпроцессное взаимодействие через именованные каналы работает без каких-либо специальных возможностей или записей в манифесте.
Чтобы попробовать этот пример, создайте два проекта консольного приложения (нацеливание net8.0-windows с ImplicitUsings включенным) и сначала запустите сервер, а затем клиент в отдельном терминале.
Сервер канала — создает именованный канал и отправляет сообщения обратно клиенту:
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.");
Клиент канала — подключается к серверу и отправляет входные данные пользователя:
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.");
При запуске обоих приложений клиент отправляет сообщения, которые сервер возвращает обратно, подтверждая межпроцессное взаимодействие между двумя настольными процессами с полным доверием без необходимости в специальной настройке.
Registry
Использование реестра для IPC обычно не рекомендуется, но поддерживается для существующего кода. Упакованные приложения могут получить доступ только к разделам реестра, к которым у них есть разрешение на доступ.
Упакованные классические приложения (см. статью «Создание пакета MSIX из кода») используют виртуализацию реестра, благодаря которой записи в глобальный реестр изолируются в пределах частного куста реестра внутри пакета MSIX. Это обеспечивает совместимость исходного кода при минимизации влияния глобального реестра и может использоваться для IPC между процессами в одном пакете. Если необходимо использовать реестр, этот подход предпочтительнее, чем непосредственное изменение глобального реестра.
RPC
RPC можно использовать для подключения упаковаемого приложения к конечной точке RPC Win32, если упаковаемое приложение имеет правильные возможности для сопоставления списков управления доступом на конечной точке RPC.
Пользовательские возможности позволяют OEM и IHV определять произвольные возможности, ACL своих конечных точек RPC с ними, а затем предоставлять эти возможности авторизованным клиентским приложениям. Полный пример приложения см. в примере CustomCapability .
Конечные точки RPC также могут быть ограничены с помощью ACL для определённых пакетированных приложений, чтобы предоставить доступ к этим конечным точкам только таким приложениям без дополнительных затрат на администрирование настраиваемых возможностей. API DeriveAppContainerSidFromAppContainerName можно использовать, чтобы получить SID из имени семейства пакетов, а затем настроить ACL для конечной точки RPC с этим SID, как показано в примере CustomCapability.
Общая память
Сопоставление файлов можно использовать для совместного использования файла или памяти между двумя или несколькими процессами со следующими ограничениями:
- По умолчанию сопоставления файлов в упакованных приложениях поддерживаются только между процессами в одном пакете, если процесс не является полным доверием.
- Сопоставления файлов можно совместно использовать в пакетах, следуя рекомендациям по совместному использованию именованных объектов.
Настольные приложения Windows App SDK работают как полностью доверенные процессы, поэтому они могут без ограничений создавать и использовать объекты отображения файлов в общей памяти. При взаимодействии с другим упакованным приложением, которое не имеет полного доверия, используйте подход ACL, описанный в совместном использовании именованных объектов.
Для эффективного совместного использования и обработки больших объемов данных рекомендуется разделяемая память.
Loopback
Loopback — это процесс взаимодействия с сетевым сервером, прослушивающим localhost (адрес обратного цикла).
Для обеспечения безопасности и сетевой изоляции loopback-соединения IPC по умолчанию блокируются для упакованных приложений. Вы можете включить loopback-подключения для доверенных упакованных приложений с помощью возможностей и свойств манифеста.
- Все пакетированные приложения, участвующие в loopback-подключениях, должны объявить возможность
privateNetworkClientServerв своих манифестах пакетов. - Два упакованных приложения могут взаимодействовать через loopback, объявив LoopbackAccessRules в манифестах пакета.
- Каждое приложение должно указать другое приложение в своих LoopbackAccessRules. Клиент объявляет для сервера «исходящее» правило, а сервер объявляет «входящие» правила для поддерживаемых им клиентов.
Note
Имя семейства пакетов, необходимое для идентификации приложения в этих правилах, можно найти с помощью редактора манифеста пакета в Visual Studio во время разработки, через Центр партнеров для приложений, опубликованных через Microsoft Store, или с помощью команды Get-AppxPackage PowerShell для уже установленных приложений.
Непакованные приложения и службы не имеют удостоверения пакета, поэтому их нельзя объявить в LoopbackAccessRules. Вы можете настроить упакованное приложение для подключения по loopback к неупакованным приложениям и службам с помощью CheckNetIsolation.exe, однако это возможно только в сценариях боковой загрузки (sideload) или отладки, когда у вас есть локальный доступ к компьютеру и права администратора.
- Если упакованное приложение подключается к неупакованному приложению или службе, выполните команду
CheckNetIsolation.exe LoopbackExempt -a -n=<PACKAGEFAMILYNAME>, чтобы добавить исключение для loopback для упакованного приложения. - Если неупакованное приложение или служба подключается к упакованному приложению, выполните команду
CheckNetIsolation.exe LoopbackExempt -is -n=<PACKAGEFAMILYNAME>, чтобы разрешить упакованному приложению принимать входящие loopback-подключения.- CheckNetIsolation.exe должно выполняться непрерывно, пока упакованое приложение прослушивает подключения.
Note
Имя семейства пакетов, необходимое для -n флага CheckNetIsolation.exe, можно найти с помощью редактора манифеста пакета в Visual Studio во время разработки, через Центр партнеров для приложений, опубликованных через Microsoft Store, или с помощью команды Get-AppxPackage PowerShell для уже установленных приложений.
Выбор механизма IPC
В следующей таблице перечислены механизмы IPC и их лучшие варианты использования:
| Механизм | лучше всего подходит для | Requirements |
|---|---|---|
| Услуги для приложений | Обмен небольшими объёмами данных с помощью контейнеров свойств | Упакованное приложение с идентичностью пакета |
| КОМ | Повторно используемые компоненты, уровни автоматизации | Нет (Win32) или манифест пакета (packaged COM) |
| Именованные каналы | Двунаправленное взаимодействие на основе потока | Нет для приложений с полным доверием |
| Общая память | Большие данные, высокая производительность | Нет для приложений с полным доверием |
| RPC | Распределенные программы клиента и сервера | Списки контроля доступа должны разрешать доступ |
| Registry | Совместимость устаревшего кода | Не рекомендуется для нового кода |
| Loopback | Сетевые протоколы (TCP/UDP) |
privateNetworkClientServer возможность для упакованных приложений |
Связанные материалы
Windows developer