C#

.Net CoreアプリをLinuxで実行するときの相対パス問題

Linux(CentOS)で実行するアプリを.Net Coreを用いてWindowsで開発しています。

実行ファイルがあるフォルダ内のファイルを操作したかったので

 ./hoge.txt のように相対パスでファイルをしていました。

Linuxにて動作確認すると動かなったので、検証と対策をまとめました。

.Net CoreをLinux上で実行する方法: こちら

検証

GetFullPath(String) で実行ファイルがある場所の絶対パスを取得したいと思います。

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("path: " + Path.GetFullPath("." + Path.DirectorySeparatorChar));
    }
}

Path.DirectorySeparatorCharは、プラットフォームに合わせたフォルダ区切り文字を取得します。

Windowsで実行

(略)\(project name)\(project name)\bin\Debug\netcoreapp3.1\
実行ファイルがあるフォルダの絶対パスを取得できました!

Linuxで検証

実行ファイルの場所は/a/b/c/ConsoleApp1です。

パターン1

$ /a/b/c/ConsoleApp1
path: /

パターン2

$ cd /a/b/
$ /a/b/c/ConsoleApp1
path: /a/b/

パターン3

$ cd /a/b/c/
$ /a/b/c/ConsoleApp1
path: /a/b/c/
自分がいるディレクトリを取得している?

解決策

相対パスはあきらめて絶対パスを使用します。

具体的にはSystem.AppDomain.CurrentDomain.BaseDirectoryを使います。

実行ファイルのフォルダの絶対パスが取得できます。

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory);
    }
}

検証

パターン1

$ /a/b/c/ConsoleApp1
path: /a/b/c/

パターン2

$ cd /a/b/
$ /a/b/c/ConsoleApp1
path: /a/b/c/

パターン3

$ cd /a/b/c/
$ /a/b/c/ConsoleApp1
path: /a/b/c/
今回は問題なく実行ファイルがあるフォルダの絶対パスを取得できました!

おまけ: ひとつ上の階層を取得する方法

 ../ というやつです。

class Program
{
    static void Main(string[] args)
    {
        var baseDir = AppDomain.CurrentDomain.BaseDirectory;
        var baseDirParent = Directory.GetParent(Path.GetDirectoryName(baseDir)).ToString();
        Console.WriteLine("path: " + baseDirParent);
    }
}

実行

$ /a/b/c/ConsoleApp1
path: /a/b/