Megosztás a következőn keresztül:


Windows futtatókörnyezeti API-k meghívása asztali alkalmazásokban

Ez a témakör azt ismerteti, hogyan állíthatja be asztali alkalmazásprojekteit a Windows operációs rendszer által biztosított Windows Futtatókörnyezet (WinRT) API-k használatára, és hogyan adhat hozzá modern Windows 11- és Windows 10-szolgáltatásokat az asztali alkalmazásokhoz.

Egyes Windows-futtatókörnyezeti (WinRT-) API-k asztali alkalmazásokban nem támogatottak. További információért lásd: A Windows Runtime API-k, amelyeket nem támogatnak asztali alkalmazásokban.

.NET-projekt módosítása Windows Runtime API-k használatára

A .NET-projekteknek számos lehetősége van:

  • A .NET 6-tól kezdve a Projektfájlban megadhatja a Target Framework Moniker (TFM) elemet a WinRT API-k eléréséhez. Ez a beállítás támogatott a Windows 10 1809-es vagy újabb verzióját célzó projektekben.
  • A .NET korábbi verzióihoz telepítheti a Microsoft.Windows.SDK.Contracts NuGet-csomagot, hogy minden szükséges hivatkozást hozzáadjon a projekthez. Ez a beállítás támogatott a Windows 10 1803-ás vagy újabb verzióját célzó projektekben.
  • Ha a projekt többcélú .NET 6 (vagy újabb) és a korábbi .NET verziókat célozza meg, akkor a projektfájlt úgy konfigurálhatja, hogy mindkét beállítást használja.

.NET 6 és újabb verziók: A Target Framework Moniker lehetőség használata

Ez a beállítás csak a .NET 6 -ot (vagy újabb verziót) használó és a Windows 10 1809-es vagy újabb operációsrendszer-kiadást megcélzott projektekben támogatott. Ha a projektfájlban megad egy Windows operációs rendszer verzióspecifikus TFM-et, egy hivatkozás hozzáadódik a megfelelő Windows SDK célcsomag-hez. A forgatókönyvről további háttérinformációkat Windows API-k meghívása a .NET-című blogbejegyzésben talál.

  1. Ha a projekt meg van nyitva a Visual Studióban, kattintson a jobb gombbal a projektre Megoldáskezelő, és válassza a Projektfájl szerkesztéselehetőséget. A projektfájl ehhez hasonlóan fog kinézni.

    Jegyzet

    Az alábbi példában egy WinExeOutputType látható, amely egy végrehajtható Windows-grafikus felhasználói felületet határoz meg (és megakadályozza, hogy a konzolablak megnyíljon az alkalmazás futtatásakor). Ha az alkalmazás nem rendelkezik grafikus felhasználói felülettel, akkor a OutputType értéke eltérő lesz. A WinRT API-kat Windows GUI-alkalmazásokból, konzolalkalmazásokból és kódtárakból hívhatja meg. Emellett előfordulhat, hogy TargetFramework értéke nem felel meg pontosan az alábbi példának.

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <OutputType>WinExe</OutputType>
        <TargetFramework>net8.0</TargetFramework>
      </PropertyGroup>
    </Project>
    
  2. Az összes többi beállítást hagyja meg, cserélje le a TargetFramework elem értékét az alábbi sztringek egyikére:

    • net8.0-windows10.0.17763.0: Ha az alkalmazás a Windows 10 1809-es verzióját célozza meg.
    • net8.0-windows10.0.18362.0: Ha az alkalmazás a Windows 10 1903-as verzióját célozza meg.
    • net8.0-windows10.0.19041.0: Ha az alkalmazás a Windows 10 2004-es verzióját célozza meg.
    • net8.0-windows10.0.22000.0: Ha az alkalmazás a Windows 11 kezdeti kiadását célozza.
    • net8.0-windows10.0.22621.0: Ha az alkalmazás a Windows 11-es, 22H2-es verziót célozza.
    • net8.0-windows10.0.26100.0: Ha az alkalmazás a Windows 11-es, 24H2-es verziót célozza.

    A következő elem például a Windows 10 2004-es verzióját megcélzó projekthez tartozik.

    <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
    

    A .NET későbbi verzióiban az értéket lecserélheti a megfelelő verzióra, például net8.0-windows10.0.19041.0.

  3. Mentse a módosításokat, és zárja be a projektfájlt.

