다음을 통해 공유


WPF 데스크톱 앱을 .NET 8로 업그레이드하는 방법

이 문서에서는 WPF(Windows Presentation Foundation) 데스크톱 앱을 .NET 8로 업그레이드하는 방법을 설명합니다. WPF는 플랫폼 간 기술인 .NET에서 실행되지만 WPF는 여전히 Windows 전용 프레임워크입니다. 다음 WPF 관련 프로젝트 형식은 .NET 업그레이드 도우미를 사용하여 업그레이드할 수 있습니다.

  • WPF 프로젝트
  • 컨트롤 라이브러리
  • .NET 라이브러리

.NET Framework에서 .NET으로 업그레이드하는 경우 WPF .NET과의 차이점 문서와 .NET Framework에서 .NET으로 포팅 가이드를 검토해 보세요.

필수 조건

데모 앱

이 문서는 .NET 샘플 GitHub 리포지토리에서 다운로드할 수 있는 웹 즐겨찾기 샘플 프로젝트를 업그레이드하는 컨텍스트에서 작성되었습니다.

업그레이드 시작

여러 프로젝트를 업그레이드하는 경우 종속성이 없는 프로젝트부터 시작합니다. 웹 즐겨찾기 샘플에서 WebSiteRatings 프로젝트는 StarVoteControl 라이브러리에 의존하므로 StarVoteControl을 먼저 업그레이드해야 합니다.

소스 제어나 복사본 등 코드를 백업해 두세요.

Visual Studio에서 프로젝트를 업그레이드하려면 다음 단계를 따릅니다.

  1. 솔루션 탐색기 창에서 StarVoteControl 프로젝트를 마우스 오른쪽 단추로 클릭하고 업그레이드를 선택합니다.

    Visual Studio에서 .NET 업그레이드 도우미의 업그레이드 메뉴 항목입니다.

    Visual Studio의 .NET 업그레이드 도우미 업그레이드 메뉴 항목입니다.

  2. 현재 위치 프로젝트 업그레이드를 선택합니다.

  3. 다음으로 대상 프레임워크를 선택합니다. 업그레이드하는 프로젝트 형식에 따라 다양한 옵션이 제공됩니다. 라이브러리가 WPF와 같은 데스크톱 기술에 의존하지 않고 .NET Framework 프로젝트와 .NET 프로젝트 모두에서 사용할 수 있는 경우 .NET Standard 2.0이 좋은 선택입니다. 그러나 최신 .NET 릴리스는 .NET Standard에 비해 많은 언어 및 컴파일러 개선 사항을 제공합니다.

    .NET 8.0을 선택한 후 다음을 선택합니다.

  4. 코드 파일, 라이브러리 등 프로젝트와 관련된 모든 아티팩트가 포함된 트리가 표시됩니다. 개별 아티팩트 또는 전체 프로젝트를 업그레이드할 수 있으며 이는 기본값입니다. 업그레이드를 시작하려면 업그레이드 선택을 선택합니다.

    업그레이드가 완료되면 결과가 표시됩니다.

    21개 항목 중 7개 항목을 건너뛴 것으로 표시된 .NET 업그레이드 도우미의 업그레이드 결과 탭.

    단색 녹색 원이 있는 아티팩트는 업그레이드되었으며 빈 녹색 원은 건너뛰었습니다. 건너뛴 아티팩트는 업그레이드 도우미가 업그레이드할 항목을 찾지 못했음을 의미합니다.

이제 앱의 지원 라이브러리가 업그레이드되었으므로 기본 앱을 업그레이드합니다.

앱 업그레이드

모든 지원 라이브러리가 업그레이드되면 기본 앱 프로젝트를 업그레이드할 수 있습니다. 다음 단계를 수행합니다.

  1. 솔루션 탐색기 창에서 WebSiteRatings 프로젝트를 마우스 오른쪽 단추로 클릭하고 업그레이드를 선택합니다.
  2. 업그레이드 모드로 현재 위치 프로젝트 업그레이드를 선택합니다.
  3. 대상 프레임워크로 .NET 8.0을 선택하고 다음을 선택합니다.
  4. 모든 아티팩트를 선택한 상태로 두고 업그레이드 선택을 선택합니다.

업그레이드가 완료되면 결과가 표시됩니다. 항목에 경고 기호가 있으면 읽어야 할 메모가 있다는 의미이며 항목을 확장하여 읽을 수 있습니다.

클린 빌드 생성

