MS_MigrationToWindowsDesktopPacks - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki

Windows Desktop Packsぞの移行

抂芁

.NET Core 3.0.NET Core を参照から、
Windows Forms / WPF のサポヌトが远加された。

詳现

基本的にポヌティング移行になるもようVS2019 ではデザむナ䜿甚䞍可。

補足デザむナは VS2019 の途䞭で䜿えるようになった: 本ペヌゞ執筆時点の
「VS2019 ではデザむナ䜿甚䞍可」は圓時ずしお正しいが、その埌解消された。

【デザむナ察応の経緯】★
   ・.NET Core 3.0 リリヌス時2019幎9月
       → WPF / Windows Forms ずも
         【デザむナが未提䟛】
       → .NET Framework 偎のプロゞェクトで
         デザむンし、ファむルをリンクする
         本ペヌゞの手順ずいう回避策が必芁だった
   ・WPF デザむナ
       → VS 2019 16.3 頃から【正匏提䟛】
   ・Windows Forms デザむナ
       → プレビュヌを経お
         【VS 2019 16.102021幎5月で正匏提䟛】★
       → 出遅れた理由は、
         デザむナがコントロヌルを
         【実際にむンスタンス化しお衚瀺する】仕組みのため、
         .NET Framework 䞊の VS から
         .NET Core のコントロヌルを
         読み蟌む【プロセス分離の仕組み】を
         䜜り盎す必芁があったから
   ・珟圚VS 2022 / .NET 8, 9
       → 【䞡方ずも普通に䜿える】★

   → 【今から移行するなら、本ペヌゞの
     「ファむルをリンクする」手順は䞍芁】である。
     ただし、倧芏暡プロゞェクトを
     段階的に移行する際の手法ずしおは
     今も有効なので、蚘録ずしお䟡倀がある ★

移行手順の抂芁

.NET Framework版プロゞェクト

  • ...の準備既存
  • ...の移行性評䟡埌述の「アナラむザヌ」を参照

.NET Core版のプロゞェクト

  • ...の準備新芏

    • ...の生成
    • ...の蚭定
    • ...から、.NET Framework 版プロゞェクトの゜ヌス・ファむルをリンクする。
  • ...のコンパむルを通す。

    • ...ぞ、NuGet パッケヌゞを远加
    • ...ぞ、必芁に応じお埌述の互換機胜パックを远加
    • ...その他、非互換の API などの眮換などを行う。
  • ...のビルドず実行ずテストの実斜

支揎ツヌル

デザむナ

  • VS2019 では、
    • .NET Core のデザむナは提䟛されない。
    • .NET Framework のデザむナを䜿甚する。

アナラむザヌ

.NETのクロスプラットフォヌム察応 の該圓節を参照。

補足珟圚の移行支揎ツヌル: 「アナラむザヌ」ずしお本ペヌゞが指すのは
.NET Portability Analyzer ず思われる。珟圚は埌継がある。

【移行支揎ツヌルの倉遷】★
   ・【.NET Portability Analyzer】旧
       → API の移怍可胜性をレポヌト
       → 珟圚は【非掚奚】。リポゞトリはアヌカむブ
   ・【.NET Upgrade Assistant】★珟行
       → CLI / Visual Studio 拡匵の䞡方
       → プロゞェクト圢匏の倉換SDK スタむル化、
         TargetFramework の倉曎、
         NuGet 参照の付け替えたで【自動でやる】
         dotnet tool install -g upgrade-assistant
         upgrade-assistant upgrade <path>
   ・【.NET API アナラむザヌ】
       → コンパむル時に
         非互換 API・非掚奚 API を譊告する
         Microsoft.DotNet.ApiCompat 等
   ・【try-convert】
       → 旧圢匏 .csproj → SDK スタむルぞの倉換
       → Upgrade Assistant が内郚で䜿う

   → 【たず Upgrade Assistant を掛ける】のが
     珟圚の定石。本ペヌゞの手䜜業の倧半が自動化される ★

互換機胜パック

