Mai 2019

Band 34, Nummer 5

[.NET Core 3.0]

Erstellen eines zentralisierten Pull Request-Hubs mit Windows Forms in .NET Core 3.0

Von Eric Fleming | Mai 2019

Windows Forms (oder einfach WinForms) wird seit Jahren verwendet, um leistungsfähige Windows-basierte Anwendungen mit umfangreichen und interaktiven Benutzeroberflächen zu entwickeln. Die Investitionen in diese Desktopanwendungen in allen Unternehmensbereichen sind beträchtlich: Rund 2,4 Millionen Entwickler nutzen Visual Studio, um jeden Monat Anwendungen im Desktopstil zu erstellen. Die Vorteile der Nutzung und Erweiterung vorhandener WinForms-Codeelemente sind überzeugend, aber es gibt auch noch andere Vorteile. Die Drag & Drop-Benutzeroberfläche des WinForms-Designers ermöglicht es Benutzern, voll funktionsfähige Benutzeroberflächen ohne spezielle Kenntnisse oder entsprechendes Training zu erstellen. WinForms-Anwendungen sind einfach zu implementieren und zu aktualisieren, können unabhängig von der Internetverbindung arbeiten und bieten verbesserte Sicherheit, indem sie auf einem lokalen Computer ausgeführt werden, der keine Konfigurationen im Internet offenlegt. Bis vor kurzem konnten WinForms-Anwendungen nur mit der vollständigen Version von .NET Framework erstellt werden, aber das Release der Vorschau von .NET Core 3.0 ändert dies alles.

Die neuen Funktionen und Vorteile von .NET Core gehen über Webentwicklung hinaus. Mit .NET Core 3.0 fügt WinForms Funktionen wie einfachere Bereitstellung, verbesserte Leistung, Unterstützung für .NET Core-spezifische NuGet-Pakete, die .NET Core-Befehlszeilenschnittstelle (CLI) und vieles mehr hinzu. In diesem Artikel werde ich auf viele dieser Vorteile eingehen und erläutern, warum sie wichtig sind und wie Sie sie in WinForms-Anwendungen verwenden können.

Fangen wir gleich mit der Erstellung unserer ersten .NET Core 3.0 WinForms-Anwendung an. Für diesen Artikel werde ich eine Anwendung erstellen, die offene Pull Requests für eines der auf GitHub gehosteten Open-Source-Repositorys von Microsoft abruft und anzeigt. Der erste Schritt besteht darin, die neuesten Versionen von Visual Studio 2019 und dem .NET Core 3.0 SDK zu installieren. Danach haben Sie Zugriff auf die Befehle der .NET Core CLI, um eine neue WinForms-Anwendung zu erstellen. Dies war für WinForms-Anwendungen vor dem Hinzufügen von Unterstützung für .NET Core nicht möglich.

In Kürze wird eine neue Visual Studio-Vorlage veröffentlicht, mit der Sie ein WinForms-Projekt erstellen können, das auf .NET Core 3.0 abzielt. Diese Vorlage ist noch nicht verfügbar, also lassen Sie uns vorerst ein neues WinForms-Projekt namens PullRequestHub generieren, indem wir den folgenden Befehl ausführen:

dotnet new winforms -o PullRequestHub

Um sicherzustellen, dass das Projekt erfolgreich erstellt wurde, navigieren Sie in das neue Verzeichnis, das mit dem Befehl „dotnet new“ erstellt wurde, und verwenden Sie die CLI, um das Projekt zu erstellen und auszuführen:

cd .\PullRequestHub\

Da Sie Zugriff auf die .NET Core CLI besitzen, haben Sie auch Zugriff auf die Befehle zum Wiederherstellen, Ausführen und Erstellen der Anwendung. Probieren Sie vor der Ausführung die Wiederherstellungs- und Ausführungsbefehle aus:

dotnet restore
dotnet build

Diese Befehle funktionieren genau so, als würden sie in der Befehlszeile für eine .NET Core-Webanwendung ausgeführt. Und beachten Sie, dass bei der Ausführung des Befehls „dotnet run“ sowohl eine Wiederherstellung als auch ein Buildvorgang vor der Ausführung der App durchgeführt wird (bit.ly/2UCkEaN). Führen wir das Projekt nun aus, um es zu testen, indem wir „dotnet run“ in der Befehlszeile eingeben.

