什么会导致正在执行的应用程序的当前目录发生更改?
我有一个 C# 应用程序,其中包含以下代码:
string file = "relativePath.txt";
//Time elapses...
string contents = File.ReadAllText(file);
大多数情况下,这都可以正常工作。 该文件是相对于应用程序启动的目录读取的。 但在测试中发现,如果放置约5小时,应用程序会抛出FileNotFoundException
,提示“C:\Documents and Settings\Adminstrator\relativePath.txt”无法被访问。成立。 如果立即运行读取文件的操作,则会从正确的位置读取文件,我们将其称为“C:\foo\relativePath.txt”,
结果是什么? 而且,最好的解决办法是什么? 是否针对 Assembly.GetEntryAssembly().Location
解析文件?
I have a C# application that includes the following code:
string file = "relativePath.txt";
//Time elapses...
string contents = File.ReadAllText(file);
This works fine, most of the time. The file is read relative to the directory that the app was started from. However, in testing, it has been found that if left alone for about 5 hours, the app will throw a FileNotFoundException
saying that "C:\Documents and Settings\Adminstrator\relativePath.txt" could not be found. If the action that reads the file is run right away though, the file is read from the proper location, which we'll call "C:\foo\relativePath.txt"
What gives? And, what is the best fix? Resolving the file against Assembly.GetEntryAssembly().Location
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
OpenFileDialog 是一个可以改变你的路径的令人毛骨悚然的地方。 当用户在文件夹之间导航时,它会将您的应用程序目录更改为当前正在查看的目录。 如果用户在不同的目录中关闭对话框,那么您将被困在该目录中。
它有一个名为 RestoreDirectory 的属性 这会导致对话框重置路径。 但我相信默认是“假”。
One spooky place that can change your path is the OpenFileDialog. As a user navigates between folders it's changing your application directory to the one currently being looked at. If the user closes the dialog in a different directory then you will be stuck in that directory.
It has a property called RestoreDirectory which causes the dialog to reset the path. But I believe the default is "false".
如果文件始终位于相对于可执行程序集的路径中,那么可以,使用 Assembly.Location。 如果适用,我主要使用 Assembly.GetExecutingAssembly,而不是 Assembly.GetEntryAssembly。 这意味着如果您从 DLL 访问文件,则该路径将相对于 DLL 路径。
If the file is always in a path relative to the executable assembly, then yes, use Assembly.Location. I mostly use Assembly.GetExecutingAssembly if applicable though instead of Assembly.GetEntryAssembly. This means that if you're accessing the file from a DLL, the path will be relative to the DLL path.
我认为教训应该是不要依赖相对路径,它们很容易出错。 当前目录可以被正在运行的进程中的任意数量的东西更改,例如文件对话框(尽管有一个属性可以防止它们更改它),因此您永远无法真正保证相对路径始终指向何处,除非您使用相对路径,从已知路径(如 Application.StartupPath)(但从 Visual Studio 启动时要小心)或其他已知路径生成固定路径。
使用相对路径将使您的代码难以维护,因为项目中完全不相关的部分的更改可能会导致另一部分失败。
I think the lesson should be don't rely on relative paths, they are prone to error. The current directory can be changed by any number of things in your running process like file dialogs (though there is a property to prevent them changing it), so you can never really guarantee where a relative path will lead at all times unless you use the relative path to generate a fixed one from a known path like Application.StartupPath (though beware when launching from Visual Studio) or some other known path.
Using relative paths will make your code difficult to maintain as a change in a totally unrelated part of your project could cause another part to fail.
在 System.Environment 中,您有 SpecialFolder 枚举,这将帮助您获得标准的相对路径。
至少通过这种方式,路径是在内部获取并交还给您的,因此希望如果系统以某种方式更改路径,代码将处理它。
In System.Environment, you have the SpecialFolder enum, that will help you get standard relative paths.
This way at least, the path is gotten internally and handed back to you, so hopefully if the system is changing the path somehow, the code will just handle it.
如果你做了类似的事情
> cd c:\文件夹 1
c:\文件夹 1 > ../folder 2/theApplication.exe
应用程序的当前工作目录为 c:\folder 1 。
这是一个示例程序
在 Visualstudio 中构建它,然后在 debug/bin 目录中打开命令提示符并执行
bin/debug > CWD.exe
然后执行
bin/debug > 光盘 ../../
> bin/debug/CWD.exe
您将看到启动路径的差异。
关于原来的问题......
“如果单独放置大约 5 小时,应用程序将引发 FileNotFoundException”
应用程序运行后,仅移动或从预期位置删除该文件就会导致此错误。
格雷格
if you do somehting like
> cd c:\folder 1
c:\folder 1 > ../folder 2/theApplication.exe
The current working directory of the applicaiton will be c:\folder 1 .
Here is an example program
Build this in visualstudio then open a command prompt in the debug/bin directory and do
bin/debug > CWD.exe
then do
bin/debug > cd ../../
> bin/debug/CWD.exe
you will see the difference in the startup path.
In relation to the original question...
"if left alone for about 5 hours, the app will throw a FileNotFoundException"
Once the application is running, only moving, or removing that file from the expected location should cause this error.
greg
如果您使用 openfiledialog 并且记住路径属性(不确定确切的名称)为 true,那么我认为它将更改您当前的目录。
If you use an openfiledialog and the remember path property (not sure about the exact name) is true then it will change your current directory I think.