程序自拷贝重启后GetCurrentDirectoryA返回值不变该如何解决?
问题核心原因
你碰到的死循环本质是混淆了Windows系统中两个完全不同的路径概念:
GetCurrentDirectoryA返回的是进程当前工作目录:这个值是进程启动时由父进程指定的动态值,和你exe文件本身存放在哪个位置没有必然关联,也不会随exe文件的物理位置变化自动更新。- 你实际需要判断的是exe自身的物理存放目录,需要用专门的API获取。
修复方案
把你判断路径的逻辑从读取GetCurrentDirectoryA的返回值,替换成读取自身exe的实际路径,步骤如下:
- 调用
GetModuleFileNameA接口,传入NULL作为模块句柄,就能拿到当前运行的exe的完整绝对路径 - 切割路径去掉末尾的exe文件名,得到exe所在的目录
- 和
GetWindowsDirectoryA返回的系统目录做对比,一致就跳过自拷贝逻辑,不一致再执行拷贝+重启操作
参考代码示例
#include <windows.h> #include <shlwapi.h> #pragma comment(lib, "shlwapi.lib") BOOL IsRunningInWindowsDir() { // 获取自身exe完整路径 char szExeFullPath[MAX_PATH] = {0}; if (!GetModuleFileNameA(NULL, szExeFullPath, MAX_PATH)) { return FALSE; } // 移除文件名,保留所在目录 if (!PathRemoveFileSpecA(szExeFullPath)) { return FALSE; } // 获取Windows系统目录 char szWinDir[MAX_PATH] = {0}; if (!GetWindowsDirectoryA(szWinDir, MAX_PATH)) { return FALSE; } // Windows路径不区分大小写,用不区分大小写的对比逻辑 return lstrcmpiA(szExeFullPath, szWinDir) == 0; } // 业务逻辑入口调用 int main() { if (!IsRunningInWindowsDir()) { // 1. 执行自身、关联资源到Windows目录的拷贝逻辑 // 2. 用绝对路径启动Windows目录下的新exe char szTargetExePath[MAX_PATH] = {0}; GetWindowsDirectoryA(szTargetExePath, MAX_PATH); PathAppendA(szTargetExePath, "你的程序名.exe"); ShellExecuteA(NULL, "open", szTargetExePath, NULL, NULL, SW_SHOWNORMAL); // 3. 退出当前旧进程 ExitProcess(0); } // 后续正常业务逻辑 return 0; }
额外优化建议
- 写入Windows目录需要程序持有管理员权限,你需要在程序的manifest配置中添加
requireAdministrator权限声明,否则拷贝操作会被系统拦截 - 如果你只是需要多个组件共享固定路径,更推荐选择
C:\ProgramData\你的程序自定义目录作为存储位置,不需要修改系统目录,权限要求更低,也能实现全局所有组件都能访问到固定路径的需求
内容的提问来源于stack exchange,提问作者брат волк
相关产品推荐
相关产品推荐

