调用 Win API 提供的文件选择器后,程序当前工作目录会被修改到最后一次所选文件的目录,因此此时再使用相对路径,可能就会导致不预期的结果。
解决方案:
#include <windows.h> // 提供 GetOpenFileName 等 API
#include <stdio.h> // 提供 printf
#include <tchar.h> // 提供 _wgetcwd
int main(int argc, char* argv[])
{
printf("argv[0]:\t%s\n", argv[0]);
// 输出:argv[0]: E:\TempProject\x64\Debug\CodeTest_Project.exe
// 说明 argv[0] 存储的是包含程序名的完全路径
wchar_t pwszOldPath[MAX_PATH] = { 0 };
_wgetcwd(pwszOldPath, MAX_PATH);
wprintf(L"_wgetcwd:\t%ls\n", pwszOldPath);
// 输出:_wgetcwd: E:\TempProject
// 此处调用 _wgetcwd 以获取程序当前工作目录的完整路径
// 由于使用 VS 进行调试,所以程序的工作目录在项目目录下,而非程序目录下
// 此处调用 GetOpenFileName 选择一张其他目录的图片文件
TCHAR pszPath[MAX_PATH] = { 0 };
OPENFILENAME filename = { 0 };
filename.lStructSize = sizeof(filename);
filename.lpstrFile = pszPath;
filename.nMaxFile = sizeof(pszPath) / sizeof(*pszPath);
filename.lpstrFilter = L"PNG(*.png)\0*.png\0\0";
filename.Flags = OFN_EXPLORER;
GetOpenFileName(&filename);
wprintf(L"pszPath:\t%ls\n", pszPath);
// 输出:pszPath: C:\Users\myname\Pictures\test.png
wchar_t pwszNewPath[MAX_PATH] = { 0 };
_wgetcwd(pwszNewPath, MAX_PATH);
wprintf(L"_wgetcwd:\t%ls\n", pwszNewPath);
// 输出:_wgetcwd: C:\Users\myname\Pictures
// 证明读取图片文件后,程序工作目录发生了变化,移动到了刚刚选取的文件所在目录
// 现在将目录设置回先前保存的目录
SetCurrentDirectory(pwszOldPath);
wchar_t pwszFinalPath[MAX_PATH] = { 0 };
_wgetcwd(pwszFinalPath, MAX_PATH);
wprintf(L"_wgetcwd:\t%ls\n", pwszFinalPath);
// 输出:_wgetcwd: E:\TempProject
// 证明程序目录恢复成功
// 备注:
// 在 VS 中调试时,这样是将工作目录设置回了项目目录
// 如果想要设置工作目录为程序目录,则需要使用 argv[0] 提供的完整程序路径,代码略
return 0;
}
如需更多信息,参见 http://huidong.xyz/article.php?blog_id=170