Migrieren einer Windows Forms-Desktopanwendung zu .NET 5

In diesem Artikel wird beschrieben, wie eine Windows Forms-Desktopanwendung von .NET Framework zu .NET 5 oder höher migriert wird. Das .NET SDK bietet Unterstützung für Windows Forms-Anwendungen. Windows Forms ist immer noch ein ausschließlich für Windows bestimmtes Framework und kann nur unter Windows ausgeführt.

Für die Migration einer Anwendung von .NET Framework zu .NET 5 ist im Allgemeinen eine neue Projektdatei erforderlich. Bei .NET 5 werden Projektdateien im SDK-Format verwendet, während bei .NET Framework in der Regel ältere Visual Studio-Projektdateien zum Einsatz kommen. Wenn Sie jemals eine Visual Studio-Projektdatei in einem Text-Editor geöffnet haben, wissen Sie, wie detailliert diese ist. Projekte im SDK-Format sind kleiner und erfordern weniger Einträge als Projekte im älteren Dateiformat.

Weitere Informationen zu .NET 5 finden Sie unter Einführung in .NET.

Ausprobieren des Upgrade-Assistenten

Der .NET-Upgrade-Assistent ist ein Befehlszeilentool, das für verschiedene Arten von .NET Framework-Apps ausgeführt werden kann. Es soll ein Upgrade von .NET Framework-Apps auf .NET 5 vereinfachen. Nachdem Sie das Tool ausgeführt haben, ist zum Abschließen der App-Migration in den meisten Fällen mehr Aufwand erforderlich. Das Tool umfasst die Installation von Analysetools, die beim Durchführen der Migration helfen können.

Weitere Informationen finden Sie unter Upgraden einer WPF-App auf .NET 5 mit dem .NET-Upgrade-Assistenten.

Voraussetzungen

  • Visual Studio 2019, Version 16.8, Vorschauversion

  • Vorschauversion des WinForms-Designers in Visual Studio.

    Um den Designer zu aktivieren, wechseln Sie zu Extras > Optionen > Umgebung > Vorschaufeatures, und wählen Sie Option Use the preview Windows Forms designer for .NET Core apps (Vorschauversion des Windows Forms-Designers für .NET Core-Apps verwenden) aus.

  • In diesem Artikel wird die Beispielanwendung Vergleichsspiel verwendet. Wenn Sie diese Anwendung verwenden möchten, laden Sie sie herunter, und öffnen Sie sie in Visual Studio. Andernfalls verwenden Sie Ihre eigene Anwendung.

Consider

Wenn Sie eine .NET Framework Windows Forms-Anwendung migrieren, müssen Sie ein paar Dinge berücksichtigen.

  1. Überprüfen Sie, ob Ihre Anwendung ein guter Kandidat für die Migration ist.

    Verwenden Sie .NET Portability Analyzer, um zu bestimmen, ob Ihr Projekt zu .NET 5 migriert werden kann. Wenn bei Ihrem Projekt Probleme mit .NET 5 vorliegen, können Sie diese Probleme mit dem Analyzer identifizieren. Das Tool .NET Portability Analyzer kann als Visual Studio-Erweiterung installiert oder über die Befehlszeile verwendet werden. Weitere Informationen finden Sie unter .NET Portability Analyzer.

  2. Sie verwenden eine andere Version von Windows Forms.

    Als .NET Core 3.0 veröffentlicht wurde, wurde Windows Forms als Open-Source-Version auf GitHub zur Verfügung gestellt. Der Code für Windows Forms für .NET 5 ist ein Fork der .NET Framework-Windows Forms-Codebasis. Es ist möglich, dass einige Unterschiede bestehen, und Ihre Anwendung schwierig zu migrieren ist.

  3. Das Windows Compatibility Pack könnte Ihnen bei der Migration helfen.

    Einige APIs, die in .NET Framework verfügbar sind, sind nicht in .NET 5 verfügbar. Das Windows Compatibility Pack fügt viele dieser APIs hinzu und könnte zur Kompatibilität Ihrer Windows Forms-App mit .NET 5 beitragen.

  4. Aktualisieren Sie die NuGet-Pakete, die von Ihrem Projekt verwendet werden.

    Es hat sich bewährt, vor jeder Migration die neuesten Versionen der NuGet-Pakete zu verwenden. Wenn Ihre Anwendung auf NuGet-Pakete verweist, aktualisieren Sie sie auf die neueste Version. Stellen Sie sicher, dass die Anwendung erfolgreich erstellt wird. Wenn nach dem Upgrade Paketfehler auftreten, stufen Sie das Paket auf die neueste Version herab, die Ihren Code nicht beschädigt.

