LoginSignup
3
1

More than 3 years have passed since last update.

作業ディレクトリと実行ディレクトリという罠 - 相対パスに気をつけろ!

Last updated at Posted at 2020-10-28

まえがき

実行ファイル(.exe)と同じフォルダや相対パス上に設定ファイルなどを置くことがあると思います。
この際に、作業ディレクトリ(カレントディレクトリ)と実行ディレクトリの違いを理解していないと、.exeファイルをどこから呼び出すかによって、上記の設定ファイルなどのパスが見つからずファイルが開けないという事態を招きます。

.dllの場合どうなるかについては本記事では扱っていませんので、参考サイト等をご確認ください。

先に結論

「まえがき」に書いたシーンでは、「実験用ソースコード」のExecutionPathTestメソッド内を参考に設定ファイルを開くようにすれば、基本的にはOKのはず。
(※ドライブ直下とかファイルサーバ上とかは未テストなので確証はない。。。)

実験結果ログ(コマンドプロンプト)

実験用ソースコード」を使って、実験してみました。

setting.txtが実行ファイルと同じ階層のフォルダ直下に置いてあるケース。)

実行ファイルのディレクトリで実行した場合

C:\SvnLocal\trunk\DirTest>CurDirExeDirTest.exe
--- relative path ---
[1]setting.txt
[1-check]Found.
[2]C:\SvnLocal\trunk\DirTest\setting.txt
[2-check]Found.

--- curent directory ---
[3]C:\SvnLocal\trunk\DirTest
[3-check]Found.

--- executing directory or file ---
[4]C:\SvnLocal\trunk\DirTest\CurDirExeDirTest.exe
[5]C:\SvnLocal\trunk\DirTest
[6]C:\SvnLocal\trunk\DirTest\setting.txt
[6-check]Found.
実行ファイルとは異なるディレクトリで実行した場合

C:\SvnLocal\trunk\DirTest>cd ..

C:\SvnLocal\trunk>DirTest\CurDirExeDirTest.exe
--- relative path ---
[1]setting.txt
[1-check]Cannot found.
[2]C:\SvnLocal\trunk\setting.txt
[2-check]Cannot found.

--- curent directory ---
[3]C:\SvnLocal\trunk
[3-check]Cannot found.

--- executing directory or file ---
[4]C:\SvnLocal\trunk\DirTest\CurDirExeDirTest.exe
[5]C:\SvnLocal\trunk\DirTest
[6]C:\SvnLocal\trunk\DirTest\setting.txt
[6-check]Found.

結果:[6]のやりかたのみファイルを見つけられます。

実験用ソースコード

CurDirExeDirTest.cs

using System;
using System.IO;

class CurDirExeDirTest
{
    static readonly string SettingFileName = "setting.txt";

    [STAThread]
    static void Main(string[] args)
    {
        RelativePathTest();
        CurrentPathTest();
        ExecutionPathTest();
    }

    static void RelativePathTest()
    {
        Console.WriteLine("--- relative path ---");

        Console.Write("[1]");
        Console.WriteLine(SettingFileName);

        if ( File.Exists(SettingFileName) ) {
            Console.WriteLine("[1-check]Found.");
        }
        else {
            Console.WriteLine("[1-check]Cannot found.");
        }

        string settingFilePathByRelPath = Path.GetFullPath(SettingFileName);
        Console.Write("[2]");
        Console.WriteLine(settingFilePathByRelPath);

        if ( File.Exists(settingFilePathByRelPath) ) {
            Console.WriteLine("[2-check]Found.");
        }
        else {
            Console.WriteLine("[2-check]Cannot found.");
        }

        Console.WriteLine("");
    }

    static void CurrentPathTest()
    {
        Console.WriteLine("--- curent directory ---");

        string curDir = Environment.CurrentDirectory; // Directory.GetCurrentDirectory() でも同様
        Console.Write("[3]");
        Console.WriteLine(curDir);

        string settingFilePathByCurDir = Path.Combine(curDir, SettingFileName);
        if ( File.Exists(settingFilePathByCurDir) ) {
            Console.WriteLine("[3-check]Found.");
        }
        else {
            Console.WriteLine("[3-check]Cannot found.");
        }

        Console.WriteLine("");
    }

    static void ExecutionPathTest()
    {
        Console.WriteLine("--- executing directory or file ---");

        string assemblyFullPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
        Console.Write("[4]");
        Console.WriteLine(assemblyFullPath);

        string execDirName = Path.GetDirectoryName(assemblyFullPath);
        Console.Write("[5]");
        Console.WriteLine(execDirName);

        string settingFilePathByExeDir = Path.Combine(execDirName, SettingFileName);
        Console.Write("[6]");
        Console.WriteLine(settingFilePathByExeDir);

        if ( File.Exists(settingFilePathByExeDir) ) {
            Console.WriteLine("[6-check]Found.");
        }
        else {
            Console.WriteLine("[6-check]Cannot found.");
        }

        Console.WriteLine("");
    }
}

参考サイト

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1