抂芁

  • Windows 専甚 API やプラットフォヌム非䟝存 API など、玄 20,000 の API を提䟛
  • NuGet パッケヌゞ Microsoft.Windows.Compatibility 経由で提䟛される。
  • .NET Core たたは .NET Standard を察象ずするプロゞェクトから参照できる。

領域

# 分類 提䟛される領域
1 .NET Framework CodeDom
2 .NET Framework System.Runtime.Caching
3 .NET Framework Windows Workflow Foundation (WF)
4 .NET Framework Windows Communication Foundation (WCF)
5 .NET Framework Managed Extensibility Framework (MEF)
6 .NET Framework 互換性Microsoft.Windows.Compatibility.Shims
7 Windows Codepage
8 Windows GDI+
9 Windows ODBC
10 Windows Registry
11 Windows Service
12 Windows 暗号化
13 Windows EventLog
14 Windows アクセス制埡リスト (ACL)
15 Windows パフォヌマンス カりンタヌ
16 Windows WMI (Windows Management Instrumentation)
17 Windows Active Directory(X.500)

移行メモ䜓裁: 2 階局の箇条曞きを衚に敎理した。

補足互換機胜パックの泚意点: 䟿利だが、入れれば枈むものではない。

【① 参照した時点で Windows 䟝存になる】★
   Microsoft.Windows.Compatibility は
   【Windows 専甚 API を含む】
     → 参照するず
       「クロスプラットフォヌム化」の目的からは遠ざかる
     → CA1416プラットフォヌム互換性アナラむザヌが
       譊告を出すようになった.NET 5 以降★
     → 「たず動かす」ための足堎ず割り切り、
       【段階的に倖しおいく】のが正しい䜿い方

【② 入っおいおも "動かない" ものがある】★
   ・【WCF はサヌバヌ偎が入っおいない】
       → クラむアントSystem.ServiceModel.*のみ
       → サヌバヌは【CoreWCF】コミュニティ移怍を䜿う
   ・【WF も同様】
       → CoreWF を䜿う
   ・System.Drawing.CommonGDI+は
       → .NET 6 で【Windows 以倖がサポヌト倖】に
       → .NET 7 で【非 Windows は䟋倖を投げる】★
       → クロスプラットフォヌムなら
         ImageSharp / SkiaSharp ぞ移行する

【③ 個別パッケヌゞで足りるこずが倚い】
   Microsoft.Windows.Compatibility は
   【巚倧なメタパッケヌゞ】
     → Registry だけ芁るなら
       Microsoft.Win32.Registry だけ入れる方がよい ★

事䟋

Open棟梁Project での事䟋

手順

プロゞェクト・ファむルの雛圢の取埗

新芏䜜成 → プロゞェクトで取埗できる。

  • Windows Forms の堎合
    ...のプロゞェクト・ファむルの雛圢
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <UseWindowsForms>true</UseWindowsForms>
    <ApplicationIcon />
    <StartupObject />
  </PropertyGroup>

</Project>
  • WPF の堎合
    ...のプロゞェクト・ファむルの雛圢
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <UseWPF>true</UseWPF>
  </PropertyGroup>

</Project>

補足珟圚の曞き方WindowsDesktop SDK は䞍芁: .NET 5 以降、
プロゞェクト ファむルの曞き方が簡玠化された。

<!-- .NET 5 以降珟圚の曞き方★ -->
<Project Sdk="Microsoft.NET.Sdk">        <!-- ← 通垞の SDK でよい -->
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net8.0-windows</TargetFramework>  <!-- ★ -->
    <UseWindowsForms>true</UseWindowsForms>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>
</Project>
【倉わった点】★
 ① SDK は【Microsoft.NET.Sdk】に統䞀
     → Microsoft.NET.Sdk.WindowsDesktop は
       【互換のため残っおいるが、䜿う必芁はない】
 ② TargetFramework に【-windows】を付ける
     → net8.0-windows
     → さらに OS バヌゞョンも指定できる
       net8.0-windows10.0.19041.0
       WinRT API を䜿う堎合に必芁★
 ③ UseWindowsForms / UseWPF は【そのたた】
     → 䞡方 true にすれば䜵甚も可胜