Sichern von Projekten

Beim Migrieren eines Projekts müssen Sie das Projekt zunächst einmal sichern. Wenn etwas schief geht, können Sie Ihren Code in den ursprünglichen Zustand zurückversetzen, indem Sie die Sicherung wiederherstellen. Verlassen Sie sich beim Sichern eines Projekts nicht auf Tools wie .NET Portability Analyzer. Am besten erstellen Sie selbst eine Kopie des ursprünglichen Projekts.

NuGet-Pakete

Wenn Ihr Projekt auf NuGet-Pakete verweist, befindet sich in Ihrem Projektordner vermutlich eine packages.config-Datei. Bei Projekten im SDK-Format werden NuGet-Paketverweise in der Projektdatei konfiguriert. In Visual Studio-Projektdateien können optional ebenfalls NuGet-Pakete definiert werden. Bei .NET 5 werden für NuGet-Pakete keine packages.config-Dateien verwendet. NuGet-Paketverweise müssen vor der Migration in die Projektdatei migriert werden.

Gehen Sie wie folgt vor, um die packages.config-Datei zu migrieren:

  1. Suchen Sie in Projektmappen-Explorer nach dem Projekt, das migriert werden soll.
  2. Klicken Sie mit der rechten Maustaste auf packages.config > „packages.config“ zu PackageReference migrieren.
  3. Wählen Sie alle Pakete auf oberster Ebene aus.

Es wird ein Buildbericht erstellt, um Sie über mögliche Probleme bei der Migration der NuGet-Pakete zu informieren.

Projektdatei

Als Nächstes müssen Sie bei der Migration einer Anwendung die Projektdatei konvertieren. Wie bereits erwähnt, werden bei .NET 5 Projektdateien im SDK-Format verwendet. Visual Studio-Projektdateien, die bei .NET Framework verwendet werden, werden nicht geladen. Es kann jedoch sein, das Sie bereits Projekte im SDK-Format verwenden. Den Unterschied können Sie in Visual Studio leicht erkennen. Klicken Sie mit der rechten Maustaste in Projektmappen-Explorer, und suchen Sie nach der Menüoption Projektdatei bearbeiten. Wenn dieses Menüelement nicht angezeigt wird, verwenden Sie das alte Visual Studio-Projektformat und müssen ein Upgrade ausführen.

Konvertieren alle Projekte in Ihrer Projektmappe. Wenn Sie die bereits erwähnte Beispielanwendung verwenden, werden die beiden Projekte MatchingGame und MatchingGame.Logic konvertiert.

Gehen Sie wie folgt vor, um ein Projekt zu konvertieren:

  1. Suchen Sie in Projektmappen-Explorer nach dem Projekt, das migriert werden soll.

  2. Klicken Sie mit der rechten Maustaste auf das Projekt, und wählen Sie Projekt entladen aus.

  3. Klicken Sie mit der rechten Maustaste auf das Projekt, und wählen Sie Projektdatei bearbeiten aus.

  4. Kopieren Sie den XML-Code des Projekt, und fügen Sie ihn in einen Text-Editor ein. Sie sollten eine Kopie verwenden, sodass Sie ohne großen Aufwand Inhalte in das neue Projekt verschieben können.

  5. Löschen Sie den Inhalt der Datei, und fügen Sie den folgenden XML-Code ein:

    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <OutputType>WinExe</OutputType>
        <TargetFramework>net5.0-windows</TargetFramework>
        <UseWindowsForms>true</UseWindowsForms>
        <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
      </PropertyGroup>
    
    </Project>
    

    Wichtig

    Mit Bibliotheken muss keine <OutputType>-Einstellung definiert werden. Entfernen Sie diesen Eintrag, wenn Sie ein Bibliotheksprojekt aktualisieren.