A WinRT API-k nem támogatottak a .NET 6-os vagy újabb verzióiban

A .NET 6-os és újabb verzióiban a Windows.UI több Windows Runtime (WinRT) API-t is tartalmaz, amelyek nem támogatottak a Windows.UI névtérben. Az alább felsorolt API-k esetében az API-k egyenértékű verziói léteznek a WinUI (Microsoft.UI) névtérben (például Microsoft.UI.Text). A következő WinRT API-k nem támogatottak a .NET 6-os és újabb verzióiban:

Több Windows operációsrendszer-verzió támogatása

A Windows operációs rendszer konkrét verziójához tartozó TargetFramework tulajdonság határozza meg az SDK-verziót, amellyel az alkalmazást lefordították. Ez a tulajdonság határozza meg az akadálymentes API-k készletét a létrehozáskor, és alapértelmezett értékeket biztosít TargetPlatformVersion és TargetPlatformMinVersion (ha nincs explicit módon beállítva). A TargetPlatformVersion tulajdonságot nem kell explicit módon definiálni a projektfájlban, mivel azt automatikusan a TargetFramework operációsrendszer-verzió állítja be.

A TargetPlatformMinVersion felülbírálható, hogy kisebb legyen, mint a TargetPlatformVersion (amelyet a TargetFramework tulajdonság verziója határoz meg). Ez lehetővé teszi, hogy egy alkalmazás korábbi operációsrendszer-verziókon fusson. A projektfájlban például az alábbiakat állíthatja be, hogy az alkalmazás a Windows 10 1809-es verziójára csökkenjen.

<Project Sdk="Microsoft.NET.Sdk">
 <PropertyGroup>
   <OutputType>WinExe</OutputType>
   <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
   <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
 </PropertyGroup>
</Project>

Vegye figyelembe, hogy ha a TargetPlatformMinVersion alacsonyabb verzióra van állítva, mint a TargetPlatformVersion, akkor lehetőséget teremt a nem elérhető API-k meghívására. Ha olyan WinRT API-kat hív meg, amelyek nem minden támogatott operációsrendszer-verzióban érhetők el, javasoljuk, hogy ezeket a hívásokat ApiInformation-ellenőrzésekkel védje. További információ: Adaptív verziójú alkalmazások.

A .NET korábbi verziói: A Microsoft.Windows.SDK.Contracts NuGet csomag telepítése

Ezt a lehetőséget akkor használja, ha az alkalmazás .NET Core 3.x vagy .NET-keretrendszert használ. Ez a beállítás támogatott a Windows 10 1803-ás vagy újabb verzióját célzó projektekben.

  1. Győződjön meg arról, hogy csomaghivatkozások engedélyezve vannak:

    1. A Visual Studióban kattintson Eszközök –> NuGet-csomagkezelő –> Csomagkezelő beállításaielemre.
    2. Győződjön meg arról, hogy a PackageReference van kiválasztva az alapértelmezett csomagkezelési formátumszámára.
  2. Ha a projekt meg van nyitva a Visual Studióban, kattintson a jobb gombbal a projektre Megoldáskezelő, és válassza a NuGet-csomagok kezeléselehetőséget.

  3. A NuGet Package Manager ablakban válassza a Böngészés lapot, és keressen Microsoft.Windows.SDK.Contracts.

  4. Miután megtalálta a Microsoft.Windows.SDK.Contracts csomagot, a NuGet Package Manager ablakának jobb ablaktábláján válassza ki a telepíteni kívánt csomag Verzió a megcélzni kívánt Windows 10-verzió alapján:

    • 10.0.19041.xxxx: Válassza ezt a Windows 10 2004-es verziójához.
    • 10.0.18362.xxxx: Válassza ezt a Windows 10 1903-es verziójához.
    • 10.0.17763.xxxx: Válassza ezt a Windows 10 1809-es verziójához.
    • 10.0.17134.xxxx: Válassza ezt a Windows 10 1803-es verziójához.
  5. Kattintson a Telepítésgombra.