프로젝트가 업그레이드된 후 정리하고 컴파일합니다.

  1. 솔루션 탐색기 창에서 WebSiteRatings 프로젝트를 마우스 오른쪽 단추로 클릭하고 정리를 선택합니다.
  2. 솔루션 탐색기 창에서 WebSiteRatings 프로젝트를 마우스 오른쪽 단추로 클릭하고 빌드를 선택합니다.

애플리케이션에서 오류가 발생한 경우 오류 목록 창에서 해당 오류를 찾아 해결 방법을 제안할 수 있습니다.

업그레이드 후 단계

프로젝트가 .NET Framework에서 .NET으로 업그레이드되는 경우 .NET Framework에서 .NET으로 업그레이드한 후 현대화 문서의 정보를 검토합니다.

업그레이드 후에는 다음을 수행할 수 있습니다.

  • NuGet 패키지를 확인합니다.

    .NET 업그레이드 도우미는 일부 패키지를 새 버전으로 업그레이드했습니다. 이 문서에 제공된 샘플 앱을 사용하면 Microsoft.Data.Sqlite NuGet 패키지가 1.0.0에서 8.0.x로 업그레이드되었습니다. 그러나 1.0.0SQLite NuGet 패키지에 의존하지만 8.0.x는 해당 종속성을 제거합니다. SQLite NuGet 패키지는 더 이상 필요하지 않지만 프로젝트에서 계속 참조됩니다. SQLiteSQLite.Native NuGet 패키지를 모두 프로젝트에서 제거할 수 있습니다.

  • 이전 NuGet 패키지를 정리합니다.

    이제 NuGet 패키지 참조가 프로젝트 파일에 선언되었으므로 packages.config 파일은 더 이상 필요하지 않으며 프로젝트에서 삭제할 수 있습니다. 또한 Packages라는 로컬 NuGet 패키지 캐시 폴더는 프로젝트의 폴더 또는 부모 폴더에 있습니다. 이 로컬 캐시 폴더는 삭제할 수 있습니다. 새로운 NuGet 패키지 참조는 사용자 프로필 디렉터리에서 사용할 수 있는 .nuget\packages라는 패키지용 전역 캐시 폴더를 사용합니다.

  • System.Configuration 라이브러리를 제거합니다.

    대부분의 .NET Framework 앱은 System.Configuration 라이브러리를 참조하세요. 업그레이드 후에도 이 라이브러리가 계속 직접 참조될 수 있습니다.

    System.Configuration 라이브러리는 app.config 파일을 사용하여 앱에 런타임 구성 옵션을 제공합니다. .NET의 경우 이 라이브러리는 System.Configuration.ConfigurationManager NuGet 패키지로 바뀌었습니다. 라이브러리에 대한 참조를 제거하고 프로젝트에 NuGet 패키지를 추가합니다.

  • 앱을 현대화할 수 있는 장소를 확인합니다.

    .NET이 릴리스된 이후 API와 라이브러리가 상당히 변경되었습니다. 그리고 대부분의 경우 .NET Framework에서는 이러한 개선 사항에 액세스할 수 없습니다. .NET으로 업그레이드하면 이제 더 최신 라이브러리에 액세스할 수 있습니다.

    다음 섹션에서는 이 문서에서 사용되는 샘플 앱을 현대화하는 영역을 설명합니다.

현대화: 웹 브라우저 컨트롤

WPF 샘플 앱이 참조하는 WebBrowser 컨트롤은 오래된 Internet Explorer를 기반으로 합니다. .NET용 WPF는 Microsoft Edge 기반의 WebView2 컨트롤을 사용할 수 있습니다. 다음 단계를 완료하여 새 WebView2 웹 브라우저 컨트롤로 업그레이드합니다.

  1. Microsoft.Web.WebView2 NuGet 패키지를 추가합니다.

  2. MainWindow.xaml 파일에서 다음을 수행합니다.

    1. 루트 요소의 wpfControls 네임스페이스로 컨트롤을 가져옵니다.

      <mah:MetroWindow x:Class="WebSiteRatings.MainWindow"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
              xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
              xmlns:local="clr-namespace:WebSiteRatings"
              xmlns:vm="clr-namespace:WebSiteRatings.ViewModels"
              xmlns:VoteControl="clr-namespace:StarVoteControl;assembly=StarVoteControl"
              xmlns:wpfControls="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
              Loaded="MetroWindow_Loaded"
              mc:Ignorable="d"
              Title="My Sites" Height="650" Width="1000">
      
    2. <Border> 요소가 선언된 아래쪽에서 WebBrowser 컨트롤을 제거하고 wpfControls:WebView2 컨트롤로 교체합니다:

      <Border Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" BorderThickness="1" BorderBrush="Black" Margin="5">
          <wpfControls:WebView2 x:Name="browser" ScrollViewer.CanContentScroll="True" />
      </Border>
      
  3. MainWindow.xaml.cs 코드 숨김 파일을 편집합니다. ListBox_SelectionChanged 메서드를 업데이트하여 browser.Source 속성을 유효한 Uri(으)로 설정합니다. 이 코드는 이전에 웹 사이트 URL에 문자열로 전달되었지만 WebView2 컨트롤에는 Uri이(가) 필요합니다.

    private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var siteCollection = (ViewModels.SiteCollection)DataContext;
    
        if (siteCollection.SelectedSite != null)
            browser.Source = new Uri(siteCollection.SelectedSite.Url);
        else
            browser.NavigateToString("<body></body>");
    }
    

