C# 什么会导致正在执行的应用程序的当前目录发生更改?

C# 什么会导致正在执行的应用程序的当前目录发生更改?,c#,.net,filesystems,working-directory,C#,.net,Filesystems,Working Directory,我有一个C#应用程序,其中包括以下代码: string file = "relativePath.txt"; //Time elapses... string contents = File.ReadAllText(file); 大多数情况下,这很好用。该文件是相对于启动应用程序的目录读取的。但是,在测试中发现,如果单独使用约5小时,应用程序将抛出一个FileNotFoundException,说明找不到“C:\Documents and Settings\administrator\re

我有一个C#应用程序,其中包括以下代码:

string file = "relativePath.txt";

//Time elapses...

string contents = File.ReadAllText(file);
大多数情况下,这很好用。该文件是相对于启动应用程序的目录读取的。但是,在测试中发现,如果单独使用约5小时,应用程序将抛出一个
FileNotFoundException
,说明找不到“C:\Documents and Settings\administrator\relativePath.txt”。但是,如果立即运行读取文件的操作,则会从正确的位置读取文件,我们称之为“C:\foo\relativePath.txt”


有什么好处?那么,最好的解决办法是什么?根据
Assembly.GetEntryAssembly().Location

解析文件如果文件始终位于相对于可执行程序集的路径中,则是,使用Assembly.Location。我主要使用Assembly.GetExecutionGassembly(如果适用),而不是Assembly.GetEntryAssembly。这意味着,如果从DLL访问文件,则该路径将相对于DLL路径

我认为教训应该是不要依赖相对路径,它们容易出错。当前目录可以被运行过程中的任意数量的东西更改,如文件对话框(尽管有一个属性阻止它们更改),因此,除非使用相对路径从已知路径(如Application.StartupPath)生成固定路径,否则您永远无法确保相对路径始终指向何处(尽管从Visual Studio启动时要小心)或其他已知路径


使用相对路径将使您的代码难以维护,因为对项目中完全不相关的部分所做的更改可能会导致另一部分失败。

一个可以更改路径的可怕地方是OpenFileDialog。当用户在文件夹之间导航时,它会将您的应用程序目录更改为当前正在查看的目录。如果用户在另一个目录中关闭对话框,然后您将被困在该目录中


它有一个名为的属性,该属性导致对话框重置路径。但我认为默认值为“false”。

如果使用openfiledialog和记住路径属性(不确定确切名称)如果为true,则我认为它将更改当前目录。

在System.Environment中,您拥有枚举,这将帮助您获得标准的相对路径


至少通过这种方式,路径是在内部获取并返回给您的,因此,如果系统以某种方式更改路径,希望代码能够处理它。

如果您执行类似操作

>cd c:\文件夹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

我最初使用的是GetExecutionGassembly,但当我想到它时,我希望它是相对于可执行文件的路径的,因为路径将在该可执行文件的配置文件中定义。我也只会在路径不是绝对路径的情况下解决它…您可以使用path.Combine(Assembly[无论什么].Location,relativePath)。如果relativePath为绝对路径,则Path.Combine将返回该绝对路径并放弃第一个参数。不过,呃,我想您应该在将该位置的exe文件名传递给Path之前去掉它。Combine:)启动应用程序的目录将作为当前工作目录加载。这是完全允许改变的,如果代码的一个模糊部分这样做了,那么您将以上述行为结束。将相对路径转换为绝对路径。一种方法是将应用程序根路径存储在某个位置(例如作为安装的一部分),然后在整个代码中使用app\u root\u path\SomePath。