A .NET különböző verzióit több célként használó projektek konfigurálása

Ha a projekt több célt megcélzó .NET 6 (vagy újabb) és korábbi verziókat (beleértve a .NET Core 3.x-et és a .NET-keretrendszert) céloz meg, akkor konfigurálhatja a projektfájlt úgy, hogy a Target Framework Moniker (TFM) segítségével automatikusan beszerezze a WinRT API-referenciákat a .NET 6-hoz (vagy újabbhoz), és a Microsoft.Windows.SDK.Contracts NuGet-csomagot használja a korábbi verziókhoz.

  1. Ha a projekt meg van nyitva a Visual Studióban, kattintson a jobb gombbal a projektre Megoldáskezelő, és válassza a Projektfájl szerkesztéselehetőséget. Az alábbi példa egy .NET Core 3.1-et használó alkalmazás projektfájlját mutatja be.

    Jegyzet

    Az alábbi példában egy WinExeOutputType látható, amely egy végrehajtható Windows-grafikus felhasználói felületet határoz meg (és megakadályozza, hogy a konzolablak megnyíljon az alkalmazás futtatásakor). Ha az alkalmazás nem rendelkezik grafikus felhasználói felülettel, akkor a OutputType értéke eltérő lesz. A WinRT API-kat Windows GUI-alkalmazásokból, konzolalkalmazásokból és kódtárakból hívhatja meg. Emellett előfordulhat, hogy TargetFramework értéke nem felel meg pontosan az alábbi példának.

    <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
      <PropertyGroup>
        <OutputType>WinExe</OutputType>
        <TargetFramework>netcoreapp3.1</TargetFramework>
        <UseWindowsForms>true</UseWindowsForms>
      </PropertyGroup>
    </Project>
    
  2. Cserélje le a TargetFramework elemet egy TargetFrameworks elemre (jegyezze fel a többes számot). Ebben az elemben adja meg a Target Framework Monikers (TFM)-eket a megcélzni kívánt .NET összes verziójához, pontosvesszővel elválasztva.

    • A .NET 6-os vagy újabb verzióihoz használja a következő Target Framework Monikers (TFM-ek) egyikét:
      • net6.0-windows10.0.17763.0: Ha az alkalmazás a Windows 10 1809-es verzióját célozza meg.
      • net6.0-windows10.0.18362.0: Ha az alkalmazás a Windows 10 1903-as verzióját célozza.
      • net6.0-windows10.0.19041.0: Ha az alkalmazás a Windows 10 2004-es verzióját célozza meg.
      • net6.0-windows10.0.22000.0: Ha az alkalmazás a Windows 11 kezdeti kiadását célozza.
      • net6.0-windows10.0.22621.0: Ha az alkalmazás a Windows 11 22H2-es verzióját célozza.
      • net6.0-windows10.0.26100.0: Ha az alkalmazás a Windows 11 24H2-es verzióját célozza meg.
    • A .NET Core 3.x esetén használja netcoreapp3.0 vagy netcoreapp3.1.
    • A .NET-keretrendszerhez használja net46.

    Az alábbi példa bemutatja, hogyan célozhat meg egyszerre több célt a .NET Core 3.1 és a .NET 6 (Windows 10, 2004-es verzió) platformok közötti célzással.

    <TargetFrameworks>netcoreapp3.1;net6.0-windows10.0.19041.0</TargetFrameworks>
    
  3. A PropertyGroup elem után adjon hozzá egy PackageReference elemet, amely tartalmaz egy feltételes utasítást, amely telepíti a Microsoft.Windows.SDK.Contracts NuGet-csomagot az alkalmazás által használt .NET Core 3.x vagy .NET-keretrendszer bármely verziójához. A PackageReference elemnek egy ItemGroup elem gyermekének kell lennie. Az alábbi példa bemutatja, hogyan teheti ezt meg a .NET Core 3.1-ben.

    <ItemGroup>
      <PackageReference Condition="'$(TargetFramework)' == 'netcoreapp3.1'"
                        Include="Microsoft.Windows.SDK.Contracts"
                        Version="10.0.19041.0" />
    </ItemGroup>
    

    Ha elkészült, a projektfájlnak ehhez hasonlóan kell kinéznie.

    <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
      <PropertyGroup>
        <OutputType>WinExe</OutputType>
        <TargetFrameworks>netcoreapp3.1;net6.0-windows10.0.19041.0</TargetFrameworks>
        <UseWPF>true</UseWPF>
      </PropertyGroup>
      <ItemGroup>
        <PackageReference Condition="'$(TargetFramework)' == 'netcoreapp3.1'"
                         Include="Microsoft.Windows.SDK.Contracts"
                         Version="10.0.19041.0" />
      </ItemGroup>
    </Project>
    
  4. Mentse a módosításokat, és zárja be a projektfájlt.

