Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Catatan
Beberapa informasi berkaitan dengan produk yang telah dirilis sebelumnya, yang mungkin dimodifikasi secara substansial sebelum dirilis secara komersial. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.
Artikel ini memandu Anda membuat penyedia umpan sederhana yang mendaftarkan URI konten umpan dan mengimplementasikan antarmuka IFeedProvider . Metode antarmuka ini dipanggil oleh Papan Widget untuk meminta parameter string kueri kustom, biasanya untuk mendukung skenario autentikasi. Penyedia umpan dapat mendukung satu umpan atau beberapa umpan.
Untuk menerapkan penyedia umpan menggunakan C++/WinRT, lihat Menerapkan penyedia umpan di aplikasi C# Windows (C++/WinRT).
Prasyarat
- Perangkat Anda harus mengaktifkan mode pengembang. Untuk informasi selengkapnya lihat Pengaturan untuk pengembang.
- Visual Studio 2026 atau yang lebih baru dengan beban kerja pengembangan aplikasi WinUI . Pastikan untuk menambahkan komponen untuk C++ (v143) dari dropdown opsional.
Membuat aplikasi konsol C++/WinRT win32 baru
Di Visual Studio, buat proyek baru. Dalam dialog Buat proyek baru, atur filter bahasa ke "C++" dan filter platform ke Windows, lalu pilih templat proyek Aplikasi Konsol Windows (C++/WinRT). Beri nama proyek baru "ExampleFeedProvider". Untuk panduan ini, pastikan bahwa opsi Tempatkan solusi dan proyek di direktori yang sama tidak dipilih. Saat diminta, atur versi Windows target untuk aplikasi ke 10.022631.2787 atau yang lebih baru.
Menambahkan referensi ke paket NuGet Windows App SDK dan Pustaka Implementasi Windows
Sampel ini menggunakan paket NuGet SDK Aplikasi Windows stabil terbaru. Di Penjelajah Solusi, klik kanan Referensi dan pilih Kelola paket NuGet.... Di manajer paket NuGet, pilih tab Telusuri dan cari "Microsoft.WindowsAppSDK". Pilih versi stabil terbaru di menu drop-down Versi lalu klik Instal.
Sampel ini juga menggunakan paket NuGet Pustaka Implementasi Windows. Di Penjelajah Solusi, klik kanan Referensi dan pilih Kelola paket NuGet.... Di manajer paket NuGet, pilih tab Telusuri dan cari "Microsoft.Windows.ImplementationLibrary". Pilih versi terbaru di menu drop-down Versi lalu klik Instal.
Dalam file header yang telah dikompilasikan sebelumnya, pch.h, tambahkan direktif penyertaan berikut.
//pch.h
#pragma once
#include <wil/cppwinrt.h>
#include <wil/resource.h>
...
#include <winrt/Microsoft.Windows.Widgets.Providers.h>
Catatan
Anda harus menyertakan header wil/cppwinrt.h terlebih dahulu, sebelum header WinRT.
Untuk mengelola mematikan aplikasi penyedia umpan dengan benar, kita memerlukan implementasi kustom dari winrt::get_module_lock. Kami terlebih dahulu mendeklarasikan metode SignalLocalServerShutdown yang akan didefinisikan dalam file main.cpp kami dan akan menetapkan suatu event yang memberi tanda kepada aplikasi untuk keluar. Tambahkan kode berikut ke file pch.h Anda, tepat di bawah #pragma once arahan, sebelum yang lain menyertakan.
//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
Menambahkan kelas FeedProvider untuk menangani operasi umpan
Di Visual Studio, klik ExampleFeedProvider kanan proyek di Penjelajah Solusi dan pilih Add-Class>.
Dalam dialog Tambahkan kelas, beri nama kelas "FeedProvider" dan klik Tambahkan.
Mendeklarasikan kelas yang mengimplementasikan antarmuka IFeedProvider
Antarmuka IFeedProvider mendefinisikan metode yang akan dipanggil Papan Widget untuk memulai operasi dengan penyedia umpan. Ganti definisi kelas kosong dalam file FeedProvider.h dengan kode berikut. Kode ini mendeklarasikan struktur yang mengimplementasikan antarmuka IFeedProvider dan mendeklarasikan prototipe untuk metode antarmuka.
// FeedProvider.h
#pragma once
struct FeedProvider : winrt::implements<FeedProvider, winrt::Microsoft::Windows::Widgets::Feeds::Providers::IFeedProvider>
{
FeedProvider() {}
/* IFeedProvider 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 */
};
Menerapkan metode IFeedProvider
Di beberapa bagian berikutnya, kita akan menerapkan metode antarmuka IFeedProvider . Sebelum membahas metode antarmuka, tambahkan baris berikut ke FeedProvider.cpp, setelah direktif include, untuk memasukkan API penyedia umpan ke dalam namespace winrt dan mengizinkan akses ke peta yang sudah kami deklarasikan di langkah sebelumnya.
Catatan
Objek yang diteruskan ke metode panggilan balik antarmuka IFeedProvider hanya dijamin valid dalam panggilan balik. Anda tidak boleh menyimpan referensi ke objek ini karena perilakunya di luar konteks panggilan balik tidak terdefinisi.
// FeedProvider.cpp
namespace winrt
{
using namespace Microsoft::Windows::Widgets::Feeds::Providers;
}
OnFeedProviderEnabled
Metode OnFeedProviderEnabled dipanggil ketika umpan yang terkait dengan penyedia dibuat oleh host Widgets Board. Dalam implementasi metode ini, buat string kueri dengan parameter yang akan diteruskan ke URL yang menyediakan konten umpan, termasuk token autentikasi yang diperlukan. Buat instans CustomQueryParametersUpdateOptions, dengan melewatkan FeedProviderDefinitionId dari argumen acara yang mengidentifikasi umpan yang diaktifkan serta string kueri. Dapatkan FeedManager default dan panggil SetCustomQueryParameters untuk mendaftarkan parameter string kueri ke Papan Widget.
// FeedProvider.cpp
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);
}
OnFeedProviderDinonaktifkan
OnFeedProviderDisabled dipanggil ketika semua umpan untuk penyedia ini telah dinonaktifkan di Papan Widget. Penyedia umpan tidak diperlukan untuk melakukan tindakan apa pun sebagai respons terhadap panggilan metode ini. Pemanggilan metode dapat digunakan untuk tujuan telemetri atau untuk memperbarui parameter string kueri atau mencabut token autentikasi, jika diperlukan. Jika aplikasi hanya mendukung penyedia umpan tunggal atau jika semua penyedia umpan yang didukung oleh aplikasi telah dinonaktifkan, aplikasi dapat keluar sebagai respons terhadap panggilan balik ini.
// FeedProvider.cpp
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());
}
Saat Umpan Diaktifkan, Saat Umpan Dinonaktifkan
OnFeedEnabled dan OnFeedDisabled dipanggil oleh Papan Widget saat umpan diaktifkan atau dinonaktifkan. Penyedia umpan tidak diperlukan untuk melakukan tindakan apa pun sebagai respons terhadap panggilan metode ini. Pemanggilan metode dapat digunakan untuk tujuan telemetri atau untuk memperbarui parameter string kueri atau mencabut token autentikasi, jika diperlukan.
// FeedProvider.cpp
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.cpp
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 dinaikkan ketika Papan Widget menentukan bahwa parameter kueri kustom yang terkait dengan penyedia umpan perlu di-refresh. Misalnya, metode ini dapat dinaikkan jika operasi untuk mengambil konten umpan dari layanan web jarak jauh gagal. Properti FeedProviderDefinitionId dari CustomQueryParametersRequestedArgs yang diteruskan ke metode ini menentukan umpan tempat param string kueri diminta. Penyedia harus meregenerasi string kueri dan meneruskannya kembali ke Widgets Board dengan memanggil SetCustomQueryParameters.
// FeedProvider.cpp
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);
}
Mendaftarkan kelas pabrik yang akan membuat instans FeedProvider pada permintaan
Tambahkan header yang mendefinisikan kelas FeedProvider ke bagian penyertaan di bagian atas file main.cpp aplikasi Anda. Kami juga akan menyertakan mutex di sini.
// main.cpp
...
#include "FeedProvider.h"
#include <mutex>
Deklarasikan peristiwa yang akan memicu aplikasi kami untuk keluar dan fungsi SignalLocalServerShutdown yang akan mengatur peristiwa. Tempelkan kode berikut di main.cpp.
// main.cpp
wil::unique_event g_shudownEvent(wil::EventOptions::None);
void SignalLocalServerShutdown()
{
g_shudownEvent.SetEvent();
}
Selanjutnya, Anda harus membuat CLSID yang akan digunakan untuk mengidentifikasi penyedia umpan Anda untuk aktivasi COM. Buat GUID di Visual Studio dengan membuka ALAT-Buat> GUID. Pilih opsi "static const GUID =" dan klik Salin lalu tempelkan ke dalam main.cpp. Perbarui definisi GUID dengan sintaks C++/WinRT berikut, atur nama variabel GUID feed_provider_clsid. Biarkan versi GUID yang dikomentari karena Anda akan memerlukan format ini nanti, saat mengemas aplikasi Anda.
// main.cpp
...
// {80F4CB41-5758-4493-9180-4FB8D480E3F5}
static constexpr GUID feed_provider_clsid
{
0x80f4cb41, 0x5758, 0x4493, { 0x91, 0x80, 0x4f, 0xb8, 0xd4, 0x80, 0xe3, 0xf5 }
};
Tambahkan definisi pabrik kelas berikut ke main.cpp. Ini sebagian besar kode boilerplate yang tidak khusus untuk implementasi penyedia umpan. Perhatikan bahwa CoWaitForMultipleObjects menunggu acara penutupan dipicu sebelum aplikasi keluar.
// 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;
}
Mengemas aplikasi penyedia umpan Anda
Dalam rilis saat ini, hanya aplikasi paket yang dapat didaftarkan sebagai penyedia umpan. Langkah-langkah berikut akan membawa Anda melalui proses pengemasan aplikasi Anda dan memperbarui manifes aplikasi untuk mendaftarkan aplikasi Anda dengan OS sebagai penyedia umpan.
Membuat proyek pengemasan MSIX
Di Penjelajah Solusi, klik kanan solusi Anda dan pilih Tambahkan> Proyek Baru.... Dalam dialog Tambahkan proyek baru, pilih templat "Proyek Pengemasan Aplikasi Windows" dan klik Berikutnya. Atur nama proyek ke "ExampleFeedProviderPackage" dan klik Buat. Saat diminta, atur versi target ke versi 1809 atau yang lebih baru dan klik OK. Selanjutnya, klik kanan proyek ExampleFeedProviderPackage dan pilih Tambah-> Referensi Proyek. Pilih proyek ExampleFeedProvider dan klik OK.
Menambahkan referensi paket SDK Aplikasi Windows ke proyek pengemasan
Anda perlu menambahkan referensi ke paket NuGet Windows App SDK ke proyek kemasan MSIX. Di Penjelajah Solusi, klik dua kali proyek ExampleFeedProviderPackage untuk membuka file ExampleFeedProviderPackage.wapproj. Tambahkan xml berikut di dalam elemen Project .
<!--ExampleFeedProviderPackage.wapproj-->
<ItemGroup>
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.231116003-experimentalpr">
<IncludeAssets>build</IncludeAssets>
</PackageReference>
</ItemGroup>
Catatan
Pastikan Versi yang ditentukan dalam elemen PackageReference cocok dengan versi stabil terbaru yang Anda referensikan di langkah sebelumnya.
Jika versi SDK Aplikasi Windows yang benar sudah diinstal di komputer dan Anda tidak ingin membundel runtime SDK dalam paket Anda, Anda dapat menentukan dependensi paket dalam file Package.appxmanifest untuk proyek 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>
...
Memperbarui manifes paket
Di Penjelajah Solusi klik Package.appxmanifest kanan file dan pilih Tampilkan Kode untuk membuka file xml manifes. Selanjutnya, Anda perlu menambahkan beberapa deklarasi namespace untuk ekstensi paket aplikasi yang akan kita gunakan. Tambahkan definisi namespace berikut ke elemen Paket tingkat atas.
<!-- Package.appmanifest -->
<Package
...
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
Di dalam elemen Aplikasi, buat elemen kosong baru bernama Extensions. Pastikan ini muncul setelah tag penutup untuk uap:VisualElements.
<!-- Package.appxmanifest -->
<Application>
...
<Extensions>
</Extensions>
</Application>
Ekstensi pertama yang perlu kita tambahkan adalah ekstensi ComServer . Ini mendaftarkan titik masuk dari executable ke dalam OS. Ekstensi ini adalah aplikasi paket yang setara dengan mendaftarkan server COM dengan mengatur kunci registri, dan tidak khusus untuk penyedia umpan. Tambahkan elemen com:Extension berikut sebagai turunan dari elemen Extensions. Ubah GUID di atribut Id elemen com:Class ke GUID yang Anda buat di langkah sebelumnya.
<!-- 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>
Selanjutnya, tambahkan ekstensi yang mendaftarkan aplikasi sebagai penyedia umpan. Tempelkan elemen uap3:Extension dalam cuplikan kode berikut, sebagai turunan dari elemen Extensions. Pastikan untuk mengganti atribut ClassId elemen COM dengan GUID yang Anda gunakan di langkah sebelumnya.
<!-- 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>
Untuk deskripsi terperinci dan informasi format untuk semua elemen ini, lihat Format XML manifes paket penyedia umpan.
Menambahkan ikon ke proyek kemasan Anda
Di Penjelajah Solusi, klik kanan pada ExampleFeedProviderPackage Anda dan pilih Tambahkan->Folder Baru. Beri nama folder ini ProviderAssets karena inilah yang digunakan di Package.appxmanifest dari langkah sebelumnya. Di sinilah kami akan menyimpan Ikon kami untuk umpan kami. Setelah Anda menambahkan Ikon yang Anda inginkan , pastikan nama gambar cocok dengan apa yang muncul setelah Path=ProviderAssets\ di umpan Anda Package.appxmanifest atau tidak akan muncul di Papan Widget.
Menguji penyedia umpan Anda
Pastikan Anda telah memilih arsitektur yang cocok dengan komputer pengembangan Anda dari menu dropdown Solusi Platform, misalnya "x64". Di Penjelajah Solusi, klik kanan solusi Anda dan pilih Bangun Solusi. Setelah ini selesai, klik kanan pada ExampleWidgetProviderPackage Anda dan pilih Deploy. Aplikasi konsol harus diluncurkan ketika di-deploy dan Anda akan melihat umpan diaktifkan dalam output konsol. Buka Papan Widget dan Anda akan melihat umpan baru di tab di sepanjang bagian atas umpan.
Memecahkan masalah penyedia umpan Anda
Setelah Anda menyematkan umpan, Platform Widget akan memulai aplikasi penyedia umpan Anda untuk menerima dan mengirim informasi yang relevan tentang umpan. Untuk men-debug umpan yang sedang berjalan, Anda dapat melampirkan debugger ke aplikasi penyedia umpan yang sedang berjalan atau Anda dapat menyiapkan Visual Studio untuk secara otomatis mulai men-debug proses penyedia umpan setelah dimulai.
Agar terhubung ke proses yang sedang berjalan:
- Di Visual Studio klik Debug -> Lampirkan ke proses.
- Filter proses dan temukan aplikasi penyedia umpan yang Anda inginkan.
- Pasang debugger.
Untuk melampirkan debugger secara otomatis ke proses ketika proses baru saja dimulai:
- Di Visual Studio klik Debug -> Target Debug Lainnya -> Debug Paket Aplikasi terinstal.
- Filter paket dan temukan paket penyedia umpan yang Anda inginkan.
- Pilih dan centang kotak yang mengatakan Jangan luncurkan, tetapi debug kode saya saat dimulai.
- Klik Lampirkan.
Mengonversi aplikasi konsol Anda ke aplikasi Windows
Untuk mengonversi aplikasi konsol yang dibuat dalam panduan ini ke aplikasi Windows:
- Klik kanan pada proyek ExampleWidgetProvider di Penjelajah Solusi dan pilih Properti. Navigasi ke Linker -> Sistem dan ubah SubSistem dari "Konsol" ke "Windows". Ini juga dapat dilakukan dengan menambahkan <SubSystem>Windows</SubSystem> ke <Link>..</Link> bagian dari .vcxproj.
- Di main.cpp, ubah
int main()keint WINAPI wWinMain(_In_ HINSTANCE /*hInstance*/, _In_opt_ HINSTANCE /*hPrevInstance*/, _In_ PWSTR pCmdLine, _In_ int /*nCmdShow*/).
Menerbitkan aplikasi penyedia umpan Anda
Setelah mengembangkan dan menguji penyedia umpan, Anda dapat menerbitkan aplikasi di Microsoft Store agar pengguna dapat menginstal umpan di perangkat mereka. Untuk panduan langkah demi langkah untuk menerbitkan aplikasi, lihat Menerbitkan aplikasi Anda di Microsoft Store.
Koleksi Toko Umpan
Setelah aplikasi diterbitkan di Microsoft Store, Anda dapat meminta aplikasi Anda disertakan dalam Kumpulan Penyimpanan umpan yang membantu pengguna menemukan aplikasi yang menampilkan umpan Windows. Untuk mengirimkan permintaan Anda, lihat Mengajukan Umpan/Papan Anda agar ditambahkan ke Koleksi Toko.
Windows developer