107.4K Views
August 26, 22
スライド概要
「.NET 6 移行祭り! C# Tokyo イベント」で発表したスライドです。
https://csharp-tokyo.connpass.com/event/254206/
.NET Framewarkから.NET 6への移行で やった細かいこと(C++/CLIもあるよ) 2022/8/26 須藤(suusanex)
自己紹介 ID:suusanex( connpass・Twitter・GitHub共通) 名前:須藤圭太 サイエンスパーク株式会社という独立系ソフトウェアベンダーに所属 https://sciencepark.co.jp 4年ほど受託開発で、上流から下流まで全部を回す ここ8年ほどは、自社製品開発も担当 Windowsアプリ開発のネタが多い 勉強会もやってます。 https://sciencepark.connpass.com
.NET 6への移行 .NET Frameworkの既存コードを、.NET 6に移行しよう! メニュー1つでコンバート、とはいかない 細かくやることが色々あったので、細かいことを紹介します プロジェクトの置き換え編 ビルド編 発行編
プロジェクトの置き換え編 プロジェクトの作り直し プロジェクトの編集 プロジェクト設定の移植 AssemblyInfo.csに注意 C++/CLIプロジェクト
プロジェクトの作り直し C#はプロジェクトの形式が変わるので、プロジェクトファイルを作り直し Frameworkと違って、プロジェクト=フォルダ。 フォルダ内のファイルは、全てプロジェクトに入る 新プロジェクトは、デフォルト値なら書かず、必要なものだけ書くという作り フォルダの状態 エディタ無しでも、プロジェクトファイルを読み書きしやすい プロジェクトファイル プロジェクトに含まれるファイル 自動
プロジェクトの編集 プロジェクトの編集は、従来は右クリックして「プロパティ」 その機能は今も有るが、テキストファイルとして編集する方が便利 プロジェクトをダブルクリックすると、テキストで開く テキストとプロパティ画面
プロジェクト設定の移植 旧プロジェクトから、NuGetや参照などプロジェクト特有のものだけを書き写 す 記法が分からない物は、一度プロパティ画面のGUIで設定して、どのようなテ キストになったか見ると良い良い NuGetのライブラリは、旧プロジェクトとXMLの記法が同じなので、旧プロ ジェクトをテキストエディタで開けばまとめてコピペできる 旧プロジェクトがpackages.config型の場合は、Reference型に変換しておくと良い <ItemGroup> <PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.16" /> <PackageReference Include="Microsoft.Toolkit.Mvvm" Version="7.0.2" /> <PackageReference Include="NLog.Extensions.Logging" Version="1.7.4" /> </ItemGroup>
AssemblyInfo.csに注意 そのまま組み込むと、二重定義になる .NET 6では、プロジェクトの情報から自動生成するのがデフォルト デフォルトに合わせるなら、AssemblyInfo.csを削除すればOK ただし、バージョンの記載を1ファイルにまとめるなどの工夫ができない そういう工夫をする場合は、プロジェクトに次の設定を入れて自動生成を止め ると良い <PropertyGroup> <GenerateAssemblyInfo>false</GenerateAssemblyInfo> </PropertyGroup>
C++/CLIプロジェクト C++のプロジェクトは旧型のまま 一部だけ書き換えてそのまま使うこともできるが、作り直した方が確実 書き換える場合のポイント(作り直して比較したもの) <TargetFrameworkVersion>v4.8 → <TargetFramework>net6.0 <Keyword>ManagedCProj → <Keyword>NetCoreCProj <VCProjectVersion>16.0 → <VCProjectVersion>17.0 <CLRSupport>true → <CLRSupport>NetCore 言語仕様が変わっていないので、C#とC++の間の薄いアダプタとして使ってい るなら、プロジェクトを変更するだけで問題なく動く
ビルド編 型(ライブラリ)が見つからない 名前空間が変わっている 一部はメソッドの定義自体が違う
型(ライブラリ)が見つからない 型が見つからなくてコンパイルが通らない、というのが大量に出る ライブラリ廃止か?!と慌てない .NETのライブラリは、標準ではなくNuGetでの選択取得になったものが多い MS Docsで適用対象が「.NET Platform Extensions」という表記になっているものは、 NuGetで取得 たいてい、型の名称そのままでNuGetに登録されている 例:Microsoft.Extensions.Hosting→ Microsoft Docs / NuGet MS Docs NuGet
名前空間が変わっている EntityFrameworkからEntityFramework Coreなど、クラスもメソッドも同じだ が名前空間が丸ごと違うというものがある global usingを使ってまとめて定義してしまうと今後が楽かもしれない using System.Data.Entity; ↓ 上の行を置換で全部削除して、1つだけ次の行を追加 global using Microsoft.EntityFrameworkCore;
一部はメソッドの定義自体が違う 例えばFile・DirectoryのSetAccessControlは staticメソッドからFileInfo,DirectoryInfoのメソッドに File.SetAccessControl(path, sec) ↓ var fi = new FileInfo(path); fi.SetAccessControl(sec); こうしたものは、1つずつ手で書き換えるしかない ほとんど無かったので、かなり例外的なケースだと思う
発行編 デスクトップアプリもビルドから発行へ 発行のコマンドライン実行 言語用のアセンブリ
デスクトップアプリもビルドから発行へ ビルドではなく発行を使う 確実に動くように依存モジュールなどをまとめてくれる 対象環境の指定、1ファイルにまとめるかなどの設定も可能 単独のプロセスとして起動するもの(つまり.exe)ごとに発行を行う 設定は対象プロジェクトごとに.pubxmlファイルで保存可能 設定が保存された.pubxml
発行のコマンドライン実行 GUIからの実行だと、対象プロジェクトが多い場合は面倒なので、コマンドが 良い C#のみなら、dotnet publishコマンドにソリューションファイルを渡せば一発 C++/CLI混在の場合は、dotnet publishコマンドではエラーが出て解決できない msbuildでpublishを呼ぶ必要がある 例:msbuild ソリューション名.sln /t:"プロジェクト名1:Restore;Rebuild;Publish";" プロジェクト名2:Restore;Rebuild;Publish; /p:Configuration=Release /p:Platform="Any CPU" /p:PublishProfile=Release /m 上の例は、発行の設定を各プロジェクトの.pubxmlファイルに設定しておいた場合
言語別のアセンブリ 発行すると、全言語用のresources.dllを入れたサブフォルダが作られる これらは使わないことの方が多く、邪魔 プロジェクトに SatelliteResourceLanguages を追加すれば良い <SatelliteResourceLanguages>ja-JP</SatelliteResourceLanguages> この設定は、「発行を行うプロジェクト」へ書く必要がある点に注意 MSのドキュメントでは「対象ライブラリを参照しているプロジェクト」と書いてあ るが、それだと効かない・・・
まとめ .NET Frameworkから.NET 6への移行は、ボタン一発というほど簡単ではない しかしポイントを押さえれば、1つずつの作業量はそう多くない 恐れず移行してみよう!