Komponenten für Windows-Runtime in C# und Visual Basic

Sie können verwalteten Code verwenden, um eigene Windows-Runtime-Typen zu erstellen und diese in einer Windows-Runtime-Komponente zu packen. Sie können Ihre Komponente in Universelle Windows-Plattform-Apps (UWP) verwenden, die in C++, JavaScript, Visual Basic oder C# geschrieben sind. In diesem Thema werden die Regeln zum Erstellen einer Komponente und einige Aspekte der .NET-Unterstützung für die Windows-Runtime erläutert. Im Allgemeinen ist diese Unterstützung allen .NET-Programmierern klar. Wenn Sie aber eine Komponente erstellen, die mit JavaScript oder C++ verwendet werden soll, müssen Sie auf die Unterschiede bei der Unterstützung der Windows-Runtime durch diese Sprachen achten.

Wenn Sie eine Komponente erstellen, die nur in UWP-Apps verwendet werden kann, die in Visual Basic oder C# geschrieben sind, und die Komponente keine UWP-Steuerelemente enthält, sollten Sie die Klassenbibliotheksvorlage anstelle der Projektvorlage Windows-Runtime Komponente in Microsoft Visual Studio verwenden. Eine einfache Klassenbibliothek weist weniger Einschränkungen auf.

Hinweis

C#-Entwickler, die Desktop-Apps in .NET 6 oder höher schreiben, sollten eine Komponente für Windows-Runtime in C#/WinRT erstellen. Weitere Informationen finden Sie unter Erstellen von Windows-Runtime-Komponenten mit C#/WinRT.

Deklarieren von Typen in Windows-Runtime Komponenten

Intern können die Windows-Runtime-Typen in Ihrer Komponente jede .NET-Funktionalität verwenden, die in einer UWP-App zulässig ist. Weitere Informationen finden Sie unter .NET für UWP-Apps.