C++ asztali (Win32) projekt módosítása Windows Futtatókörnyezet API-k használatára

A WinRT API-k használatához használja C++/WinRT. A C++/WinRT egy teljesen standard modern C++17 nyelvi kivetítés WinRT API-khoz, fejlécfájl-alapú kódtárként implementálva, és úgy lett kialakítva, hogy első osztályú hozzáférést biztosítson a modern Windows API-hoz.

A C++/WinRT projekt konfigurálása:

További információ ezekről a lehetőségekről: Visual Studio támogatása a C++/WinRT-hez és a VSIX.

Windows 10-élmények hozzáadása

Most már készen áll arra, hogy modern élményeket adjon hozzá, amelyek életre kelnek, amikor a felhasználók futtatják az alkalmazását Windows 10-en. Használja ezt a tervezési folyamatot.

Először döntse el, hogy milyen szolgáltatásokat szeretne hozzáadni

Rengeteg lehetőség közül választhat. Egyszerűsítheti például a vásárlási rendelési folyamatot bevételszerzési API-khasználatával, vagy oda irányíthatja a figyelmet az alkalmazására, ha valami érdekeset oszthat meg, például egy másik felhasználó által közzétett új képet.

felugró értesítés

Még akkor is, ha a felhasználók figyelmen kívül hagyják vagy elutasítják az üzenetet, újra láthatják a műveletközpontban, majd az üzenetre kattintva megnyithatják az alkalmazást. Ez növeli az alkalmazás iránti elkötelezettséget, és azzal a bónuszsal jár, hogy az alkalmazás mélyen integrálva jelenik meg az operációs rendszerrel. A jelen cikk későbbi részében bemutatjuk az ehhez szükséges kódot.

További ötletekért tekintse meg az UWP dokumentációját.

Döntse el, hogy javítja vagy bővíti-e a

Gyakran hallani fogja, hogy a javítja a és kibővítikifejezéseket, ezért szánunk egy kis időt, hogy pontosan elmagyarázzuk, mit jelentenek ezek a kifejezések.

A kifejezéssel ismertetjük azokat a WinRT API-kat, amelyeket közvetlenül az asztali alkalmazásból hívhat meg, függetlenül attól, hogy csomagolt alkalmazásról van-e szó. Ha Windows 10-es felületet választott, azonosítsa a létrehozásához szükséges API-kat, majd ellenőrizze, hogy az API megjelenik-e ezen a listában. Ez azoknak az API-knak a listája, amelyeket közvetlenül az asztali alkalmazásból hívhat meg. Ha az API nem jelenik meg ebben a listában, annak az az oka, hogy az API-hoz társított funkciók csak egy UWP-folyamaton belül futhatnak. Gyakran előfordul, hogy ezek közé tartoznak az UWP XAML-t megjelenítő API-k, például egy UWP-térképvezérlő vagy egy Windows Hello biztonsági üzenet.