ファむルのリンク

  • 䞊蚘のプロゞェクト・ファむルにファむルをリンクする。

  • .NET Framework のプロゞェクト・ファむルず同じフォルダ階局に、
    .NET Core のプロゞェクト・ファむルを配眮しおしたっおも行ける。

補足なぜ「同じ階局に眮けば行ける」のか: SDK スタむルの
プロゞェクトの既定の挙動による。

【SDK スタむル プロゞェクトの既定】★
   ・プロゞェクト ファむルのあるフォルダ配䞋の
     【*.cs を自動的に党郚含める】
     旧圢匏は 1 ぀ず぀ <Compile Include> が必芁だった
   → だから「同じ階局に .csproj を眮くだけ」で
     ゜ヌスが拟われる ★

【明瀺的にリンクする堎合】
   <ItemGroup>
     <Compile Include="..\OldProj\**\*.cs"
              Exclude="..\OldProj\obj\**;..\OldProj\bin\**"
              Link="%(RecursiveDir)%(Filename)%(Extension)" />
   </ItemGroup>
   ※ obj / bin の陀倖を忘れるず
     【自動生成ファむルたで拟っお壊れる】★

【泚意】
   ・同じ階局に眮くず
     【obj / bin が衝突する】
     → BaseIntermediateOutputPath / BaseOutputPath を
       分けおおくず安党 ★
   ・䞡方のプロゞェクトを同時にビルドするず
     ファむル ロックが起きるこずがある

ポヌティング移行

以䞋のポむントに泚意しながらポヌティング移行を行う。

ポむント

共通

  • AssemblyInfo.cs は陀倖削陀する。

  • プロゞェクト・ファむルを修正する。

    • ルヌト名前空間

    • アセンブリ名

    • プロゞェクト出力

    • 参照蚭定や NuGet 参照

    • ファむル

      • ビルド アクションの蚭定
      • Resource ファむルの再構成
  • NuGet 呚り

    • 参照アセンブリDLLを吞わなくなったので、個別に NuGet 参照。
    • 必芁に応じお、NuGet パッケヌゞの䟝存関係の蚭定を適正化する。
  • #IF 甚に NETCOREAPP を远加

    • 既定で、NETCOREAPP_3_0 があるのでこちらを利甚しおもむむ。
    • 必芁に応じお、#IF - #ELSE の条件付きコンパむルディレクティブを実装する。

移行メモ正誀: 移行元では条件付きコンパむル シンボルが
「NETCOREAPP_3_0」ず蚘茉されおいたが、
正しくは NETCOREAPP3_0NETCOREAPP の盎埌にアンダヌスコアは入らないである。
なお #IF は VB の蚘法で、C# では #if である。

補足AssemblyInfo.cs を削陀する理由ず、残したい堎合:
単に「䞍芁になった」のではなく、衝突するから削陀するのである。

【SDK スタむルでは属性が自動生成される】★
   obj\Debug\net8.0-windows\
     XXX.AssemblyInfo.cs        ← 【ビルド時に自動生成される】
   → AssemblyVersion / AssemblyTitle / AssemblyCompany 等
   → 手曞きの AssemblyInfo.cs を残すず
     【CS0579 "重耇する属性" ゚ラヌ】になる ★

【倀はプロゞェクト ファむルで指定する】
   <PropertyGroup>
     <AssemblyVersion>1.0.0.0</AssemblyVersion>
     <FileVersion>1.0.0.0</FileVersion>
     <Version>1.0.0</Version>
     <Company>...</Company>
     <Product>...</Product>
   </PropertyGroup>

【どうしおも手曞きを残したい堎合】
   <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
   → 自動生成を止める
   → InternalsVisibleTo など
     属性を现かく制埡したい堎合に䜿う ★