Das war erfolgreich! Sie haben soeben Ihre erste .NET Core WinForms-Anwendung erstellt. Beim Ausführen wird ein Formular mit dem Text „Hello .NET Core!“ auf dem Bildschirm angezeigt.

Bevor ich das Hinzufügen von Logik zu unserer Anwendung fortsetze, sehen wir uns kurz den aktuellen Zustand der Designer-Ansicht von WinForms in Visual Studio an.

Einrichten des Designers für .NET Core WinForms-Apps

Wenn Sie das CLI-generierte Projekt in Visual Studio öffnen, werden Sie feststellen, dass einige Funktionen fehlen. Insbesondere gibt es derzeit keine Designer-Ansicht für .NET Core WinForms-Anwendungen. Es gibt zwar Pläne, diese Funktionalität zur Verfügung zu stellen, aber sie wurden noch nicht umgesetzt.

Glücklicherweise ist eine Problemumgehung vorhanden, die Ihnen Zugriff auf einen Designer ermöglichen kann – zumindest solange, bis native Unterstützung hinzugefügt wird. Vorerst können Sie ein .NET Framework-Projekt erstellen, das Ihre Benutzeroberflächendateien enthält. Auf diese Weise können Sie die Benutzeroberflächendateien mit dem Designer bearbeiten, und das .NET Core-Projekt verweist dann aus dem .NET Framework-Projekt auf die Benutzeroberflächendateien. Auf diese Weise können Sie die Benutzeroberflächenfunktionen nutzen, während Sie die Anwendung dennoch in .NET Core erstellen. Hier sehen Sie, wie ich für mein Projekt vorgehe.

Zusätzlich zu dem von Ihnen erstellten PullRequestHub-Projekt möchten Sie ein neues WinForms-Projekt hinzufügen, das unter einer vollständigen Version von .NET Framework ausgeführt wird. Nennen Sie dieses Projekt PullRequestHub.Designer. Nachdem das neue Projekt erstellt wurde, entfernen Sie die Form1-Dateien aus dem .NET Core-Projekt, und belassen Sie nur die Klasse „Program.cs“.

Navigieren Sie zu PullRequestHub.Designer, und benennen Sie die Formulardateien in PullRequestForm um. Jetzt bearbeiten Sie die .NET Core-Projektdatei und fügen den folgenden Code hinzu, um die Dateien in beiden Projekten miteinander zu verknüpfen. Dies berücksichtigt auch alle weiteren Formulare oder Ressourcen, die Sie in Zukunft erstellen:

<ItemGroup>
  <Compile Include=”..\PullRequestHub.Designer\**\*.cs” />
</ItemGroup>

Sobald Sie die Projektdatei gespeichert haben, werden die PullRequestForm-Dateien im Projektmappen-Explorer angezeigt, und Sie können mit ihnen interagieren. Wenn Sie den Benutzeroberflächen-Editor verwenden möchten, müssen Sie sicherstellen, dass Sie die PullRequestForm-Datei aus dem .NET Core-Projekt schließen und die PullRequestForm-Datei aus dem .NET Framework-Projekt öffnen. Die Änderungen erfolgen in beiden Projekten, allerdings ist der Editor ist nur aus dem .NET Framework-Projekt verfügbar.

Erstellen der Anwendung

Beginnen wir damit, der Anwendung Code hinzuzufügen. Um offene Pull Requests aus GitHub abzurufen, muss ich einen HttpClient erstellen. Hier kommt .NET Core 3.0 ins Spiel, da es den Zugriff auf die neue HttpClientFactory bereitstellt. Der HttpClient in der vollständigen Frameworkversion wies einige Probleme auf, unter anderem beim Erstellen des Clients mit einer using-Anweisung. Das HttpClient-Objekt wurde verworfen, aber der darunter liegende Socket wurde für einige Zeit nicht freigegeben (standardmäßig 240 Sekunden). Wenn die Socketverbindung 240 Sekunden lang geöffnet bleibt und Sie einen hohen Durchsatz in Ihrem System haben, besteht die Möglichkeit, dass Ihr System alle freien Sockets belegt. In diesem Fall müssen neue Anforderungen warten, bis ein Socket freigegeben wird, was zu recht drastischen Leistungseinbußen führen kann.

