我正在维护一些用Delphi 6和C ++ Builder 4编写的旧应用程序。使用任一编译器编译的应用程序都会出现一种看似奇怪的现象。即使将.exe复制到其他目录,它们也会记住它们的默认工作目录。确定默认工作目录的机制是什么,以及如何知道默认工作目录不与.exe所在的目录相同的时间?
示例:假设我在MyApp.exe
中有源代码和已编译的32位PE C:\CppBuilder\Projects\MyApp
。然后我将MyApp.exe
和该文件夹中的其他文件复制到USB闪存盘F:\
。然后,在资源管理器中,我在MyApp.exe
中双击F:\
,然后应用程序启动。使用fopen打开的文件仍然从C:\CppBuilder\Projects\Myapp
打开。如果我重命名或删除文件夹C:\CppBuilder\Projects\Myapp
,则会按照我的预期从F:\
打开输入文件。文件打开对话框的默认文件夹也类似。
这有什么潜在的机制?
对不起,如果这是一个愚蠢的问题,但我真的找不到答案,我很尴尬地说,而且它一直让我发疯。我想确定关于文件的打开位置,而不使用文件名中的完整路径。再说一遍,我很抱歉。如果你知道答案,请帮助我。
答案 0 :(得分:5)
这是Windows 7及更高版本的一项功能,在对GetOpenFileName()
和GetSaveFileName()
的基础调用中。
具体而言,OPENFILENAME
结构的lpstrInitialDir
字段的文档说明:
lpstrInitialDir
类型:LPCTSTR初始目录。选择初始目录的算法在不同平台上有所不同。
Windows 7:
- 如果lpstrInitialDir与第一次应用程序使用“打开”或“另存为”对话框时传递的值相同,则用户最近选择的路径将用作初始目录。
- 否则,如果lpstrFile包含路径,则该路径是初始目录。
- 否则,如果lpstrInitialDir不为NULL,则指定初始目录。
- 如果lpstrInitialDir为NULL并且当前目录包含指定过滤器类型的任何文件,则初始目录是当前目录。
- 否则,初始目录是当前用户的个人文件目录。
- 否则,初始目录是Desktop文件夹。
醇>Windows 2000 / XP / Vista:
- 如果lpstrFile包含路径,则该路径是初始目录。
- 否则,lpstrInitialDir指定初始目录。
- 否则,如果应用程序过去使用了“打开”或“另存为”对话框,则会选择最近使用的路径作为初始目录。但是,如果应用程序未长时间运行,则会丢弃其保存的选定路径。
- 如果lpstrInitialDir为NULL并且当前目录包含指定过滤器类型的任何文件,则初始目录是当前目录。
- 否则,初始目录是当前用户的个人文件目录。
- 否则,初始目录是Desktop文件夹。
醇>
此外,调用公共文件对话框,除非设置OFN_NOCHANGEDIR
标志,will continuously change your application's working directory到该对话框中选择的最后一个 - 这是否选择/保存了文件。即使指定了OFN_NOCHANGEDIR
,工作目录仍会随着用户导航对话框而更改,但在对话框关闭时会恢复。这使得相对路径在多线程上下文中特别不安全。
fopen
将使用当前工作目录,因此如果应用程序先前已更改其工作目录或通过调用公共文件对话框将其更改,则这些调用将受到影响上方。
答案 1 :(得分:0)
Delphi和C ++构建器应用程序的工作目录与大多数其他应用程序相同。并且GetCurrentDir始终返回默认的exe目录的正确工作目录。但是在VCL打开/保存对话框中,如果您在使用上次使用的目录时未指定 InitialDir 属性。