実行中のアプリの現在のディレクトリが変更される原因は何ですか?
-
03-07-2019 - |
質問
次のコードを含むC#アプリケーションがあります:
string file = "relativePath.txt";
//Time elapses...
string contents = File.ReadAllText(file);
これはほとんどの場合、正常に機能します。ファイルは、アプリが起動されたディレクトリに関連して読み込まれます。ただし、テストでは、約5時間放置すると、アプリが" C:\ Documents and Settings \ Adminstrator \ relativePath.txt"を示す FileNotFoundException
をスローすることがわかりました。見つかりませんでした。ただし、ファイルを読み取るアクションがすぐに実行される場合、ファイルは適切な場所から読み取られます。この場所を" C:\ foo \ relativePath.txt"
何が得られますか?そして、最善の修正は何ですか? Assembly.GetEntryAssembly()。Location
?
解決
ファイルが常に実行可能アセンブリに対して相対的なパスにある場合は、はい、Assembly.Locationを使用します。必要に応じて、Assembly.GetEntryAssemblyではなく、ほとんどの場合Assembly.GetExecutingAssemblyを使用します。これは、DLLからファイルにアクセスしている場合、パスはDLLパスに相対的であることを意味します。
他のヒント
パスを変更できる不気味な場所の1つは、OpenFileDialogです。ユーザーがフォルダ間を移動すると、アプリケーションディレクトリが現在表示されているディレクトリに変更されます。ユーザーが別のディレクトリでダイアログを閉じると、そのディレクトリでスタックします。
RestoreDirectory 。ダイアログでパスをリセットします。しかし、デフォルトは「false」だと思います。
レッスンは相対パスに依存するべきではなく、エラーが発生しやすいと思います。現在のディレクトリは、ファイルダイアログなどの実行中のプロセスのさまざまなものによって変更できます(ただし、変更を防止するプロパティがあります)ので、 Application.StartupPathなどの既知のパス(Visual Studioから起動する場合は注意してください)またはその他の既知のパスから固定パスを生成する相対パス。
相対パスを使用すると、プロジェクトのまったく関係のない部分を変更すると別の部分が失敗する可能性があるため、コードの保守が難しくなります。
System.Environmentには、 SpecialFolder 列挙型。標準の相対パスを取得するのに役立ちます。
少なくともこの方法では、パスは内部的に取得されて返されます。したがって、システムが何らかの方法でパスを変更している場合、コードがそれを処理することを願っています。
次のような処理を行う場合
> cd c:\ folder 1
c:\ folder 1> ../folder 2 / theApplication.exe
アプリケーションの現在の作業ディレクトリはc:\ folder 1です。
ここにプログラム例があります
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace CWD {
class Program {
static void Main (string[] args) {
Console.WriteLine(Application.StartupPath);
}
}
}
これをvisualstudioでビルドし、debug / binディレクトリでコマンドプロンプトを開いて実行します
bin / debug> CWD.exe
それから
bin / debug> cd ../../ > bin / debug / CWD.exe
起動パスに違いが見られます。
元の質問に関連して... "約5時間放置すると、アプリはFileNotFoundExceptionをスローします"
アプリケーションが実行されたら、そのファイルを移動するか、予想される場所からファイルを削除するだけでこのエラーが発生します。
greg
openfiledialogを使用し、記憶パスプロパティ(正確な名前がわからない)がtrueの場合、現在のディレクトリが変更されると思います。