Die HttpClientFactory hilft dabei, diese Probleme zu entschärfen. Zum einen bietet sie Ihnen eine einfachere Möglichkeit, Clientimplementierungen an einem zentraleren Ort vorzukonfigurieren. Sie verwaltet auch die Lebensdauer der HttpClients für Sie, sodass Sie nicht auf die zuvor genannten Probleme stoßen. Schauen wir uns an, wie Sie dies jetzt in einer WinForms-Anwendung umsetzen können.

Eine der besten und einfachsten Möglichkeiten, diese neue Funktion zu nutzen, ist Abhängigkeitsinjektion. Abhängigkeitsinjektion (oder allgemeiner Inversion of Control) ist eine Technik zum Übergeben von Abhängigkeiten in Klassen. Sie ist auch eine fantastische Möglichkeit, die Kopplung von Klassen zu verringern und Komponententests zu erleichtern. Sie erfahren beispielsweise, wie Sie beim Programmstart eine Instanz von IHttpClientFactory erstellen können. Dieses Objekt kann später im Formular genutzt werden. Dies war in WinForms in früheren Versionen von .NET nicht ganz einfach zu erreichen, und es ist ein weiterer Vorteil der Verwendung von .NET Core.

In der Datei „Program.cs“ erstellen Sie eine Methode namens ConfigureServices. Erstellen Sie in dieser Methode eine neue ServiceCollection, um Ihnen Dienste über Abhängigkeitsinjektion zur Verfügung zu stellen. Sie müssen zunächst das neueste dieser beiden NuGet-Pakete installieren:

  • „Microsoft.Extensions.DependencyInjection“
  • „Microsoft.Extensions.Http“

Fügen Sie dann den in Abbildung 1 gezeigten Code hinzu. Dadurch wird eine neue IHttpClientFactory erstellt, die in Ihren Formularen verwendet werden kann. Das Ergebnis ist ein Client, den Sie explizit für Anforderungen verwenden können, die die GitHub-API einbeziehen.

Abbildung 1: Erstellen einer neuen IHttpClientFactory