Dieser XML-Code stellt die grundlegende Struktur des Projekts dar. Er enthält jedoch keine Einstellung aus der alten Projektdatei. Führen Sie die folgenden Schritte aus, und verwenden Sie dabei die zuvor in einen Text-Editor kopierten alten Projektinformationen:

  1. Kopieren Sie die folgenden Elemente aus der alten Projektdatei in das <PropertyGroup>-Element in der neuen Projektdatei:

    • <RootNamespace>
    • <AssemblyName>

    Die Projektdatei sollte in etwa wie der folgende XML-Code aussehen:

    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <OutputType>WinExe</OutputType>
        <TargetFramework>net5.0-windows</TargetFramework>
        <UseWindowsForms>true</UseWindowsForms>
        <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
    
        <RootNamespace>MatchingGame</RootNamespace>
        <AssemblyName>MatchingGame</AssemblyName>
      </PropertyGroup>
    
    </Project>
    
  2. Kopieren Sie die <ItemGroup>-Elemente aus der alten Projektdatei, zu denen <ProjectReference> oder <PackageReference> gehört, in der neuen Datei an eine Stelle nach dem schließenden Tag </PropertyGroup>.

    Die Projektdatei sollte in etwa wie der folgende XML-Code aussehen:

    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        (contains settings previously described)
      </PropertyGroup>
    
      <ItemGroup>
        <ProjectReference Include="..\MatchingGame.Logic\MatchingGame.Logic.csproj">
          <Project>{36b3e6e2-a9ae-4924-89ae-7f0120ce08bd}</Project>
          <Name>MatchingGame.Logic</Name>
        </ProjectReference>
      </ItemGroup>
      <ItemGroup>
        <PackageReference Include="MetroFramework">
          <Version>1.2.0.3</Version>
        </PackageReference>
      </ItemGroup>
    
    </Project>
    

    Da die <ProjectReference>-Elemente keine untergeordneten <Project>- und <Name>-Elemente benötigen, können Sie diese Einstellungen entfernen:

    <ItemGroup>
      <ProjectReference Include="..\MatchingGame.Logic\MatchingGame.Logic.csproj" />
    </ItemGroup>
    

Ressourcen und Einstellungen

Ein wichtiger Aspekt im Unterschied zwischen .NET Framework-Projekten und den von .NET 5 verwendeten Projekten im SDK-Format ist, dass .NET Framework-Projekte ein Abonnementmodell für Codedateien verwenden. Alle Codedateien, die Sie kompilieren möchten, müssen explizit in der Projektdatei definiert sein. Bei Projekten im SDK-Format ist es umgekehrt. Sie nehmen standardmäßig das Deaktivierverhalten an: Alle Codedateien, die aus dem Projektverzeichnis und darunter beginnen, werden automatisch in Ihr Projekt eingefügt. Sie müssen diese Einträge nicht migrieren, wenn sie einfach und ohne Einstellungen sind. Dies gilt auch für andere gängige Dateien wie z. B. RESX.

Windows Forms-Projekte können auch auf die folgenden Dateien verweisen:

  • Properties\Settings.settings
  • Properties\Resources.resx
  • Properties\app.manifest

Auf die Datei app.manifest wird automatisch von Ihrem Projekt verwiesen, und Sie müssen für die Migration keine speziellen Vorbereitungen treffen.

