Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Примечание.
Некоторые сведения относятся к предварительной версии продукта, в которую перед коммерческим выпуском могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
В этой статье описывается создание простого поставщика веб-каналов, который регистрирует URI содержимого веб-канала и реализует интерфейс IFeedProvider . Методы этого интерфейса вызываются доской мини-приложений, чтобы запросить пользовательские параметры запроса, как правило, для поддержки сценариев аутентификации. Поставщики веб-каналов могут поддерживать один веб-канал или несколько веб-каналов.
Сведения о реализации поставщика веб-каналов с помощью C++/WinRT см. в разделе "Реализация поставщика веб-каналов" в приложении Windows C# (C++/WinRT).
Требования
- Устройство должно быть включено в режиме разработчика. Дополнительные сведения см. в разделе "Параметры" для разработчиков.
- Visual Studio 2026 или более поздней версии с рабочей нагрузкой разработки приложений WinUI . Обязательно добавьте компонент для C++ (версии 143) из дополнительного раскрывающегося списка.
Создание консольного приложения C++/WinRT win32
В Visual Studio создайте проект . В диалоговом окне "Создание проекта" установите для фильтра языка значение "C++" и фильтр платформы в Windows, а затем выберите шаблон проекта консольного приложения Windows (C++/WinRT). Назовите новый проект ExampleFeedProvider. Убедитесь, что в этом пошаговом руководстве опция Разместить решение и проект в одном каталоге не отмечена. При появлении запроса задайте целевую версию Windows для приложения 10.022631.2787 или более поздней версии.
Добавьте ссылки на пакеты NuGet Windows App SDK и Windows Implementation Library
В этом примере используется последний стабильный пакет Пакета NuGet для приложений Windows. В Обозреватель решений щелкните правой кнопкой мыши ссылки и выберите пункт "Управление пакетами NuGet...". В диспетчере пакетов NuGet перейдите на вкладку "Обзор" и найдите "Microsoft.WindowsAppSDK". Выберите последнюю стабильную версию в раскрывающемся списке "Версия" , а затем нажмите кнопку "Установить".
В этом примере также используется пакет NuGet библиотеки реализации Windows. В Обозреватель решений щелкните правой кнопкой мыши ссылки и выберите пункт "Управление пакетами NuGet...". В диспетчере пакетов NuGet перейдите на вкладку "Обзор" и найдите "Microsoft.Windows.ImplementationLibrary". Выберите последнюю версию в раскрывающемся списке "Версия" и нажмите кнопку "Установить".
В файле заголовка pch.h предварительно скомпилированного добавьте следующие директивы #include.
//pch.h
#pragma once
#include <wil/cppwinrt.h>
#include <wil/resource.h>
...
#include <winrt/Microsoft.Windows.Widgets.Providers.h>
Примечание.
Перед любыми заголовками WinRT необходимо сначала включить заголовок wil/cppwinrt.h.
Для правильного завершения работы приложения поставщика потоков необходимо реализовать пользовательскую версию winrt::get_module_lock. Мы предварительно объявляем метод SignalLocalServerShutdown , который будет определен в нашем main.cpp файле и установим событие, которое сигнализирует приложению о выходе. Добавьте следующий код в файл pch.h, непосредственно под директивой #pragma once , прежде чем другие включают.
//pch.h
#include <stdint.h>
#include <combaseapi.h>
// In .exe local servers the class object must not contribute to the module ref count, and use
// winrt::no_module_lock, the other objects must and this is the hook into the C++ WinRT ref counting system
// that enables this.
void SignalLocalServerShutdown();
namespace winrt
{
inline auto get_module_lock() noexcept
{
struct service_lock
{
uint32_t operator++() noexcept
{
return ::CoAddRefServerProcess();
}
uint32_t operator--() noexcept
{
const auto ref = ::CoReleaseServerProcess();
if (ref == 0)
{
SignalLocalServerShutdown();
}
return ref;
}
};
return service_lock{};
}
}
#define WINRT_CUSTOM_MODULE_LOCK
Добавьте класс FeedProvider для обработки операций с данными веб-канала
В Visual Studio щелкните правой кнопкой мыши проект
Объявление класса, реализующего интерфейс IFeedProvider
Интерфейс IFeedProvider определяет методы, которые панель виджетов вызывает для запуска операций с поставщиком фидов. Замените пустое определение класса в файле FeedProvider.h следующим кодом. Этот код объявляет структуру, которая реализует интерфейс IFeedProvider и объявляет прототипы для методов интерфейса.
// FeedProvider.h
#pragma once
struct FeedProvider : winrt::implements<FeedProvider, winrt::Microsoft::Windows::Widgets::Feeds::Providers::IFeedProvider>
{
FeedProvider() {}
/* IFeedrovider required functions that need to be implemented */
void OnFeedProviderEnabled(winrt::Microsoft::Windows::Widgets::Feeds::Providers::FeedProviderEnabledArgs args);
void OnFeedProviderDisabled(winrt::Microsoft::Windows::Widgets::Feeds::Providers::FeedProviderDisabledArgs args);
void OnFeedEnabled(winrt::Microsoft::Windows::Widgets::Feeds::Providers::FeedEnabledArgs args);
void OnFeedDisabled(winrt::Microsoft::Windows::Widgets::Feeds::Providers::FeedDisabledArgs args);
void OnCustomQueryParametersRequested(winrt::Microsoft::Windows::Widgets::Feeds::Providers::CustomQueryParametersRequestedArgs args);
/* IFeedProvider required functions that need to be implemented */
};
Реализация методов IFeedProvider
В следующих нескольких разделах мы реализуем методы интерфейса IFeedProvider . Перед погружением в методы интерфейса добавьте следующие строки после директив включения, чтобы включить API поставщика веб-каналов в пространство имен winrt и обеспечить доступ к карте, объявленной на предыдущем шаге.
Примечание.
Объекты, передаваемые в методы обратного вызова интерфейса IFeedProvider , гарантированно допустимы только в обратном вызове. Не следует хранить ссылки на эти объекты, так как их поведение вне контекста обратного вызова не определено.
// WidgetProvider.cpp
namespace winrt
{
using namespace Microsoft::Windows::Widgets::Feeds::Providers;
}
OnFeedProviderEnabled
Метод OnFeedProviderEnabled вызывается, когда веб-канал, связанный с поставщиком, создается хостом Widgets Board. В реализации этого метода создайте строку запроса с параметрами, которые будут переданы URL-адресу, который предоставляет содержимое веб-канала, включая все необходимые маркеры проверки подлинности. Создайте экземпляр CustomQueryParametersUpdateOptions, передавая в FeedProviderDefinitionId из аргумента события, который определяет включенный веб-канал и строку запроса. Получите экземпляр по умолчанию FeedManager и вызовите SetCustomQueryParameters, чтобы зарегистрировать параметры строки запроса на доске виджетов.
// FeedProvider.cs
void FeedProvider::OnFeedProviderEnabled(winrt::Microsoft::Windows::Widgets::Feeds::Providers::FeedProviderEnabledArgs args)
{
std::wstringstream wstringstream;
wstringstream << args.FeedProviderDefinitionId().c_str() << L" feed provider was enabled." << std::endl;
_putws(wstringstream.str().c_str());
auto updateOptions = winrt::CustomQueryParametersUpdateOptions(args.FeedProviderDefinitionId(), L"param1¶m2");
winrt::FeedManager::GetDefault().SetCustomQueryParameters(updateOptions);
}
При отключении поставщика каналов
OnFeedProviderDisabled вызывается в доске Widgets, когда все веб-каналы для этого поставщика отключены. Поставщики веб-каналов не обязаны выполнять какие-либо действия в ответ на вызов этого метода. Вызов метода можно использовать для целей телеметрии или обновления параметров строки запроса или отзыва маркеров проверки подлинности при необходимости. Если приложение поддерживает только одного поставщика веб-каналов или если все поставщики веб-каналов, поддерживаемые приложением, были отключены, приложение может выйти в ответ на этот обратный вызов.
// FeedProvider.cs
void FeedProvider::OnFeedProviderDisabled(winrt::Microsoft::Windows::Widgets::Feeds::Providers::FeedProviderDisabledArgs args)
{
std::wstringstream wstringstream;
wstringstream << args.FeedProviderDefinitionId().c_str() << L" feed provider was disabled." << std::endl;
_putws(wstringstream.str().c_str());
}
OnFeedEnabled, OnFeedDisabled
OnFeedEnabled и OnFeedDisabled вызываются Панелью Виджетов при включении или отключении канала. Поставщики веб-каналов не обязаны выполнять какие-либо действия в ответ на эти вызовы метода. Вызов метода можно использовать для целей телеметрии или обновления параметров строки запроса или отзыва маркеров проверки подлинности при необходимости.
// FeedProvider.cs
void FeedProvider::OnFeedEnabled(winrt::Microsoft::Windows::Widgets::Feeds::Providers::FeedEnabledArgs args)
{
std::wstringstream wstringstream;
wstringstream << args.FeedDefinitionId().c_str() << L" feed was enabled." << std::endl;
_putws(wstringstream.str().c_str());
}
// FeedProvider.cs
void FeedProvider::OnFeedDisabled(winrt::Microsoft::Windows::Widgets::Feeds::Providers::FeedDisabledArgs args)
{
std::wstringstream wstringstream;
wstringstream << args.FeedDefinitionId().c_str() << L" feed was disabled." << std::endl;
_putws(wstringstream.str().c_str());
}
OnCustomQueryParametersRequested
OnCustomQueryParametersRequested возникает, когда Панель виджетов определяет, что пользовательские параметры запроса, связанные с поставщиком канала данных, необходимо обновить. Например, этот метод может вызываться, если операция получения содержимого веб-канала из удаленной веб-службы не удалась. Свойство FeedProviderDefinitionId объекта CustomQueryParametersRequestedArgs , переданное в этот метод, указывает канал, для которого запрашиваются параметры строки запроса. Поставщик должен повторно создать строку запроса и передать ее обратно в доску мини-приложений, вызвав SetCustomQueryParameters.
// FeedProvider.cs
void FeedProvider::OnCustomQueryParametersRequested(winrt::Microsoft::Windows::Widgets::Feeds::Providers::CustomQueryParametersRequestedArgs args)
{
std::wstringstream wstringstream;
wstringstream << L"CustomQueryParameters were requested for " << args.FeedProviderDefinitionId().c_str() << std::endl;
_putws(wstringstream.str().c_str());
auto updateOptions = winrt::CustomQueryParametersUpdateOptions(args.FeedProviderDefinitionId(), L"param1¶m2");
winrt::FeedManager::GetDefault().SetCustomQueryParameters(updateOptions);
}
Регистрация фабрики классов, которая создаст экземпляр FeedProvider по запросу
Добавьте заголовок, определяющий класс FeedProvider, в секцию `includes` в верхней части файла вашего приложения main.cpp. Мы также будем включать мьютекс здесь.
// main.cpp
...
#include "FeedProvider.h"
#include <mutex>
Объявите событие, которое активирует наше приложение для выхода и функцию SignalLocalServerShutdown , которая установит событие. Вставьте следующий код в main.cpp.
// main.cpp
wil::unique_event g_shudownEvent(wil::EventOptions::None);
void SignalLocalServerShutdown()
{
g_shudownEvent.SetEvent();
}
Затем необходимо создать CLSID, который будет использоваться для идентификации поставщика канала для активации COM. Создайте GUID в Visual Studio, перейдя в раздел "Сервис-создание> GUID". Выберите опцию "static const GUID =", нажмите «Копировать», а затем вставьте это в main.cpp. Обновите определение GUID, используя следующий синтаксис C++/WinRT, и назначьте имя переменной GUID — feed_provider_clsid. Оставьте закомментированную версию GUID, так как вам потребуется этот формат позже при упаковке приложения.
// main.cpp
...
// {80F4CB41-5758-4493-9180-4FB8D480E3F5}
static constexpr GUID feed_provider_clsid
{
0x80f4cb41, 0x5758, 0x4493, { 0x91, 0x80, 0x4f, 0xb8, 0xd4, 0x80, 0xe3, 0xf5 }
};
Добавьте следующее определение фабрики классов в main.cpp. Это в основном шаблонный код, который не является специфичным для реализации поставщиков фидов. Обратите внимание, что CoWaitForMultipleObjects ожидает активации события завершения работы до выхода приложения.
// main.cpp
template <typename T>
struct SingletonClassFactory : winrt::implements<SingletonClassFactory<T>, IClassFactory>
{
STDMETHODIMP CreateInstance(
::IUnknown* outer,
GUID const& iid,
void** result) noexcept final
{
*result = nullptr;
std::unique_lock lock(mutex);
if (outer)
{
return CLASS_E_NOAGGREGATION;
}
if (!instance)
{
instance = winrt::make<FeedProvider>();
}
return instance.as(iid, result);
}
STDMETHODIMP LockServer(BOOL) noexcept final
{
return S_OK;
}
private:
T instance{ nullptr };
std::mutex mutex;
};
int main()
{
winrt::init_apartment();
wil::unique_com_class_object_cookie feedProviderFactory;
auto factory = winrt::make<SingletonClassFactory<winrt::Microsoft::Windows::Widgets::Feeds::Providers::IFeedProvider>>();
winrt::check_hresult(CoRegisterClassObject(
feed_provider_clsid,
factory.get(),
CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE,
feedProviderFactory.put()));
DWORD index{};
HANDLE events[] = { g_shudownEvent.get() };
winrt::check_hresult(CoWaitForMultipleObjects(CWMO_DISPATCH_CALLS | CWMO_DISPATCH_WINDOW_MESSAGES,
INFINITE,
static_cast<ULONG>(std::size(events)), events, &index));
return 0;
}
Подготовьте приложение поставщика каналов
В текущем выпуске только пакетированные приложения можно зарегистрировать в качестве поставщиков каналов. Приведенные ниже шаги помогут вам упаковать своё приложение и обновить манифест приложения, чтобы зарегистрировать его в операционной системе в качестве поставщика ленты.
Создание проекта упаковки MSIX
В Обозреватель решений щелкните решение правой кнопкой мыши и выберите "Добавить> новый проект...". В диалоговом окне "Добавление нового проекта" выберите шаблон "Проект упаковки приложений Windows" и нажмите кнопку "Далее". Задайте для имени проекта значение ExampleFeedProviderPackage и нажмите кнопку "Создать". При появлении запроса задайте целевую версию версии 1809 или более поздней и нажмите кнопку "ОК".
Затем щелкните правой кнопкой мыши проект ExampleFeedProviderPackage и выберите
Добавление ссылки на пакет sdk для приложений Windows в проект упаковки
Необходимо добавить ссылку на пакет NuGet Windows App SDK в проект упаковки MSIX. В Обозреватель решений дважды щелкните проект ExampleFeedProviderPackage, чтобы открыть файл ExampleFeedProviderPackage.wapproj. Добавьте следующий xml-код в элемент Project .
<!--ExampleFeedProviderPackage.wapproj-->
<ItemGroup>
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.231116003-experimentalpr">
<IncludeAssets>build</IncludeAssets>
</PackageReference>
</ItemGroup>
Примечание.
Убедитесь, что версия, указанная в элементе PackageReference, соответствует последней стабильной версии, упомянутой на предыдущем шаге.
Если на компьютере уже установлена правильная версия пакета SDK для приложений Windows, и вы не хотите упаковывать среду выполнения пакета в пакет, можно указать зависимость пакета в файле Package.appxmanifest для проекта ExampleFeedProviderPackage.
<!--Package.appxmanifest-->
...
<Dependencies>
...
<PackageDependency Name="Microsoft.WindowsAppRuntime.1.5.233430000-experimental1" MinVersion="2000.638.7.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
...
</Dependencies>
...
Обновление манифеста пакета
В Обозреватель решений щелкните файл правой кнопкой мыши Package.appxmanifest и выберите команду Просмотреть код, чтобы открыть XML-файл манифеста. Затем необходимо добавить некоторые объявления областей имен для расширений пакета приложения, который мы будем использовать. Добавьте следующие определения пространства имен в элемент package верхнего уровня.
<!-- Package.appmanifest -->
<Package
...
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
В элементе Application создайте пустой элемент с именем Extensions. Убедитесь, что это располагается после закрывающего тега uap:VisualElements.
<!-- Package.appxmanifest -->
<Application>
...
<Extensions>
</Extensions>
</Application>
Первым расширением , который необходимо добавить, является расширение ComServer . Это регистрирует точку входа исполняемого файла в ОС. Это расширение является эквивалентом упакованного приложения, регистрирующего COM-сервер установкой ключа реестра, и не является специфичным для поставщиков фидов. Добавьте следующий элемент com:Extension в качестве дочернего элемента Extensions. Измените GUID в атрибуте Id элемента com:Class на GUID, который вы создали на предыдущем шаге.
<!-- Package.appxmanifest -->
<Extensions>
<com:Extension Category="windows.comServer">
<com:ComServer>
<com:ExeServer Executable="ExampleFeedProvider\ExampleFeedProvider.exe" Arguments="-RegisterProcessAsComServer" DisplayName="C++ Feed Provider App">
<com:Class Id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" DisplayName="FeedProvider" />
</com:ExeServer>
</com:ComServer>
</com:Extension>
</Extensions>
Затем добавьте расширение, которое регистрирует приложение в качестве поставщика канала новостей. Вставьте элемент uap3:Extension в следующий фрагмент кода в качестве дочернего элемента Extensions. Обязательно замените атрибут ClassId элемента COM идентификатором GUID, который использовался на предыдущих шагах.
<!-- Package.appxmanifest -->
<Extensions>
...
<uap3:Extension Category="windows.appExtension">
<uap3:AppExtension Name="com.microsoft.windows.widgets.feeds" DisplayName="ContosoFeed" Id="com.examplewidgets.examplefeed" PublicFolder="Public">
<uap3:Properties>
<FeedProvider Icon="ms-appx:Assets\StoreLogo.png" Description="FeedDescription">
<Activation>
<!-- Apps exports COM interface which implements IFeedProvider -->
<CreateInstance ClassId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" />
</Activation>
<Definitions>
<Definition Id="Contoso_Feed"
DisplayName="Contoso_Feed Feed"
Description="Feed representing Contoso"
ContentUri="https://www.contoso.com/"
Icon="ms-appx:Images\StoreLogo.png">
</Definition>
<Definition Id="Fabrikam_Feed"
DisplayName="Fabrikam Feed"
Description="Feed representing Example"
ContentUri="https://www.fabrikam.com/"
Icon="ms-appx:Images\StoreLogo.png">
</Definition>
</Definitions>
</FeedProvider>
</uap3:Properties>
</uap3:AppExtension>
</uap3:Extension>
</Extensions>
Подробные описания и сведения о форматировании всех этих элементов см. в разделе Формат XML манифеста пакета поставщика ленты.
Добавление значков в проект упаковки
В Обозревателе решений щелкните правой кнопкой мыши ExampleFeedProviderPackage и выберите Добавить> папку. Назовите эту папку ProviderAssets так, как это было использовано на Package.appxmanifest предыдущем шаге. Здесь мы будем хранить значок для наших веб-каналов. После добавления нужных значков убедитесь, что имена изображений совпадают с тем, что идет после Path=ProviderAssets\ в Package.appxmanifest, иначе веб-каналы не будут отображаться на панели виджетов.
Тестирование поставщика веб-канала
Убедитесь, что вы выбрали архитектуру, соответствующую компьютеру разработки, в раскрывающемся списке "Платформы решений", например "x64". В Обозреватель решений щелкните решение правой кнопкой мыши и выберите команду "Создать решение". После этого щелкните правой кнопкой мыши ExampleWidgetProviderPackage и выберите «Развернуть». Консольное приложение должно запускаться при развертывании, и вы увидите, что потоки активированы и отображаются в выводе консоли. Откройте Панель виджетов, и вы должны увидеть новые потоки на вкладках в верхней части раздела потоков.
Отладка поставщика веб-канала
После закрепления ваших лент, Платформа виджетов запустит приложение поставщика лент для получения и отправки соответствующей информации о ленте. Чтобы выполнить отладку запущенного веб-канала, можно подключить отладчик к приложению поставщика веб-каналов или настроить Visual Studio для автоматической отладки процесса поставщика веб-каналов после его запуска.
Чтобы подключиться к выполняемой процедуре, выполните следующие действия:
- В Visual Studio щелкните "Отладка—> присоединение к процессу".
- Отфильтруйте процессы и найдите нужное приложение поставщика каналов новостей.
- Подключение отладчика.
Чтобы автоматически подключить отладчик к процессу при первоначальном запуске:
- В Visual Studio щелкните "Отладка "> Другие целевые объекты отладки —> отладка установленного пакета приложения".
- Отфильтруйте пакеты и найдите нужный пакет поставщика веб-каналов.
- Выберите его и установите флажок напротив пункта "Не запускать, но отладка кода при его запуске".
- Нажмите кнопку Присоединить.
Преобразование консольного приложения в приложение Windows
Чтобы преобразовать консольное приложение, созданное в этом пошаговом руководстве, в приложение Windows:
- Щелкните правой кнопкой мыши проект ExampleWidgetProvider в Обозреватель решений и выберите "Свойства". Перейдите к Linker> Система и измените SubSystem с «Console» на «Windows». Это также можно сделать, добавив <SubSystem>Windows</SubSystem> в секцию <Link>..</Link> файла .vcxproj.
- В main.cpp перейдите
int main()наint WINAPI wWinMain(_In_ HINSTANCE /*hInstance*/, _In_opt_ HINSTANCE /*hPrevInstance*/, _In_ PWSTR pCmdLine, _In_ int /*nCmdShow*/).
Публикация приложения поставщика источников контента
После разработки и тестирования поставщика веб-каналов вы можете опубликовать приложение в Microsoft Store, чтобы пользователи могли устанавливать веб-каналы на своих устройствах. Пошаговые инструкции по публикации приложения см. в статье "Публикация приложения в Microsoft Store".
Коллекция магазина веб-каналов
После публикации приложения в Microsoft Store вы можете запросить включение приложения в коллекцию магазинов веб-каналов, которая помогает пользователям обнаруживать приложения, которые содержат веб-каналы Windows. Чтобы отправить запрос, см. «Отправка веб-канала или доски для добавления в коллекцию магазина».
Windows developer