Jegyzet

Bár az UWP XAML-t megjelenítő API-k általában nem hívhatók meg közvetlenül az asztalról, alternatív módszereket is használhat. Ha UWP XAML-vezérlőket vagy más egyéni vizualizációs szolgáltatásokat szeretne üzemeltetni, használhatja XAML-szigetek (windows 10-es verzió, 1903-as verzió) és a vizuális réteg (windows 10-es verzió, 1803-as verziótól kezdve). Ezek a funkciók csomagolt vagy csomagolatlan asztali alkalmazásokban is használhatók.

Ha úgy döntött, hogy csomagolja az asztali alkalmazást, akkor egy másik lehetőség az alkalmazás kiterjesztése egy UWP-projekt hozzáadásával a megoldáshoz. Az asztali projekt továbbra is az alkalmazás belépési pontja, de az UWP-projekt hozzáférést biztosít az összes olyan API-hoz, amely nem jelenik meg a lista . Az asztali alkalmazás egy appszolgáltatás használatával kommunikálhat az UWP-folyamattal, és ennek beállításához számos útmutatást talál. Ha olyan felületet szeretne hozzáadni, amely UWP-projektet igényel, olvassa el a Kiterjesztés UWP-összetevőkkelcímű témakört.

referencia API-szerződések

Ha közvetlenül az asztali alkalmazásból hívhatja meg az API-t, nyisson meg egy böngészőt, és keressen rá az adott API referencia témakörére. Az API összegzése alatt talál egy táblázatot, amely leírja az API-szerződését az adott API-hoz. Íme egy példa erre a táblára:

API-szerződéstábla

Ha van egy .NET-alapú asztali alkalmazása, adjon hozzá egy hivatkozást az API-szerződéshez, majd állítsa a fájl Helyi példány másolása tulajdonságot Hamisértékre. Ha C++-alapú projektje van, adjon hozzá a További include könyvtárakhozegy olyan mappa elérési útját, amely tartalmazza ezt a fájlt.

Az API-k meghívása a felhasználói élmény hozzáadásához

Az alábbi kódot használná a korábban megtekintett értesítési ablak megjelenítéséhez. Ezek az API-k listában jelennek meg, így hozzáadhatja ezt a kódot az asztali alkalmazáshoz, és azonnal futtathatja.

using Windows.Foundation;
using Windows.System;
using Windows.UI.Notifications;
using Windows.Data.Xml.Dom;
...

private void ShowToast()
{
    string title = "featured picture of the day";
    string content = "beautiful scenery";
    string image = "https://picsum.photos/360/180?image=104";
    string logo = "https://picsum.photos/64?image=883";

    string xmlString =
    $@"<toast><visual>
       <binding template='ToastGeneric'>
       <text>{title}</text>
       <text>{content}</text>
       <image src='{image}'/>
       <image src='{logo}' placement='appLogoOverride' hint-crop='circle'/>
       </binding>
      </visual></toast>";

    XmlDocument toastXml = new XmlDocument();
    toastXml.LoadXml(xmlString);

    ToastNotification toast = new ToastNotification(toastXml);

    ToastNotificationManager.CreateToastNotifier().Show(toast);
}
#include <sstream>
#include <winrt/Windows.Data.Xml.Dom.h>
#include <winrt/Windows.UI.Notifications.h>

using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::System;
using namespace winrt::Windows::UI::Notifications;
using namespace winrt::Windows::Data::Xml::Dom;

void UWP::ShowToast()
{
    std::wstring const title = L"featured picture of the day";
    std::wstring const content = L"beautiful scenery";
    std::wstring const image = L"https://picsum.photos/360/180?image=104";
    std::wstring const logo = L"https://picsum.photos/64?image=883";

    std::wostringstream xmlString;
    xmlString << L"<toast><visual><binding template='ToastGeneric'>" <<
        L"<text>" << title << L"</text>" <<
        L"<text>" << content << L"</text>" <<
        L"<image src='" << image << L"'/>" <<
        L"<image src='" << logo << L"'" <<
        L" placement='appLogoOverride' hint-crop='circle'/>" <<
        L"</binding></visual></toast>";

    XmlDocument toastXml;

    toastXml.LoadXml(xmlString.str().c_str());

    ToastNotificationManager::CreateToastNotifier().Show(ToastNotification(toastXml));
}
using namespace Windows::Foundation;
using namespace Windows::System;
using namespace Windows::UI::Notifications;
using namespace Windows::Data::Xml::Dom;