Alle *.resx- - und *.settings-Dateien im Ordner Eigenschaften müssen im Projekt migriert werden. Kopieren Sie diese Einträge aus der alten Projektdatei in ein <ItemGroup>-Element im neuen Projekt. Ändern Sie nach dem Kopieren der Einträge alle <Compile Include="value">-Elemente so, dass das Update-Attribut anstelle von Include verwendet wird.

  • Importieren Sie die Konfiguration für die Settings.settings-Datei.

    <ItemGroup>
      <None Update="Properties\Settings.settings">
        <Generator>SettingsSingleFileGenerator</Generator>
        <LastGenOutput>Settings.Designer.cs</LastGenOutput>
      </None>
      <Compile Update="Properties\Settings.Designer.cs">
        <AutoGen>True</AutoGen>
        <DependentUpon>Settings.settings</DependentUpon>
        <DesignTimeSharedInput>True</DesignTimeSharedInput>
      </Compile>
    </ItemGroup>
    

    Wichtig

    Bei Visual Basic-Projekten wird als Standarddatei für Projekteinstellungen der Ordner My Project, bei C#-Projekten dagegen der Ordner Properties verwendet.

  • Importieren Sie die Konfiguration für alle resx-Dateien, z. B. für die Datei properties\Resources.resx. Beachten Sie, dass das Include-Attribut im <Compile>- und <EmbeddedResource>-Element in Update geändert und <EmbeddedResource> aus <SubType> entfernt wurde:

    <ItemGroup>
      <EmbeddedResource Update="Properties\Resources.resx">
        <Generator>ResXFileCodeGenerator</Generator>
        <LastGenOutput>Resources.Designer.cs</LastGenOutput>
      </EmbeddedResource>
      <Compile Update="Properties\Resources.Designer.cs">
        <AutoGen>True</AutoGen>
        <DependentUpon>Resources.resx</DependentUpon>
        <DesignTime>True</DesignTime>
      </Compile>
    </ItemGroup>
    

    Wichtig

    Bei Visual Basic-Projekten wird als Standarddatei für die Projektressource der Ordner My Project, bei C#-Projekten dagegen der Ordner Properties verwendet.

Visual Basic

Bei Projekten in der Sprache Visual Basic müssen zusätzliche Konfigurationsschritte durchgeführt werden.

  1. Importieren Sie die Einstellung My Project\Application.myapp der Konfigurationsdatei. Beachten Sie, dass das <Compile>-Element das Update-Attribut anstelle des Include-Attributs verwendet.

    <ItemGroup>
      <None Include="My Project\Application.myapp">
        <Generator>MyApplicationCodeGenerator</Generator>
        <LastGenOutput>Application.Designer.vb</LastGenOutput>
      </None>
      <Compile Update="My Project\Application.Designer.vb">
        <AutoGen>True</AutoGen>
        <DependentUpon>Application.myapp</DependentUpon>
        <DesignTime>True</DesignTime>
      </Compile>
    </ItemGroup>
    
  2. Fügen Sie dem <PropertyGroup>-Element die <MyType>WindowsForms</MyType>-Einstellung hinzu:

    <PropertyGroup>
      (contains settings previously described)
    
      <MyType>WindowsForms</MyType>
    </PropertyGroup>
    

    Mit dieser Einstellung werden die My-Namespacemember importiert, mit denen Visual Basic-Programmierer vertraut sind.

  3. Importieren Sie die vom Projekt definierten Namespaces.

    Mit Visual Basic-Projekten können Namespaces automatisch in jede Codedatei importiert werden. Kopieren Sie die <ItemGroup>-Elemente aus der alten Projektdatei, zu denen <Import> gehört, in der neuen Datei an eine Stelle nach dem schließenden Tag </PropertyGroup>.

    <ItemGroup>
      <Import Include="Microsoft.VisualBasic" />
      <Import Include="System" />
      <Import Include="System.Collections" />
      <Import Include="System.Collections.Generic" />
      <Import Include="System.Data" />
      <Import Include="System.Drawing" />
      <Import Include="System.Diagnostics" />
      <Import Include="System.Windows.Forms" />
      <Import Include="System.Linq" />
      <Import Include="System.Xml.Linq" />
      <Import Include="System.Threading.Tasks" />
    </ItemGroup>
    

    Wenn keine <Import>-Anweisungen vorhanden sind oder beim Kompilieren des Projekts Fehler auftreten, überprüfen Sie, ob im Projekt zumindest die folgenden <Import>-Anweisungen definiert sind:

    <ItemGroup>
      <Import Include="System.Data" />
      <Import Include="System.Drawing" />
      <Import Include="System.Windows.Forms" />
    </ItemGroup>
    
  4. Kopieren Sie die Einstellungen <Option*> und <StartupObject> aus dem ursprünglichen Projekt in das <PropertyGroup>-Element:

    <PropertyGroup>
      (contains settings previously described)
    
      <OptionExplicit>On</OptionExplicit>
      <OptionCompare>Binary</OptionCompare>
      <OptionStrict>Off</OptionStrict>
      <OptionInfer>On</OptionInfer>
      <StartupObject>MatchingGame.My.MyApplication</StartupObject>
    </PropertyGroup>
    