Extern können die Member Ihrer Typen nur Windows-Runtime Typen für ihre Parameter und Rückgabewerte verfügbar machen. In der folgenden Liste werden die Einschränkungen für .NET-Typen beschrieben, die von einer Windows-Runtime-Komponente verfügbar gemacht werden.

  • Die Felder, Parameter und Rückgabewerte aller öffentlichen Typen und Member in der Komponente müssen Windows-Runtime-Typen sein. Diese Einschränkung umfasst die Windows-Runtime Typen, die Sie erstellen, sowie Typen, die vom Windows-Runtime selbst bereitgestellt werden. Es enthält auch eine Reihe von .NET-Typen. Die Einbeziehung dieser Typen ist Teil der Unterstützung, die .NET bereitstellt, um die natürliche Verwendung der Windows-Runtime in verwaltetem Code zu ermöglichen. Ihr Code scheint vertraute .NET-Typen anstelle der zugrunde liegenden Windows-Runtime-Typen zu verwenden. Sie können beispielsweise .NET-primitive Typen wie Int32 und Double, bestimmte grundlegende Typen wie DateTimeOffset und Uri sowie einige häufig verwendete generische Schnittstellentypen wie IEnumerable<T> (IEnumerable(Of T) in Visual Basic und IDictionary<TKey,TValue> verwenden. Beachten Sie, dass die Typargumente dieser generischen Typen Windows-Runtime Typen sein müssen. Dies wird in den Abschnitten Übergeben Windows-Runtime Typen an verwalteten Code und Übergeben verwalteter Typen an die Windows-Runtime weiter unten in diesem Thema erläutert.

  • Öffentliche Klassen und Schnittstellen können Methoden, Eigenschaften und Ereignisse enthalten. Sie können Delegaten für Ihre Ereignisse deklarieren oder den EventHandler<T-Delegaten> verwenden. Eine öffentliche Klasse oder Schnittstelle kann nicht:

    • generisch sein.
    • Implementieren Sie eine Schnittstelle, die keine Windows-Runtime-Schnittstelle ist (Sie können jedoch eigene Windows-Runtime-Schnittstellen erstellen und implementieren).
    • Von Typen ableiten, die sich nicht im Windows-Runtime befinden, z. B. System.Exception und System.EventArgs.
  • Alle öffentliche Typen müssen über einen Stammnamespace verfügen, der mit dem Assemblynamen übereinstimmt, und der Assemblyname darf nicht mit „Windows” beginnen.

    Tipp. Standardmäßig entsprechen die Namespacenamen in Visual Studio-Projekten den Assemblynamen. In Visual Basic wird die Namespace-Anweisung für diesen Standardnamespace nicht im Code angezeigt.

  • Öffentliche Strukturen können nur öffentliche Felder als Member enthalten, und diese Felder müssen Werttypen oder Zeichenfolgen sein.

  • Öffentliche Klassen müssen versiegelt (NotInheritable in Visual Basic) sein. Wenn Ihr Programmiermodell Polymorphie erfordert, können Sie eine öffentliche Schnittstelle erstellen und diese Schnittstelle für die Klassen implementieren, die polymorph sein müssen.

Debuggen der Komponente

Wenn sowohl Ihre UWP-App als auch Ihre Komponente mit verwaltetem Code erstellt werden, können Sie beide gleichzeitig debuggen.

Wenn Sie Ihre Komponente als Teil einer UWP-App mit C++ testen, können Sie verwalteten und nativen Code gleichzeitig debuggen. Die Vorgabe ist nur systemeigener Code.

So debuggen Sie systemeigenen C++-Code und verwalteten Code

  1. Öffnen Sie das Kontextmenü für das Visual C++-Projekt, und wählen Sie Eigenschaften aus.
  2. Wählen Sie auf den Eigenschaftenseiten unter Konfigurationseigenschaften die Option Debuggen aus.
  3. Wählen Sie Debuggertyp aus, und ändern Sie dann in der Dropdownliste Nur systemeigen in Gemischt (verwaltet und systemeigen). Wählen Sie OK aus.
  4. Legen Sie Haltepunkte im systemeigenen und verwalteten Code fest.

Wenn Sie Ihre Komponente als Teil einer UWP-App mit JavaScript testen, befindet sich die Lösung standardmäßig im JavaScript-Debugmodus. In Visual Studio ist das gleichzeitige Debuggen von JavaScript und verwaltetem Code nicht möglich.

So debuggen Sie verwalteten Code anstelle von JavaScript

  1. Öffnen Sie das Kontextmenü für das JavaScript-Projekt, und wählen Sie Eigenschaften aus.
  2. Wählen Sie auf den Eigenschaftenseiten unter Konfigurationseigenschaften die Option Debuggen aus.
  3. Wählen Sie Debuggertyp aus, und ändern Sie in der Dropdownliste Nur Skript in Nur verwaltet. Wählen Sie OK aus.
  4. Legen Sie Haltepunkte im verwaltetem Code fest, und debuggen Sie wie gewohnt.

Übergeben von Windows-Runtime Typen an verwalteten Code

Wie bereits im Abschnitt Deklarieren von Typen in Windows-Runtime Komponenten erwähnt, können bestimmte .NET-Typen in den Signaturen von Membern öffentlicher Klassen angezeigt werden. Dies ist Teil der Unterstützung, die .NET bereitstellt, um die natürliche Verwendung der Windows-Runtime in verwaltetem Code zu ermöglichen. Darin sind primitive Typen und einige Klassen und Schnittstellen enthalten. Wenn Ihre Komponente aus JavaScript oder C++-Code verwendet wird, ist es wichtig zu wissen, wie Ihre .NET-Typen für den Aufrufer angezeigt werden. Beispiele mit JavaScript finden Sie unter Exemplarische Vorgehensweise zum Erstellen einer C#- oder Visual Basic-Windows-Runtime-Komponente und aufrufen aus JavaScript. In diesem Abschnitt werden häufig verwendete Typen beschrieben.

In .NET verfügen primitive Typen wie die Int32-Struktur über viele nützliche Eigenschaften und Methoden, z. B. die TryParse-Methode . Im Gegensatz dazu haben primitive Typen und Strukturen in der Windows-Runtime nur Felder. Wenn Sie diese Typen an verwalteten Code übergeben, scheinen sie .NET-Typen zu sein, und Sie können die Eigenschaften und Methoden von .NET-Typen wie gewohnt verwenden. Die folgende Liste fasst die Ersetzungen zusammen, die automatisch in der IDE vorgenommen werden:

  • Verwenden Sie für die Windows-Runtime Grundtypen Int32, Int64, Single, Double, Boolean, String (eine unveränderliche Auflistung von Unicode-Zeichen), Enum, UInt32, UInt64 und Guid den Typ desselben Namens im System-Namespace.
  • Verwenden Sie für UInt8System.Byte.
  • Verwenden Sie für Char16System.Char.
  • Verwenden Sie für die IInspectable-SchnittstelleSystem.Object.

Wenn C# oder Visual Basic eine Sprache Schlüsselwort (keyword) für einen dieser Typen bereitstellt, können Sie stattdessen die Sprache Schlüsselwort (keyword) verwenden.

Zusätzlich zu primitiven Typen werden einige einfache, häufig verwendete Windows-Runtime-Typen in verwaltetem Code als .NET-Entsprechungen angezeigt. Angenommen, Ihr JavaScript-Code verwendet die Windows.Foundation.Uri-Klasse , und Sie möchten sie an eine C#- oder Visual Basic-Methode übergeben. Der entsprechende Typ in verwaltetem Code ist die .NET System.Uri-Klasse , und dies ist der Typ, der für den Methodenparameter verwendet werden soll. Sie können erkennen, wann ein Windows-Runtime Typ als .NET-Typ angezeigt wird, da IntelliSense in Visual Studio den Windows-Runtime Typ beim Schreiben von verwaltetem Code ausblendet und den entsprechenden .NET-Typ darstellt. (Normalerweise haben die beiden Typen den gleichen Namen. Beachten Sie jedoch, dass die Windows.Foundation.DateTime-Struktur im verwalteten Code als System.DateTimeOffset und nicht als System.DateTime angezeigt wird.)

Bei einigen häufig verwendeten Sammlungstypen erfolgt die Zuordnung zwischen den Schnittstellen, die von einem Windows-Runtime Typ implementiert werden, und den Schnittstellen, die vom entsprechenden .NET-Typ implementiert werden. Wie bei den oben genannten Typen deklarieren Sie Parametertypen mithilfe des .NET-Typs. Dadurch werden einige Unterschiede zwischen den Typen ausgeblendet und das Schreiben von .NET-Code natürlicher.

In der folgenden Tabelle sind die häufigsten dieser generischen Schnittstellentypen zusammen mit anderen allgemeinen Klassen- und Schnittstellenzuordnungen aufgeführt. Eine vollständige Liste der Windows-Runtime Typen, die .NET zugeordnet werden, finden Sie unter .NET-Zuordnungen von Windows-Runtime-Typen.

Windows-Runtime .NET
IIterable<T> IEnumerable<T>
IVector<T> IList<T>
IVectorView<T> IReadOnlyList<T>
IMap<K, V> IDictionary<TKey, TValue>
IMapView<K, V> IReadOnlyDictionary<TKey, TValue>
IKeyValuePair<K, V> KeyValuePair<TKey, TValue>
IBindableIterable IEnumerable
IBindableVecinr IList
Windows.UI.Xaml.Data.INotifyPropertyChanged System.ComponentModel.INotifyPropertyChanged
Windows.UI.Xaml.Data.PropertyChangedEventHandler System.ComponentModel.PropertyChangedEventHandler
Windows.UI.Xaml.Data.PropertyChangedEventArgs System.ComponentModel.PropertyChangedEventArgs

Wenn ein Typ mehrere Schnittstellen implementiert, können Sie jede Schnittstelle verwenden, die als Parametertyp oder Rückgabetyp eines Members implementiert wird. Beispielsweise können Sie ein Dictionary<int, string> (Dictionary(Of Integer, String) in Visual Basic als IDictionary<int, string>,IReadOnlyDictionary<int, string> oder IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TValue>> übergeben oder zurückgeben.

Wichtig

JavaScript verwendet die Schnittstelle, die zuerst in der Liste der Schnittstellen angezeigt wird, die ein verwalteter Typ implementiert. Wenn Sie beispielsweise Dictionary<int, string> in JavaScript-Code zurückgeben, wird es als IDictionary<int angezeigt, Zeichenfolge> unabhängig davon, welche Schnittstelle Sie als Rückgabetyp angeben. Das bedeutet, dass die erste Schnittstelle Member enthalten muss, die in den nächsten Schnittstellen erscheinen, damit diese Member für JavaScript sichtbar sind.

Im Windows-Runtime werden IMap<K, V> und IMapView<K, V> mithilfe von IKeyValuePair durchlaufen. Wenn Sie sie an verwalteten Code übergeben, werden sie als IDictionary<TKey, TValue> und IReadOnlyDictionary<TKey, TValue> angezeigt. Daher verwenden Sie natürlich System.Collections.Generic.KeyValuePair<TKey, TValue>, um sie aufzulisten.

Die Darstellungsweise von Schnittstellen in verwaltetem Code wirkt sich auf die Darstellungsweise der Typen aus, die diese Schnittstellen implementieren. Beispielsweise implementiert die PropertySet-KlasseIMap<K, V>, die im verwalteten Code als IDictionary<TKey, TValue> angezeigt wird. PropertySet sieht so aus, als ob es IDictionary<TKey, TValue> anstelle von IMap<K, V> implementiert hätte, sodass es in verwaltetem Code anscheinend eine Add-Methode aufweist, die sich wie die Add-Methode in .NET-Wörterbüchern verhält. Es scheint nicht über eine Insert-Methode zu verfügen. Dieses Beispiel finden Sie im Thema Exemplarische Vorgehensweise zum Erstellen einer C#- oder Visual Basic-Windows-Runtime-Komponente und aufrufen aus JavaScript.

Übergeben von verwalteten Typen an die Windows-Runtime

Wie im vorherigen Abschnitt erläutert, können einige Windows-Runtime Typen als .NET-Typen in den Signaturen der Member Ihrer Komponente oder in den Signaturen von Windows-Runtime Membern angezeigt werden, wenn Sie sie in der IDE verwenden. Wenn Sie .NET-Typen an diese Member übergeben oder als Rückgabewerte der Member Ihrer Komponente verwenden, werden sie dem Code auf der anderen Seite als entsprechender Windows-Runtime Typ angezeigt. Beispiele für die Auswirkungen, die dies haben kann, wenn Ihre Komponente aus JavaScript aufgerufen wird, finden Sie im Abschnitt "Zurückgeben verwalteter Typen aus Ihrer Komponente" unter Exemplarische Vorgehensweise zum Erstellen einer C#- oder Visual Basic-Windows-Runtime-Komponente und aufrufen aus JavaScript.

Überladene Methoden

In der Windows-Runtime können Methoden überladen werden. Wenn Sie jedoch mehrere Überladungen mit der gleichen Anzahl von Parametern deklarieren, müssen Sie das Windows.Foundation.Metadata.DefaultOverloadAttribute-Attribut nur auf eine dieser Überladungen anwenden. Nur diese Überladung kann aus JavaScript aufgerufen werden. Im folgenden Code ist beispielsweise die Überladung, die int übernimmt (Integer in Visual Basic), die Standardüberladung.

public string OverloadExample(string s)
{
    return s;
}

[Windows.Foundation.Metadata.DefaultOverload()]
public int OverloadExample(int x)
{
    return x;
}
Public Function OverloadExample(ByVal s As String) As String
    Return s
End Function

<Windows.Foundation.Metadata.DefaultOverload> _
Public Function OverloadExample(ByVal x As Integer) As Integer
    Return x
End Function

[WICHTIG] JavaScript ermöglicht es Ihnen, jeden Wert an OverloadExample zu übergeben und den Wert an den Typ zu übertragen, der für den Parameter erforderlich ist. Sie können OverloadExample mit "zweiundvierzig", "42" oder 42.3 aufrufen, aber alle diese Werte werden an die Standardüberladung übergeben. Die Standardüberladung im vorherigen Beispiel gibt 0, 42 bzw. 42 zurück.

Sie können das DefaultOverloadAttribute-Attribut nicht auf Konstruktoren anwenden. Alle Konstruktoren in einer Klasse müssen eine unterschiedliche Anzahl von Parametern aufweisen.

Implementieren von IStringable

Ab Windows 8.1 enthält die Windows-Runtime eine IStringable-Schnittstelle, deren einzelne Methode, IStringable.ToString, eine grundlegende Formatierungsunterstützung bietet, die mit der von Object.ToString vergleichbar ist. Wenn Sie IStringable in einem öffentlichen verwalteten Typ implementieren, der in eine Windows-Runtime-Komponente exportiert wird, gelten die folgenden Einschränkungen:

  • Sie können die IStringable-Schnittstelle nur in einer Beziehung "Klasse implementiert" definieren, z. B. den folgenden Code in C#:

    public class NewClass : IStringable
    

    Oder in Visual Basic-Code:

    Public Class NewClass : Implements IStringable
    
  • Sie können IStringable nicht auf einer Schnittstelle implementieren.

  • Sie können keinen Parameter vom Typ IStringable deklarieren.

  • IStringable kann nicht der Rückgabetyp einer Methode, Eigenschaft oder eines Felds sein.

  • Sie können Ihre IStringable-Implementierung nicht vor Basisklassen ausblenden, indem Sie eine Methodendefinition wie die folgende verwenden:

    public class NewClass : IStringable
    {
       public new string ToString()
       {
          return "New ToString in NewClass";
       }
    }
    

    Stattdessen muss die IStringable.ToString-Implementierung immer die Basisklassenimplementierung überschreiben. Sie können eine ToString-Implementierung nur ausblenden, indem Sie sie für eine stark typisierte Klasse aufrufen instance.

Hinweis

Unter einer Vielzahl von Bedingungen können Aufrufe von nativem Code an einen verwalteten Typ, der IStringable implementiert oder die ToString-Implementierung ausblendet, zu unerwartetem Verhalten führen.

Asynchrone Vorgänge

Um eine asynchrone Methode in Ihrer Komponente zu implementieren, fügen Sie "Async" am Ende des Methodennamens hinzu, und geben Sie eine der Windows-Runtime Schnittstellen zurück, die asynchrone Aktionen oder Vorgänge darstellen: IAsyncActionWithProgress, IAsyncActionWithProgress<>, IAsyncOperation<TResult> oder IAsyncOperationWithProgress<TResult, TProgress>.

Sie können .NET-Tasks (die Task-Klasse und die generische Task<TResult-Klasse> ) verwenden, um Ihre asynchrone Methode zu implementieren. Sie müssen einen Task zurückgeben, der einen laufenden Vorgang darstellt, z. B. eine Aufgabe, die von einer asynchronen Methode zurückgegeben wird, die in C# oder Visual Basic geschrieben wurde, oder einen Vorgang, der von der Task.Run-Methode zurückgegeben wird. Wenn Sie für die Aufgabenerstellung einen Konstruktor verwenden, müssen Sie seine Task.Start-Methode vor der Rückgabe aufrufen.

Eine Methode, die (Await in Visual Basic) verwendet await , erfordert die async Schlüsselwort (keyword) (Async in Visual Basic). Wenn Sie eine solche Methode aus einer Windows-Runtime-Komponente verfügbar machen, wenden Sie die async Schlüsselwort (keyword) auf den Delegaten an, den Sie an die Run-Methode übergeben.

Für asynchrone Aktionen und Vorgänge, die weder die Abbruch- noch die Fortschrittsberichterstattung unterstützen, können Sie mit der Erweiterungsmethode WindowsRuntimeSystemExtensions.AsAsyncAction oder AsAsyncOperation<TResult> die Aufgabe in die entsprechende Schnittstelle umschließen. Der folgende Code implementiert beispielsweise eine asynchrone Methode, indem die Task.Run<TResult-Methode> verwendet wird, um einen Task zu starten. Die AsAsyncOperation<TResult-Erweiterungsmethode> gibt den Task als Windows-Runtime asynchronen Vorgang zurück.

public static IAsyncOperation<IList<string>> DownloadAsStringsAsync(string id)
{
    return Task.Run<IList<string>>(async () =>
    {
        var data = await DownloadDataAsync(id);
        return ExtractStrings(data);
    }).AsAsyncOperation();
}
Public Shared Function DownloadAsStringsAsync(ByVal id As String) _
     As IAsyncOperation(Of IList(Of String))

    Return Task.Run(Of IList(Of String))(
        Async Function()
            Dim data = Await DownloadDataAsync(id)
            Return ExtractStrings(data)
        End Function).AsAsyncOperation()
End Function

Der folgende JavaScript-Code zeigt, wie die -Methode mithilfe eines WinJS.Promise-Objekts aufgerufen werden kann. Die an die then-Methode übergebene Funktion wird ausgeführt, wenn der asynchrone Aufruf abgeschlossen ist. Der stringList-Parameter enthält die Liste der Zeichenfolgen, die von der DownloadAsStringAsync-Methode zurückgegeben wird, und die Funktion übernimmt die erforderliche Verarbeitung.

function asyncExample(id) {

    var result = SampleComponent.Example.downloadAsStringAsync(id).then(
        function (stringList) {
            // Place code that uses the returned list of strings here.
        });
}

Verwenden Sie für asynchrone Aktionen und Vorgänge, die die Abbruch- oder Statusberichterstattung unterstützen, die AsyncInfo-Klasse, um eine gestartete Aufgabe zu generieren und die Abbruch- und Statusberichtsfeatures des Vorgangs mit den Abbruch- und Fortschrittsberichtsfeatures der entsprechenden Windows-Runtime-Schnittstelle zu verbinden. Ein Beispiel, das sowohl die Abbruch- als auch die Fortschrittsberichterstattung unterstützt, finden Sie unter Exemplarische Vorgehensweise zum Erstellen einer C#- oder Visual Basic-Windows-Runtime-Komponente und aufrufen aus JavaScript.

Beachten Sie, dass Sie die Methoden der AsyncInfo-Klasse auch dann verwenden können, wenn Ihre asynchrone Methode keine Abbruch- oder Fortschrittsberichte unterstützt. Wenn Sie eine Visual Basic-Lambdafunktion oder eine anonyme C#-Methode verwenden, geben Sie keine Parameter für das Token und die IProgress<T-Schnittstelle> an. Wenn Sie eine C#-Lambda-Funktion verwenden, geben Sie einen Tokenparameter an, aber ignorieren Sie ihn. Das vorherige Beispiel, das die AsAsyncOperation<TResult-Methode> verwendet hat, sieht wie folgt aus, wenn Sie stattdessen die Methodenüberladung AsyncInfo.Run<TResult>(Func<CancellationToken, Task<TResult>>) verwenden.

public static IAsyncOperation<IList<string>> DownloadAsStringsAsync(string id)
{
    return AsyncInfo.Run<IList<string>>(async (token) =>
    {
        var data = await DownloadDataAsync(id);
        return ExtractStrings(data);
    });
}
Public Shared Function DownloadAsStringsAsync(ByVal id As String) _
    As IAsyncOperation(Of IList(Of String))

    Return AsyncInfo.Run(Of IList(Of String))(
        Async Function()
            Dim data = Await DownloadDataAsync(id)
            Return ExtractStrings(data)
        End Function)
End Function

Wenn Sie eine asynchrone Methode erstellen, die optional die Abbruch- oder Fortschrittsberichterstattung unterstützt, sollten Sie Überladungen hinzufügen, die keine Parameter für ein Abbruchtoken oder die IProgress<T-Schnittstelle> aufweisen.

Auslösen von Ausnahmen

Sie können jeden Ausnahmetyp auslösen, der in .NET für Windows-Apps enthalten ist. Sie können keine eigenen öffentlichen Ausnahmetypen in einer Komponente für Windows-Runtime deklarieren, aber Sie können nicht öffentliche Typen deklarieren und auslösen.

Wenn die Komponente die Ausnahme nicht behandelt, wird eine entsprechende Ausnahme im Code ausgelöst, der die Komponente aufgerufen hat. Die Unterstützung der Windows-Runtime durch die aufrufende Sprache bestimmt, wie die Ausnahme dem Aufrufer dargestellt wird.

  • In JavaScript erscheint die Ausnahme als Objekt, in dem die Ausnahmemeldung durch eine Stapelüberwachung ersetzt ist. Wenn Sie Ihre App in Visual Studio debuggen, wird der Originaltext der Meldung im Ausnahmedialogfeld des Debuggers unter „WinRT Information" angezeigt. Sie können mit JavaScript-Code nicht auf den Originaltext der Meldung zugreifen.

    Tipp. Momentan enthält die Stapelüberwachung den verwalteten Ausnahmetyp, aber es ist nicht empfehlenswert, diese zu untersuchen, um den Ausnahmetyp zu identifizieren. Verwenden Sie stattdessen einen HRESULT-Wert, wie weiter unten in diesem Abschnitt beschrieben.

  • In C++ erscheint die Ausnahme als Plattformausnahme. Wenn die HResult-Eigenschaft der verwalteten Ausnahme dem HRESULT einer bestimmten Plattform-Ausnahme zugeordnet werden kann, wird die spezifische Ausnahme verwendet. andernfalls wird eine Platform::COMException-Ausnahme ausgelöst. Der Meldungstext der verwalteten Ausnahme ist für C++-Code nicht verfügbar. Wenn eine bestimmte Plattformausnahme ausgelöst wurde, erscheint der Meldungstext für diesen Ausnahmetyp. Andernfalls wird kein Meldungstext ausgegeben. Siehe Ausnahmen (C++/CX).

  • In C# oder Visual Basic ist die Ausnahme eine normale verwaltete Ausnahme.

Wenn Sie in Ihrer Komponente eine Ausnahme auslösen, sollten Sie einen nicht öffentlichen Ausnahmetyp verwenden, dessen HResult-Eigenschaftswert speziell für Ihre Komponente gilt, damit die Ausnahme leichter von einem JavaScript- oder C++-Aufrufer verwaltet werden kann. Das HRESULT ist für einen JavaScript-Aufrufer über die Number-Eigenschaft des Ausnahmeobjekts und für einen C++-Aufrufer über die COMException::HResult-Eigenschaft verfügbar.

Hinweis

Verwenden Sie einen negativen Wert für Ihr HRESULT. Ein positiver Wert wird als Erfolg interpretiert und im JavaScript- oder C++-Aufrufer wird keine Ausnahme ausgelöst.

Deklarieren und Auslösen von Ereignissen

Wenn Sie einen Typ deklarieren, um die Daten für das Ereignis aufzunehmen, leiten Sie diesen von „Object“ und nicht von „EventArgs“ ab, da „EventArgs“ kein Windows-Runtime-Typ ist. Verwenden Sie EventHandler<TEventArgs> als Typ des Ereignisses, und verwenden Sie Ihren Ereignisargumenttyp als generisches Typargument. Lösen Sie das Ereignis wie in einer .NET-Anwendung aus.

Wenn Ihre Komponente für Windows-Runtime von JavaScript oder C++ verwendet wird, folgt das Ereignis dem Windows-Runtime-Ereignismuster, das diese Sprachen erwarten. Wenn Sie die Komponente aus C# oder Visual Basic verwenden, wird das Ereignis als gewöhnliches .NET-Ereignis angezeigt. Ein Beispiel finden Sie unter Exemplarische Vorgehensweise zum Erstellen einer C#- oder Visual Basic-Windows-Runtime-Komponente und zum Aufrufen dieser Komponente aus JavaScript.

Wenn Sie benutzerdefinierte Ereignisaccessoren implementieren (in Visual Basic ein Ereignis mit dem Schlüsselwort Custom deklarieren), müssen Sie in der Implementierung das Windows-Runtime-Ereignismuster verwenden. Weitere Informationen finden Sie unter Benutzerdefinierte Ereignisse und Ereignisaccessoren in Windows-Runtime Komponenten. Beachten Sie, dass es sich beim Behandeln des Ereignisses aus C#- oder Visual Basic-Code weiterhin um ein gewöhnliches .NET-Ereignis handelt.

Nächste Schritte

Nachdem Sie eine Windows-Runtime Komponente für Ihre eigene Verwendung erstellt haben, stellen Sie möglicherweise fest, dass die darin enthaltene Funktionalität für andere Entwickler nützlich ist. Sie haben zwei Optionen, um eine Komponente für die Verteilung an andere Entwickler zu packen. Siehe Verteilen einer verwalteten Komponente für Windows-Runtime.

Weitere Informationen zu Visual Basic- und C#-Sprachfeatures sowie zur .NET-Unterstützung für die Windows-Runtime finden Sie in der Visual Basic- und C#-Dokumentation.

Problembehandlung

Symptom Problembehandlung
Wenn in einer C++/WinRT-App eine C#-Komponente für Windows-Runtime, die XAML verwendet, verarbeitet wird, erzeugt der Compiler einen Fehler der Form „'MyNamespace_XamlTypeInfo': is not a member of 'winrt::MyNamespace'“, wobei MyNamespace der Name des Namespace der Windows Runtime-Komponente ist. Fügen Sie in pch.h in der verarbeitenden C++/WinRT-App #include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h> hinzu, und ersetzen Sie MyNamespace entsprechend.