void UWP::ShowToast()
{
    Platform::String ^title = "featured picture of the day";
    Platform::String ^content = "beautiful scenery";
    Platform::String ^image = "https://picsum.photos/360/180?image=104";
    Platform::String ^logo = "https://picsum.photos/64?image=883";

    Platform::String ^xmlString =
        L"<toast><visual><binding template='ToastGeneric'>" +
        L"<text>" + title + "</text>" +
        L"<text>"+ content + "</text>" +
        L"<image src='" + image + "'/>" +
        L"<image src='" + logo + "'" +
        L" placement='appLogoOverride' hint-crop='circle'/>" +
        L"</binding></visual></toast>";

    XmlDocument ^toastXml = ref new XmlDocument();

    toastXml->LoadXml(xmlString);

    ToastNotificationManager::CreateToastNotifier()->Show(ref new ToastNotification(toastXml));
}

Az értesítésekről további információt Adaptív és interaktív bejelentési értesítésekcímű témakörben talál.

A Windows XP, a Windows Vista és a Windows 7/8 telepítési alapjainak támogatása

A Windows 10-es alkalmazás modernizálható anélkül, hogy új ágat kellene létrehoznia, és külön kódbázisokat kellene fenntartania.

Ha külön bináris fájlokat szeretne létrehozni Windows 10-felhasználók számára, használja a feltételes fordítást. Ha az összes Windows-felhasználó számára üzembe helyezhető bináris fájlok egy készletét szeretné létrehozni, használjon futtatókörnyezet-ellenőrzéseket.

Vessünk egy pillantást az egyes lehetőségekre.

Feltételes fordítás

Egy kódbázist megtarthat, és bináris fájlok készletét fordíthatja le csak Windows 10-felhasználók számára.

Először adjon hozzá egy új buildkonfigurációt a projekthez.

Build konfiguráció

Ehhez a buildkonfigurációhoz hozzon létre egy állandót, amely azonosítja a WinRT API-kat hívó kódot.

A .NET-alapú projektek esetében a konstans neve feltételes fordítási állandó.

feltételes fordítási állandó

C++-alapú projektek esetén az állandó neve Preprocessor Definition.

Preprocesszordefiníciós állandó

Adja hozzá ezt az állandót az UWP-kód bármely blokkja előtt.

[System.Diagnostics.Conditional("_UWP")]
private void ShowToast()
{
 ...
}
#if _UWP
void UWP::ShowToast()
{
 ...
}
#endif

A fordító csak akkor hozza létre ezt a kódot, ha az állandó az aktív buildkonfigurációban van definiálva.

Futásidejű ellenőrzések

Az összes Windows-felhasználó számára lefordíthat egy bináris fájlt, függetlenül attól, hogy melyik Windows-verziót futtatják. Az alkalmazás csak akkor hívja meg a WinRT API-kat, ha a felhasználó csomagolt alkalmazásként futtatja az alkalmazást Windows 10-en.

A futtatókörnyezet-ellenőrzések kódhoz való hozzáadásának legegyszerűbb módja a Nuget-csomag telepítése: Desktop Bridge Segédprogramok, majd a IsRunningAsUWP() metódus használatával zárja le az összes WinRT API-t hívó kódot. További részletekért tekintse meg ezt a blogbejegyzést: Asztali híd – Az alkalmazás környezetének azonosítása.

Válaszok keresése a kérdésekre

Kérdése van? Kérdezzen minket a Stack Overflow-ról. Csapatunk figyeli ezeket a címkéket. A fórumainkon is kérdezhet.