Erneutes Laden des Projekts

Nachdem Sie ein Projekt in das neue SDK-Format konvertiert haben, laden Sie das Projekt erneut in Visual Studio:

  1. Suchen Sie in Projektmappen-Explorer nach dem Projekt, das konvertiert werden soll.

  2. Klicken Sie mit der rechten Maustaste auf das Projekt, und wählen Sie Projekt erneut laden aus.

    Wenn beim Laden des Projekts ein Fehler auftritt, enthält der XML-Code des Projekts möglicherweise einen Fehler. Öffnen Sie die Projektdatei zur Bearbeitung, suchen Sie nach dem Fehler, und beheben Sie ihn. Wenn Sie keinen Fehler finden, versuchen Sie es noch mal.

Bearbeiten der Datei „App.config“

Wenn Ihre Anwendung eine App.config-Datei enthält, entfernen Sie das <supportedRuntime>-Element:

<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />

Im Zusammenhang mit der Datei App.config müssen einige Dinge berücksichtigt werden. Die Datei App.config in .NET Framework wurde nicht nur zum Konfigurieren der Anwendung, sondern auch zum Konfigurieren von Laufzeiteinstellungen und Verhaltensweisen wie die Protokollierung verwendet. Ab .NET 5 (und in .NET Core) wird die Datei App.config nicht mehr für die Laufzeitkonfiguration verwendet. Wenn Ihre App.config-Datei diese Abschnitte enthält, werden diese nicht berücksichtigt.

Hinzufügen des Kompatibilitätspakets

Wenn Ihre Projektdatei ordnungsgemäß geladen wird, bei der Kompilierung für Ihr Projekt jedoch ein Fehler auftritt und Fehlermeldungen wie die folgende angezeigt werden:

  • Der Typ oder Namespace <some name> wurde nicht gefunden
  • Der Name <some name> ist im aktuellen Kontext nicht vorhanden

Müssen Sie Ihrer Anwendung möglicherweise das Microsoft.Windows.Compatibility-Paket hinzufügen. Mit diesem Paket werden etwa 21.000 .NET-APIs aus .NET Framework wie die System.Configuration.ConfigurationManager-Klasse und APIs für die Interaktion mit der Windows-Registrierung hinzugefügt. Fügen Sie das Paket Microsoft.Windows.Compatibility hinzu.

Bearbeiten Sie die Projektdatei, und fügen Sie das folgende <ItemGroup>-Element hinzu:

<ItemGroup>
  <PackageReference Include="Microsoft.Windows.Compatibility" Version="5.0.0" />
</ItemGroup>

Testen Ihrer App

Testen Sie Ihre Anwendung, nachdem Sie sie migriert haben.

Nächste Schritte