Windows编程----进程的当前目录

进程的当前目录

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;
}
相关推荐
Dream it possible!3 小时前
LeetCode 热题 100_字符串解码(71_394_中等_C++)(栈)
c++·算法·leetcode
My Li.4 小时前
c++的介绍
开发语言·c++
waicsdn_haha5 小时前
Postman v11 安装与API测试入门教程(Windows平台)
人工智能·windows·测试工具·mysql·postman·dbeaver·rest
-凌凌漆-5 小时前
【C#】async与await介绍
开发语言·c#
去看日出5 小时前
RabbitMQ消息队列中间件安装部署教程(Windows)-2025最新版详细图文教程(附所需安装包)
java·windows·中间件·消息队列·rabbitmq
君莫愁。5 小时前
【Unity】搭建基于字典(Dictionary)和泛型列表(List)的音频系统
数据结构·unity·c#·游戏引擎·音频
邪恶的贝利亚6 小时前
C++之序列容器(vector,list,dueqe)
开发语言·c++
原来是猿6 小时前
蓝桥备赛(13)- 链表和 list(上)
开发语言·数据结构·c++·算法·链表·list
成功助力英语中国话6 小时前
SDK编程,MFC编程,WTL编程之间的关系
c++·mfc
计算机学姐6 小时前
基于Asp.net的教学管理系统
vue.js·windows·后端·sqlserver·c#·asp.net·visual studio