开篇提示:本文为本人原创,本文欢迎转载,但必须注明本文出处,例如。
“该文引用自 CruiseYoung的:设置“当前文件夹”为“当前模块”所在文件夹
http://blog.csdn.net/fksec/article/details/41963057”
否则说明阁下愿意支付以100元人民币每字计的稿费,敬请留意。
1 开题背景
1.1 背景
经常使用VS调试程序的同学都有过这样的经历,加载某配置文件时,在用编译器调试时路径(相对路径)设置明明正确,但当程序单独运行时就找不到文件或找不到路径了。这就是程序时和调试时加载配置文件路径不一致的问题造成的。
1.2 解决方案
就是我们在加载配置文件前,我们设置一个固定参照物,然后将参照物的目录作为当前目录。这时再设置的路径就能解决上述问题。然而我们常用的参照物就是当前执行模块。
当运行模块所在目录就是当前工程的输出目录,则可以做如下设置(以VS2013为例)来代替:
工程属性-->配置属性-->调试-->工作目录: 将$(ProjectDir)改为$(OutDir);
1.3 注意事项
以上解决方案不能用在Windows服务程序中,因为Widndows会将当前程序(模块)的执行目录,与安装目录不同,而配置文件是相对于安装目录中程序的路径。所以,必须先获取Windows服务程序的安装路径后,再将该安装路径设置为当前目录,最后根据当前目录来设置配置文件的相对目录。Windows服务程序中获取安装路径的方法请到我的“CNTService_NoMFC”库中查看GetWindowsServiceInstallPath()函数的实现。
地址: https://github.com/CruiseYoung/CNTService_NoMFC/blob/master/CNTService_NoMFC/ntserv.cpp
2 设置当前目录头文件
文件:cruise_set_current_directory.hpp#pragma once #ifdef WIN32 #include <tchar.h> #include <WinSock2.h> #include <shlwapi.h> #pragma comment(lib, "shlwapi.lib") #endif // WIN32 // 设置当前工作目录,目前只有windows平台 inline void set_curr_dir(void) { #ifdef WIN32 TCHAR tzFileName[_MAX_PATH] = { 0 }; GetModuleFileName(NULL, tzFileName, _MAX_PATH); PathRemoveFileSpec(tzFileName); SetCurrentDirectory(tzFileName); #endif // WIN32 } #ifdef _WIN32 #include <tchar.h> #include <WinSock2.h> #include <stdlib.h> #include <windows.h> #endif // 设置当前工作目录,目前只有windows平台 inline void set_curr_dir2(void) { #ifdef WIN32 TCHAR tzFileName[_MAX_PATH] = { 0 }; //HMODULE hModule = GetModuleHandle(NULL); //GetModuleFileName(hModule, tzFileName, _MAX_PATH); GetModuleFileName(NULL, tzFileName, _MAX_PATH); TCHAR tzDrive[_MAX_DRIVE] = { 0 }; TCHAR tzDir[_MAX_DIR] = { 0 }; TCHAR tzFname[_MAX_FNAME] = { 0 }; TCHAR tzExt[_MAX_EXT] = { 0 }; //_tsplitpath(tzFileName, tzDrive, tzDir, tzFname, tzExt); _tsplitpath_s(tzFileName, tzDrive, _MAX_DRIVE, tzDir, _MAX_DIR, tzFname, _MAX_FNAME, tzExt, _MAX_EXT); _tcsset_s(tzFileName, 0); _tcscat_s(tzFileName, tzDrive); _tcscat_s(tzFileName, tzDir); SetCurrentDirectory(tzFileName); #endif // WIN32 }
注1:set_curr_dir()和set_curr_dir2()二者选其一即可;
注2:建议将上述函数作为main()函数中的 首句。
3 测试文件
文件:test_set_current_directory.cpp#include "cruise_set_current_directory.hpp" int main(int argc, char* argv[]) { set_curr_dir(); //log_init(_T("..\\..\\config\\log4cplus.properties"), _T("aaaa")); //log_uinit(); system("pause"); return 0; }