まえがき
実行ファイル(.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("");
}
}