进程的当前目录
Windows Api中有大量的函数在调用的时候,需要传递路径。比如创建文件,创建目录,删除目录,删除文件等等。创建文件的APICreateFile
做比喻,如果我们要创建的文件路径不是全路径,那么windows在创建的时候,首先会获取到进程的当前目录,然后用这个目录拼接成一个全路径创建文件。
一般情况下通过双击启动的exe进程,进程的当前目录就是exe文件所在的目录。VS调试环境下,进程的当前目录不是exe文件所在路径,而是项目文件所在的路径。拿C++控制台程序来说,后缀为vcxproj的项目文件在那里,进程的目录就是那里。
通过GetCurrentDirectory
可以获取到进程的当前目录。
#include <iostream>
#include <Windows.h>
int main()
{
// 定义缓冲区大小
WCHAR currentDir[MAX_PATH];
// 获取当前工作目录
DWORD length = GetCurrentDirectory(MAX_PATH, currentDir);
// 输出当前工作目录
std::wcout << L"Current Directory: " << currentDir << std::endl;
return 0;
}
我的项目文件在D:\project\ConsoleApp1\ConsoleApp
目录下,当我用VS调试项目之后,输出的进程的当前目录为D:\project\ConsoleApp1\ConsoleApp
,下面是运行结果。
但是当我直接在进程进程管理器中打开exe文件之后,输出的结果就是当前exe文件所在的目录,参考下图运行结果。
使用相对路径创建文件
接下来我们来演示一下,创建文件CreateFile
的时候,不传全路径,这个文件会创建在哪里。上面已经提到:如果我们要创建的文件路径不是全路径,那么windows在创建的时候,首先会获取到进程的当前目录,然后用这个目录拼接成一个全路径创建文件。我们执行下面代码,并且我们用VS调试。
#include <iostream>
#include <Windows.h>
int main()
{
// 定义缓冲区大小
WCHAR currentDir[MAX_PATH];
// 获取当前工作目录
DWORD length = GetCurrentDirectory(MAX_PATH, currentDir);
// 输出当前工作目录
std::wcout << L"Current Directory: " << currentDir << std::endl;
// 定义文件路径
LPCWSTR filePath = L"file.txt";
// 创建或打开文件
HANDLE hFile = CreateFile(
filePath, // 文件名
GENERIC_READ | GENERIC_WRITE, // 访问模式
0, // 共享模式
NULL, // 安全属性
CREATE_ALWAYS, // 创建选项
FILE_ATTRIBUTE_NORMAL, // 文件属性
NULL // 模板文件句柄
);
system("pause");
return 0;
}
下面是运行结果图,可以很清晰的看到,在当前项目的同级目录下,创建了一个file.txt文件。
如果我们把文件的改成下面的路径,那么在项目文件的上一级目录你会发现创建了一个file.txt文件,大家可以自行实验。-
LPCWSTR filePath = L"..\file.txt";
接下来,我们在进程管理器中直接双击exe启动,就会发现在当前exe的同级目录下创建了一个file.txt文件。运行效果如下:
修改进程的当前目录
进程的当前目录,并不是一成不变的,我们可以在调用ShellExecute的时候,手动设置进程的当前目录。也可以调用SetCurrentDirectory
设置进程的当前目录。下面的代码中:首先我们获取到进程的当前目录并输出,然后修改目录为D:\\,随后输出修改后的目录,并且创建一个file.txt。调试之后,我们会发现在D盘下创建了一个file.txt的文件。这就是进程的当前目录的作用
#include <iostream>
#include <Windows.h>
int main()
{
// 定义缓冲区大小
WCHAR currentDir[MAX_PATH];
// 获取当前工作目录
DWORD length = GetCurrentDirectory(MAX_PATH, currentDir);
// 输出当前工作目录
std::wcout << L"Current Directory: " << currentDir << std::endl;
// 设置新的工作目录
LPCWSTR newDir = L"D:\\";
SetCurrentDirectory(newDir);
// 再次获取并输出新的工作目录
length = GetCurrentDirectory(MAX_PATH, currentDir);
std::wcout << L"New Current Directory: " << currentDir << std::endl;
// 定义文件路径
LPCWSTR filePath = L"file.txt";
// 创建或打开文件
HANDLE hFile = CreateFile(
filePath, // 文件名
GENERIC_READ | GENERIC_WRITE, // 访问模式
0, // 共享模式
NULL, // 安全属性
CREATE_ALWAYS, // 创建选项
FILE_ATTRIBUTE_NORMAL, // 文件属性
NULL // 模板文件句柄
);
system("pause");
return 0;
}