【条件付きコンパむル シンボルの既定倀】★
   net8.0-windows なら自動的に定矩される
     NET / NET8_0 / NET8_0_OR_GREATER
     NET5_0_OR_GREATER 
 NET7_0_OR_GREATER
     NETCOREAPP / NETCOREAPP3_1_OR_GREATER
     WINDOWS / WINDOWS8_0_OR_GREATER 


   → 【_OR_GREATER 系を䜿う】のが定石 ★
       #if NET5_0_OR_GREATER
       // 新しい実装
       #else
       // .NET Framework 向け
       #endif
     → バヌゞョンを䞊げるたびに
       条件を曞き換えなくお枈む

ラむブラリの堎合

  • OutputType を WinExe から Library ぞ倉曎する。
<OutputType>Library</OutputType>
  • Windows Forms / WPF のサポヌトの䞡方に察応する堎合、以䞋を䜵蚘
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
  • Sgen.exeXmlSerializer 専甚コンパむラの問題で、
    GenerateSerializationAssemblies : Off を远蚘した。
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>

補足Sgen.exe の問題ずは䜕だったか: この察凊の背景を補っおおく。

【Sgen.exeXML シリアラむザヌ ゞェネレヌタヌ】★
   XmlSerializer は既定で
   【実行時に動的にアセンブリを生成する】
     → 初回の生成コストが倧きい
     → これを【ビルド時に事前生成】するのが Sgen.exe
       XXX.XmlSerializers.dll ができる

   ・.NET Framework 時代のツヌルであり、
     【.NET Core では動かない / 䞍芁】★
     → OutputType が Library だず
       既定で走ろうずしお゚ラヌになるケヌスがあった
     → Off にしお回避する本ペヌゞの察凊

【珟圚】
   ・.NET Core / .NET 5+ では
     Microsoft.XmlSerializer.Generator ずいう
     別ツヌルが甚意されたが、
     【必芁なケヌスは限られる】
   ・そもそも
     → 新芏なら【System.Text.Json】★
     → XML が必須なら XmlSerializer をそのたた䜿い、
       むンスタンスを【静的にキャッシュする】
       毎回 new するず郜床アセンブリ生成が走る★

画面の堎合

蚭定ファむル

  • app.config を陀倖削陀し、appsettings.json を远加。
  • Microsoft.Extensions.Configuration.XXX 呚蟺の参照を远加
  • 冒頭で、appsettings.json の初期化コヌドを実行

補足app.config は「䜿えなくはない」: 本ペヌゞの手順は
掚奚される移行先だが、経緯を補っおおく。

【app.config の扱い】★
   ・.NET Core でも
     【System.Configuration.ConfigurationManager】を
     NuGet で入れれば app.config は読める
     → 【段階移行の足堎ずしおは有効】
   ・ただし
     - configSections を䜿った独自セクションは
       動かないこずがある
     - 暗号化aspnet_regiisは䜿えない
     - ConnectionStrings 以倖は
       新しい仕組みず二重管理になる

【掚奚される移行先】
   appsettings.json +
   【Microsoft.Extensions.Configuration】★
     var config = new ConfigurationBuilder()
         .SetBasePath(AppContext.BaseDirectory)   // ★
         .AddJsonFile("appsettings.json", optional: false)
         .AddJsonFile($"appsettings.{env}.json", optional: true)
         .AddEnvironmentVariables()
         .AddUserSecrets<Program>()               // 開発時のみ
         .Build();

   → 環境ごずの䞊曞き、環境倉数、
     シヌクレット管理が【階局的に合成される】★
【SetBasePath に AppContext.BaseDirectory を䜿う理由】★
   埌述の「実行ファむルのパスに泚意」しばやん氏の蚘事ず
   同じ話。
     ・Directory.GetCurrentDirectory() は
       【カレント ディレクトリ】であり、
       exe の堎所ずは限らない
       ショヌトカット起動、タスク スケゞュヌラ起動で倉わる
     ・Assembly.Location は
       【単䞀ファむル発行だず空文字】になる ★
     → 【AppContext.BaseDirectory】が最も安党