앱 사용자가 실행 중인 Windows 버전에 따라 WebView2 런타임을 설치해야 할 수 있습니다. 자세한 내용은 WPF 앱에서 WebView2 시작을 참조하세요.

현대화: appsettings.json

.NET Framework는 App.config 파일을 사용하여 연결 문자열 및 로깅 공급자와 같은 앱에 대한 설정을 로드합니다. 이제 .NET은 앱 설정에 appsettings.json 파일을 사용합니다. App.config 파일은 System.Configuration.ConfigurationManager NuGet 패키지를 통해 .NET에서 지원되며 appsettings.json에 대한 지원은 Microsoft.Extensions.Configuration NuGet 패키지에서 제공됩니다.

다른 라이브러리가 .NET으로 업그레이드되면 App.config 대신 appsettings.json을 지원하여 현대화됩니다. 예를 들어 .NET 6 이상용으로 업그레이드된 .NET Framework의 로깅 공급자는 더 이상 설정에 App.config를 사용하지 않습니다. 지시를 따르고 가능하면 App.config를 사용하지 않는 것이 좋습니다.

WPF 샘플 앱에서 appsettings.json 사용

예를 들어, WPF 샘플 앱을 업그레이드한 후 로컬 데이터베이스에 대한 연결 문자열로 appsettings.json을 사용합니다.

  1. System.Configuration.ConfigurationManager NuGet 패키지를 제거합니다.

  2. Microsoft.Extensions.Configuration.Json NuGet 패키지를 추가합니다.

  3. appsettings.json이라는 프로젝트에 파일을 추가합니다.

  4. 출력 디렉터리에 복사할 appsettings.json 파일을 설정합니다.

    솔루션 탐색기에서 파일을 선택한 후 속성 창을 사용하여 Visual Studio를 통해 출력으로 복사 설정을 지정합니다. 또는 프로젝트를 직접 편집하고 다음 ItemGroup을 추가할 수 있습니다.

      <ItemGroup>
        <Content Include="appsettings.json">
          <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </Content>
      </ItemGroup>
    
  5. App.config 파일의 설정을 새 appsettings.json 파일로 마이그레이션합니다.

    WPF 샘플 앱에서 app.config에는 단일 연결 문자열만 포함되어 있습니다. appsettings.json 파일을 편집하여 연결 문자열을 정의합니다.

    {
      "ConnectionStrings": {
        "database": "DataSource=sqlite.db;"
      }
    }
    
  6. App.xaml.cs 파일을 편집하여 appsettings.json 파일을 로드하는 구성 개체를 인스턴스화하면 추가된 줄이 강조 표시됩니다.

    using System.Windows;
    using Microsoft.Extensions.Configuration;
    
    namespace WebSiteRatings
    {
        /// <summary>
        /// Interaction logic for App.xaml
        /// </summary>
        public partial class App : Application
        {
            public static IConfiguration Config { get; private set; }
    
            public App()
            {
                Config = new ConfigurationBuilder()
                    .AddJsonFile("appsettings.json")
                    .Build();
            }
        }
    }
    
  7. .\Models\Database.cs 파일에서 새 App.Config 속성을 사용하도록 OpenConnection 메서드를 변경합니다. 이렇게 하려면 Microsoft.Extensions.Configuration 네임스페이스를 가져와야 합니다.

    using Microsoft.Data.Sqlite;
    using System.Collections.Generic;
    using Microsoft.Extensions.Configuration;
    
    namespace WebSiteRatings.Models
    {
        internal class Database
        {
            public static SqliteConnection OpenConnection() =>
                new SqliteConnection(App.Config.GetConnectionString("database"));
    
            public static IEnumerable<Site> ReadSites()
    

    GetConnectionString은(는) Microsoft.Extensions.Configuration 네임스페이스에서 제공하는 확장 메서드입니다.