0%

当前工作目录是可以变化的

2015年10月29日 10:15:57

问题描述

在做 mfc 项目的时候需要获取当前目录,当时直接调用了 GetCurrentDirectory() 使用。当时在 VS2010 中有三个项目,目录结构如下:

TrayOnly项目的目录结构

TrayOnly.exe 会调用启动 BasicConf.exe,而 BasicConf.exe 负责读写配置文件”conf\sample.conf”。

  • 在 VS2010 中将 BasicConf.vcxproj 设置为启动项目进行调试时,此配置文件须在 BasicConf 文件夹下,即”BasicConf\conf\sample.conf”;
  • 将 TrayOnly.vcxproj 设置为启动项目进行调试,通过 TrayOnly.exe 启动 BasicConf.exe 时,配置文件须在 TrayOnly 文件夹下,即”TrayOnly\conf\sample.conf”;
  • 而在 Debug 目录中手动启动 BasicConf.exe 时,配置文件须在 Debug 文件夹下,即”Debug\conf\sample.conf”。

这个就是一个凌乱的现象。

设置工作目录

右击项目-属性页-调试-工作目录,默认 $(ProjectDir) = 当前项目的目录 = 当前项目 .vcxproj 文件的所在目录

关于 IDE 中更多预定义变量的意义:Visual Studio中相对路径中的宏定义

工作目录和运行目录

工作目录,全称是当前工作目录(Current Working Directory)。一般来说,每个进程都有一个与之相关联的分级文件系统(hierarchical file system)下的目录,称之为该进程的当前工作目录。工作目录是一个环境变量,如果程序刚进入 main 入口处的时候,当前工作目录其实就是程序启动的目录,但是当前工作目录是可以通过程序进行设置或者随着 OpenFileDialogSaveFileDialog 等对象所确定的目录而改变。所以使用的时候要小心。工作目录主要影响程序中使用到的相对路径,比如说 file.open(../a.txt); 这个 a.txt 文件的具体位置是根据工作目录来判断的。

运行目录,也称执行目录、应用程序所在目录。该进程从中启动的目录,即程序文件自身所在的目录,是固定不变的。

所以,当前工作目录和程序所在的目录可以不同。

参考 What is the current directory in a batch file?

the current working directory (variable)

the full path to the batch file’s directory (static)

代码实现

获得当前工作目录:

获取当前工作目录 GetCurrentDirectory

设置当前工作目录 SetCurrentDirectory

C标准函数 char * getcwd(char * buf, size_t size) 获取当前工作目录绝对路径, 注意一点: size 要足够大!

获得.exe可执行文件路径:

Windows获取程序全路径的接口是:GetModuleFileName

1
2
3
4
5
6
7
8
//exe文件所在路径为:C:\Users\Debug\xxx.exe
char exeFullPath[MAX_PATH]={0};
GetModuleFileName(NULL,exeFullPath,MAX_PATH);//得到程序模块.exe全路径
//接下来把xxx.exe文件名去掉,有以下四种:
*strrchr( exeFullPath, '\\') = 0; //得到C:\Users\Debug
strrchr( exeFullPath, '\\')[0]= 0; //也是得到C:\Users\Debug
*(strrchr( exeFullPath, '\\')+1) = 0; //得到C:\UsersDebug\
strrchr( exeFullPath, '\\')[1]= 0; //也是得到C:\Users\Debug\

C Run-Time 库获取程序全路径接口是:_get_tpgmptr

1
2
3
4
5
6
7
8
9
10
11
12
//#include <stdio.h>
#include <cstdio>
//#include <stdlib.h> ////如果是C++代码,用cst**;如果是写C 请用st**.h
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
char* p = NULL;
_get_pgmptr(&p);
cout << p << endl;
}

参考自:运行的应用程序的当前工作目录和所在的目录的区别