private static void ConfigureServices()
{
  var services = new ServiceCollection();
  services.AddHttpClient();
  services.AddHttpClient(“github”, c =>
  {
    c.BaseAddress = new Uri(“https://api.github.com/”);
    c.DefaultRequestHeaders.Add(“Accept”, “application/vnd.github.v3+json”);
    c.DefaultRequestHeaders.Add(“User-Agent”, “HttpClientFactory-Sample”);
    c.DefaultRequestHeaders.Add(“Accept”, “application/json”);
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
  });
}

Als nächstes müssen Sie die eigentliche Formularklasse (PullRequestForm) als Singleton registrieren. Fügen Sie am Ende dieser Methode die folgende Zeile hinzu:

services.AddSingleton<PullRequestForm>();

Dann müssen Sie eine Instanz des ServiceProvider-Elements erstellen. Erstellen Sie am Anfang der Klasse „Program.cs“ die folgende Eigenschaft:

private static IServiceProvider ServiceProvider { get; set; }

Da Sie nun über eine Eigenschaft für Ihren ServiceProvider verfügen, fügen Sie am Ende der ConfigureServices-Methode eine Zeile hinzu, um den ServiceProvider zu erstellen:

ServiceProvider = services.BuildServiceProvider();

Am Ende sollte die vollständige ConfigureServices-Methode wie der Code in Abbildung 2 aussehen.

Abbildung 2: Die ConfigureServices-Methode

private static void ConfigureServices()
{
  var services = new ServiceCollection();
  services.AddHttpClient();
  services.AddHttpClient(“github”, c =>
  {
    c.BaseAddress = new Uri(“https://api.github.com/”);
    c.DefaultRequestHeaders.Add(“Accept”, “application/vnd.github.v3+json”);
    c.DefaultRequestHeaders.Add(“User-Agent”, “HttpClientFactory-Sample”);
    c.DefaultRequestHeaders.Add(“Accept”, “application/json”);
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
  });
  services.AddSingleton<PullRequestForm>();
  ServiceProvider = services.BuildServiceProvider();
}

Nun müssen Sie das Formular beim Start mit dem Container verknüpfen. Wenn die Anwendung ausgeführt wird, wird PullRequestForm mit den erforderlichen verfügbaren Diensten aufgerufen. Ändern Sie die Main-Methode in den folgenden Code:

[STAThread]
static void Main()
{
  Application.EnableVisualStyles();
  Application.SetCompatibleTextRenderingDefault(false);
  ConfigureServices();
  Application.Run((PullRequestForm)ServiceProvider.GetService(typeof(PullRequestForm)));
}

Klasse! Jetzt haben Sie alle Komponenten verbunden. Im PullRequestForm-Konstruktor injizieren Sie die soeben eingebundene IHttpClientFactory und weisen sie einer lokalen Variablen zu, wie hier im Code gezeigt:

private static HttpClient _httpClient;
public PullRequestForm(IHttpClientFactory httpClientFactory)
{
  InitializeComponent();
  _httpClient = httpClientFactory.CreateClient(“github”);
}

Jetzt verfügen Sie über einen HttpClient, mit dem Sie GitHub aufrufen können, um Pull Requests, Issues und dergleichen abzurufen. Dadurch werden die nächsten Schritte etwas knifflig. Die Aufrufe von HttpClient werden asynchrone Anforderungen sein, und wenn Sie WinForms bereits verwendet haben, wissen Sie, was nun kommt. Sie müssen sich um das Threading kümmern und Dispatchupdates an den UI-Thread senden.

Um das Abrufen aller Pull Requests zu starten, fügen wir der Ansicht eine Schaltfläche hinzu. Auf diese Weise können Sie in Zukunft weitere Repositorys oder weitere Gruppen von Repositorys zur Überprüfung hinzufügen. Ziehen Sie mit dem von Ihnen eingebundenen Designer die Schaltfläche auf das Formular, und ändern Sie den Text in „Microsoft“. Wenn Sie schon dabei sind, geben Sie der Schaltfläche einen aussagekräftigeren Namen, z.B. RetrieveData_Button. Sie müssen eine Bindung an das Ereignis RetrieveData_Button_Click vornehmen, aber sie muss asynchron sein. Verwenden Sie dazu den folgenden Code:

private async void RetrieveData_Button_Click(object sender, EventArgs e)
{
}

Hier möchten Sie eine Methode aufrufen, die offene GitHub-Pull Requests abruft. Da Sie es jetzt mit asynchronen Aufrufen zu tun haben, müssen Sie aber zunächst den SynchronizationContext einbinden. Dies geschieht, indem Sie eine neue Eigenschaft hinzufügen und den Konstruktor mit dem folgenden Code aktualisieren:

private static HttpClient _httpClient;
private readonly SynchronizationContext synchronizationContext;
public PullRequestForm(IHttpClientFactory httpClientFactory)
{
  InitializeComponent();
  synchronizationContext = SynchronizationContext.Current;
  _httpClient = httpClientFactory.CreateClient(“github”);
}

Erstellen Sie anschließend ein Modell mit dem Namen PullRequestData, damit Sie Ihre Anforderung auf einfache Weise deserialisieren können. Hier ist der Code dafür:

public class PullRequestData
{
  public string Url { get; set; }
  public string Title { get; set; }
}

Erstellen Sie schließlich eine Methode namens GetPullRequestData. In dieser Methode nehmen Sie Ihre Anforderung an die GitHub-API vor und rufen alle offenen Pull Requests ab. Sie werden eine JSON-Anforderung deserialisieren, also fügen Sie dem Projekt die neueste Version des Newtonsoft.Json-Pakets hinzu. Dies ist der Code:

private async Task<List<PullRequestData>> GetPullRequestData()
{
  var gitHubResponse =
    await _httpClient.GetStringAsync(
    $”repos/dotnet/winforms/pulls?state=open”);
  var gitHubData =
    JsonConvert.DeserializeObject<List<PullRequestData>>(gitHubResponse);
  return gitHubData;
}

Dies kann nun von der RetrieveData_Button_Click-Methode aufgerufen werden. Sobald Sie eine Liste der gewünschten Daten besitzen, erstellen Sie eine Liste der Bezeichnungen für jeden Titel, damit Sie ihn auf dem Formular anzeigen können. Nachdem Sie die Liste der Bezeichnungen erstellt haben, können Sie diese der Benutzeroberfläche in der UpdateUI-Methode hinzufügen. Abbildung 3 zeigt dies.

Abbildung 3: Aufruf aus RetrieveData_Button_Click

private async void RetrieveData_Button_Click(object sender, EventArgs e)
{
  var pullRequestData = await GetPullRequestData();
  await Task.Run(() =>
  {
    var labelsToAdd = new List<Label>();
    var verticalSpaceBetweenLabels = 20;
    var horizontalSpaceFromLeft = 10;
    for (int i = 0; i < pullRequestData.Count; i++)
    {
      Label label = new Label();
      label.Text = pullRequestData[i].Title;
      label.Left = horizontalSpaceFromLeft;
      label.Size = new Size(100, 10);
      label.AutoSize = true;
      label.Top = (i * verticalSpaceBetweenLabels);
      labelsToAdd.Add(label);
    }
    UpdateUI(labelsToAdd);
  });
}

Ihre UpdateUI-Methode verwendet dann den synchronizationContext, um die Benutzeroberfläche zu aktualisieren:

public void UpdateUI(List<Label> labels)
{
  synchronizationContext.Post(new SendOrPostCallback(o =>
  {
    foreach (var label in labels)
    {
      Controls.Add(label);
    }
  }), labels);
}

Wenn Sie die Anwendung ausführen und auf die Schaltfläche „Microsoft“ klicken, wird die Benutzeroberfläche mit den Titeln aller offenen Pull Requests aus dem dotnet/winforms-Repository auf GitHub aktualisiert.

Jetzt sind Sie an der Reihe. Um dies wirklich zu einem zentralisierten Pull Request-Hub zu machen, wie der Titel dieses Artikels verspricht, aktualisieren wir dieses Beispiel so, dass es aus mehreren GitHub-Repositorys liest. Diese Repositorys müssen nicht unbedingt aus dem Microsoft-Team stammen, aber es macht Spaß, ihren Fortschritt zu verfolgen. Beispielsweise sind Microservicesarchitekturen sehr verbreitet, und in ihnen können Sie zahlreiche Repositorys verwenden, die Ihr System als Ganzes ausmachen. Da es in der Regel eine gute Idee ist, Branches und Pull Requests nicht zu lange ungemergt zu lassen, könnte ein solches Tool Ihre Einblicke in offene Pull Requests erhöhen und die Qualität Ihres gesamten Systems verbessern.

Sie könnten natürlich eine Web-App einrichten, aber dann müssten Sie sich um Bereitstellungen, den Ort ihrer Ausführung, Authentifizierung und dergleichen kümmern. Mit einer WinForms-Anwendung in .NET Core müssen Sie sich um keinen dieser Aspekte Gedanken machen. Werfen wir nun einen Blick auf einen der größten Vorteile der Erstellung einer WinForms-App mit .NET Core.

Verpacken der Anwendung

In der Vergangenheit konnte die Bereitstellung einer neuen oder aktualisierten WinForms-Anwendung Probleme im Zusammenhang mit der Version von .NET Framework verursachen, die auf den Hostcomputern installiert war. Mit .NET Core können Apps eigenständig bereitgestellt und von einem einzigen Ordner aus ausgeführt werden, ohne Abhängigkeiten von der auf dem Computer installierten Version von .NET Framework aufzuweisen. Das bedeutet, dass der Benutzer nichts installieren muss. Er kann die Anwendung einfach ausführen. Dies ermöglicht Ihnen auch, Anwendungen einzeln zu aktualisieren und bereitzustellen, da sich die verpackten Versionen von .NET Core nicht gegenseitig beeinflussen.

Die Beispiel-App in diesem Artikel soll als eigenständiges Paket zusammengestellt werden. Denken Sie daran, dass eigenständige Anwendungen größer sind, da sie auch die .NET Core-Bibliotheken enthalten. Wenn Sie die Bereitstellung auf Computern mit den neuesten Versionen von .NET Core durchführen, müssen Sie die App nicht als eigenständige App erstellen. Stattdessen können Sie die Größe der bereitgestellten App verringern, indem Sie die installierte Version von .NET Core nutzen. Eigenständige Optionen sind für den Fall gedacht, dass Ihre Anwendung nicht von der Umgebung abhängig sein soll, in der sie ausgeführt wird.

Um die Anwendung lokal zu verpacken, müssen Sie sicherstellen, dass der Entwicklermodus in Ihren Einstellungen aktiviert ist. Visual Studio zeigt eine Eingabeaufforderung an und stellt einen Link zu den Einstellungen zur Verfügung, wenn Sie versuchen, das Verpackungsprojekt auszuführen. Um den Entwicklermodus jedoch direkt zu aktivieren, navigieren Sie zu Ihren Windows-Einstellungen, drücken Sie die Windows-Taste und suchen Sie nach „Einstellungen“. Geben Sie im Suchfeld „Für Entwicklereinstellungen" ein, und wählen Sie diese Angabe aus. Es wird eine Option zum Aktivieren des Entwicklermodus angezeigt. Wählen Sie diese Option aus, und aktivieren Sie sie.

In den meisten Fällen werden Ihnen die Schritte zum Erstellen eines eigenständigen Pakets bekannt vorkommen, wenn Sie zuvor bereits eine WinForms-Anwendung verpackt haben. Beginnen Sie zunächst mit der Erstellung eines neuen Projekts für das Verpacken von Windows-Anwendungen. Nennen Sie das neue Projekt PullRequestHubPackaging. Wenn Sie aufgefordert werden, die Ziel- und Mindestversion der Plattform auszuwählen, verwenden Sie die Standardeinstellungen, und klicken Sie dann auf „OK“. Klicken Sie mit der rechten Maustaste auf „Anwendungen“, und fügen Sie einen Verweis auf das PullRequestHub-Projekt hinzu.

Nachdem der Verweis hinzugefügt wurde, müssen Sie das PullRequestHub-Projekt als Einstiegspunkt festlegen. Sobald dies geschehen ist, werden Sie beim nächsten Buildvorgang sehr wahrscheinlich den folgenden Fehler sehen: „Das Projekt "PullRequestHub" muss in der Projektdatei "RuntimeIdentifiers" angeben, wenn "SelfContained" TRUE ist.“

Um diesen Fehler zu beheben, bearbeiten Sie die Datei „PullRequestHub.csproj“. Wenn Sie diese Projektdatei öffnen, werden Sie einen weiteren Vorteil der Verwendung von .NET Core feststellen, da die Projektdatei nun das neue, schlanke Format verwendet. In auf .NET Framework basierenden WinForms-Projekten ist die Projektdatei viel ausführlicher mit expliziten Standardeinstellungen und Verweisen sowie NuGet-Verweisen, die in einer Datei „packages.config“ enthalten sind. Das neue Projektdateiformat speichert Paketverweise in der Projektdatei und ermöglicht es, alle Ihre Abhängigkeiten an einem Ort zu verwalten.

Fügen Sie in dieser Datei im ersten Knoten PropertyGroup die folgende Zeile hinzu:

<RuntimeIdentifiers>win-x86</RuntimeIdentifiers>

Ein Laufzeitbezeichner wird verwendet, um Zielplattformen zu identifizieren, auf denen die Anwendung ausgeführt wird. Er wird von .NET-Paketen verwendet, um plattformspezifische Ressourcen in NuGet-Paketen darzustellen. Sobald dieser hinzugefügt wurde, sollte der Buildvorgang erfolgreich sein, und Sie können das PullRequestHubPackaging-Projekt als Startprojekt in Visual Studio festlegen.

In der Datei „PullRequestHubPackaging.wapproj“ ist die Einstellung zu beachten, die angibt, dass das Projekt eigenständig ist. Der Codeabschnitt in der Datei, auf den Sie achten sollten, ist der folgende:

<ItemGroup>
  <ProjectReference Include=”..\PullRequestHub\PullRequestHub.csproj”>
    <DesktopBridgeSelfContained>True</DesktopBridgeSelfContained>
    <DesktopBridgeIdentifier>$(DesktopBridgeRuntimeIdentifier)
    </DesktopBridgeIdentifier>
      <Properties>SelfContained=%(DesktopBridgeSelfContained);
        RuntimeIdentifier=%(DesktopBridgeIdentifier)
      </Properties>
    <SkipGetTargetFrameworkProperties>True
    </SkipGetTargetFrameworkProperties>
  </ProjectReference>
</ItemGroup>

Hier sehen Sie, dass die Option DesktopBridgeSelfContained auf TRUE festgelegt ist, was es ermöglicht, die WinForms-Anwendung mit den .NET Core-Binärdateien zu verpacken. Wenn Sie das Projekt ausführen, werden die Dateien in einen Ordner namens „win-x86“ gespeichert, der sich in einem ähnlichen Pfad wie in diesem Beispiel befindet:

C:\Your-Path\PullRequestHub\PullRequestHub\bin\x86\Debug\netcoreapp3.0

Im Ordner „win-x86“ finden Sie zahlreiche DLLs, die alles enthalten, was die eigenständige App für ihre Ausführung benötigt.

Wahrscheinlich möchten Sie die App jedoch als quergeladene Anwendung bereitstellen oder in den Microsoft Store hochladen. Das Querladen ermöglicht automatische Updates mithilfe einer appinstaller-Datei. Diese Updates werden ab Visual Studio 2017, Update 15.7 unterstützt. Sie können auch Pakete erstellen, die Sie über den Microsoft Store vertreiben können. Der Microsoft Store übernimmt dann die Codesignierung, die Verteilung und die Aktualisierung der App.

Zusätzlich zu diesen Optionen wird zurzeit daran gearbeitet, dass Anwendungen in eine einzige ausführbare Datei verpackt werden können, sodass kein Ausgabeverzeichnis mit DLLs mehr erforderlich ist.

Weitere Vorteile

Mit .NET Core 3.0 sind Sie auch in der Lage, Funktionen von C# 8.0 zu nutzen, etwa Nullwerte zulassende Verweistypen, Standardimplementierungen für Schnittstellen, Verbesserungen bei Schalteranweisungen mithilfe von Mustern und asynchrone Datenströme. Um C# 8.0 zu aktivieren, öffnen Sie die Datei „PullRequestHub.csproj“, und fügen Sie der ersten PropertyGroup die folgende Zeile hinzu:

<LangVersion>8.0</LangVersion>

Ein weiterer Vorteil bei der Verwendung von .NET Core und WinForms besteht darin, dass beide Projekte Open-Source-Lösungen sind. Dies gibt Ihnen Zugriff auf den Quellcode und ermöglicht es, Fehler zu melden, Feedback zu teilen und Mitwirkender zu werden. Sehen Sie sich das Windows Forms-Projekt unter github.com/dotnet/winforms an.

.NET Core 3.0 verspricht, den Investitionen neuen Schwung zu verleihen, die Unternehmen und Organisationen in WinForms-Anwendungen getätigt haben, die weiterhin produktiv, zuverlässig und einfach bereitzustellen und zu verwalten sind. Entwickler können neue .NET Core-spezifische Klassen wie HttpClientFactory nutzen, C# 8.0-Funktionen wie Nullwerte zulassende Verweistypen verwenden und eigenständige Anwendungen als Paket zusammenstellen. Sie erhalten außerdem Zugriff auf die .NET Core CLI und alle Leistungsverbesserungen, die mit .NET Core einhergehen.


Eric Fleming ist Senior Software Engineer mit mehr als einem Jahrzehnt Erfahrung im Umgang mit Tools und Technologien von Microsoft. Er bloggt unter ericflemingblog.com und ist Co-Host des YouTube-Kanals „Function Junction“, der sich mit Azure Functions beschäftigt. Folgen Sie ihm auf Twitter: @efleming18.

Unser Dank gilt den folgenden technischen Experten für die Durchsicht dieses Artikels: Olia Gavrysh (Microsoft), Simon Timms


Diesen Artikel im MSDN Magazine-Forum diskutieren