dotnet publish -c Release -r win10-x64 /p:PublishSingleFile=true
で単一ファイルの発行を際に自分自身(Exe)のパスの取得ではまった話です。
Single Binary化
dotnet publishする際にPublishSingleFile
とRuntimeIdentifier
を指定することで単一のExeを出力できます。
publishコマンド 例
dotnet publish -c Release -r win10-x64 /p:PublishSingleFile=true
またはcsprojに以下の内容を記載してdotnet publish -c Release
しても同様です。
.csproj
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp3.0</TargetFramework> + <PublishSingleFile>true</PublishSingleFile> + <RuntimeIdentifier>win10-x64</RuntimeIdentifier> </PropertyGroup> </Project>
単一のExeといっても実際にはBuildフォルダ内のDLLとかを圧縮して保持し、Exe実行時に解凍してるだけっぽい?
実行してみる
publishしたExeを実行すると%USERPROFILE%/AppData/Local/Temp/.net/
以下にアプリケーション毎のフォルダが生成される。
試しに以下のコードのExeをPublishし、実行してみる。
Path 検証コード
using System; using System.Diagnostics; using System.IO; using System.Reflection; namespace PublishSingleFileSample { class Program { static void Main(string[] args) { Console.WriteLine($"GetCallingAssembly:\t{Path.GetDirectoryName(Assembly.GetCallingAssembly().Location)}"); Console.WriteLine($"GetEntryAssembly:\t{Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)}"); Console.WriteLine($"GetExecutingAssembly:\t{Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)}"); Console.WriteLine($"GetCurrentProcess:\t{Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)}"); Console.WriteLine($"GetCurrentDirectory:\t{Directory.GetCurrentDirectory()}"); Console.WriteLine($"CurrentDirectory:\t{Environment.CurrentDirectory}"); } } }
実行した結果は以下の通りです。
実行結果
PS C:\Users\piyosi> .\work\PublishSingleFileSample.exe GetCallingAssembly: C:\Users\piyosi\AppData\Local\Temp\.net\PublishSingleFileSample\32lboto0.c0l GetEntryAssembly: C:\Users\piyosi\AppData\Local\Temp\.net\PublishSingleFileSample\32lboto0.c0l GetExecutingAssembly: C:\Users\piyosi\AppData\Local\Temp\.net\PublishSingleFileSample\32lboto0.c0l GetCurrentProcess: C:\Users\piyosi\work GetCurrentDirectory: C:\Users\piyosi CurrentDirectory: C:\Users\piyosi
Assembly系で取得したパスは展開された先のパスを示しています。 Processから取得したパスは生成したExeのパスを示していますね。
上記の差によりPublishSingleFile
を指定する前後でアプリの挙動が変わってしまって、大変困った思いをしました。。
以上です。