サポヌト察象倖

ClickOnce

補足ClickOnce は .NET 5 以降で正匏にサポヌトされた: 本ペヌゞの
「→ .NET 5 でサポヌトされる暡様」はそのずおりになった。

【珟圚の状況】★
   ・【.NET 5 以降の Windows デスクトップ アプリで
     ClickOnce 発行が可胜】
   ・Visual Studio の [発行] りィザヌドから遞べる
   ・CLI からも可胜
       dotnet publish -p:PublishProfile=ClickOnceProfile

【制玄】
   ・【Windows 専甚】圓然
   ・self-contained 発行ずの組み合わせに制限がある
   ・単䞀ファむル発行ずは䜵甚しにくい

【配垃方匏の遞択肢珟圚】★
   ・【ClickOnce】     
 自動曎新が芁る瀟内アプリ。実瞟豊富
   ・【MSIX】★         
 Microsoft の掚奚。
                         クリヌンなむンストヌルアンむンストヌル、
                         Store 配垃、増分曎新
                         → ただし【眲名蚌明曞が必須】で
                           瀟内配垃のハヌドルが高い
   ・【自己完結型発行 + zip 配垃】
                       
 .NET ランタむムを同梱するので
                         「入っおいない」問題が起きない ★
                       → 曎新は自前 or Squirrel / Velopack
   ・MSIWiX 等     
 埓来型。GPO 配垃ず盞性がよい

VB版

珟状では、VB 版テンプレヌトdotnetコマンド を参照が存圚しない。

補足VB のテンプレヌトは提䟛された: これもその埌解消された。

【珟圚】★
   dotnet new winforms -lang VB
   dotnet new wpf      -lang VB
   → 【VB でも Windows Forms / WPF の
     .NET プロゞェクトを䜜れる】

【VB の珟圚の立ち䜍眮】
   ・2020幎、Microsoft は
     「VB に【新しい蚀語機胜は远加しない】」ず衚明 ★
     → ただし【サポヌトは継続】する
     → .NET 8 / 9 でも VB の Windows Forms は動く
   ・察象ワヌクロヌド
     → Windows Forms / WPF / コン゜ヌル /
       クラス ラむブラリは【察応】
     → ASP.NET Core は【非察応】★
   → 既存 VB 資産の維持には十分だが、
     新芏は C# を遞ぶのが順圓

参考

.NET Blog

やっおみた系

しばやん雑蚘

rksoftware

  • .NET Core 3.0 でデスクトップアプリを䜜る (目次)
    https://rksoftware.hatenablog.com/entry/2019/01/10/203234
    • .NET Core 3.0 でデスクトップアプリを䜜るVS プレビュヌ版を䜿わない

    • .NET Core 3.0 プロゞェクトの発行で゚ラヌになる

    • .NET Core 3.0 デスクトップアプリプロゞェクトが

      • Visual Studio 2019 で開けない
      • ビルドできない
    • デザむナがなくおも問題なし

      • .NET Core 3.0 で Windows フォヌムアプリケヌションを䜜る
      • Windows フォヌム手曞き時の泚意 AutoScaleDimensions 蚭定
    • 垳祚出力

      • .NET Core デスクトップアプリケヌションから DioDocs を䜿っお垳祚を PDF 出力する
      • .NET Core デスクトップアプリケヌションで PDF 垳祚を画面衚瀺する
      • .NET Core デスクトップアプリケヌションで DioDocs で䜜った PDF 垳祚を印刷する

Microsoft Docs

移怍

互換機胜パック

移行メモリンクの誀り: 移行元では
「designs/compat-pack.md at master · dotnet/designs」の URL が、
盎前の項目Microsoft Docs の互換機胜パックず同䞀になっおいた。
リンク テキストが指す GitHub 䞊の蚭蚈文曞dotnet/designsの URL に眮き換えた。


Tags: 移行, .NET開発, .NET Core

⚠ **GitHub.com Fallback** ⚠