使用相对路径的问题

问题引入

项目中需要集成其他团队做的一个带有界面的工具。使用该工具时碰到了如下问题:

  1. 直接双击这个工具的exe,可以正常启动。
  2. 通过程序调用,或者用Everything打开这个工具,工具可以启动,但是界面上的图标全部消失了。

问题分析

打开命令行,执行目录切换到该exe目录下,然后调用该exe,正常启动。将执行目录切换到上上级目录,然后调用该exe,工具不能正常启动,图标全部消失。
通过分析,猜测该工具设置图标等资源文件时使用的是相对路径

验证

生成一个程序read_a.exe,该程序用来打开该exe目录下面的a.txt文件(使用相对路径"./a.txt"),正常打开a.txt输出“Ok”,打开失败输出“Failed”。


#include <iostream>
#include <fstream>

int main() {
  std::fstream file("./a.txt");
  if ( !file.is_open() ) {
    std::cout << "Failed!" << std::endl;
  } else {
    std::cout << "Ok!" << std::endl;
  }

  std::cin.get();

  return 0;
}

将a.txt放到read_a.exe的目录下面。通过命令行切换到该目录,执行该程序read_a.exe。程序可以正常运行,成功打开a.txt。
在这里插入图片描述
将执行目录切换到上一级,然后执行该exe。程序打开a.txt失败。
在这里插入图片描述
通过程序调用。

#include <iostream>

int main() {
  system("\"C:\\Users\\Admin\\Desktop\\CPP_TEST\\Debug\\read_a.exe\"");
  
  return 0;
}

在这里插入图片描述

解决办法 1: 调用方切换工作路径

在调用时,将程序的工作目录临时切换到被调用程序read_a.exe的目录。调用之后再将工作目录切换到原来的路径。在Windows平台下面可以使用APISetCurrentDirectoryGetCurrentDirectory

#include <windows.h>
#include <iostream>

int main() {
  wchar_t backup_dir[MAX_PATH];
  GetCurrentDirectory(MAX_PATH, backup_dir);
  std::wcout << L"Backup dir: " << backup_dir << std::endl;
  
  if ( SetCurrentDirectory(L"C:\\Users\\Admin\\Desktop\\CPP_TEST\\Debug\\") ) {
    system("read_a.exe");
    SetCurrentDirectory(backup_dir);
  }

  return 0;
}

在这里插入图片描述

解决方法 2:获取自身的执行路径

为了使用相对路径,更方便地加载文件,可以首先获得exe自身的绝对路径,然后用其拼接相对路径。

#include <windows.h>
#include <iostream>

#include <fstream>
int main() {
  // 获取当前exe的路径。
  wchar_t path[MAX_PATH] = { 0 };
  GetModuleFileName(NULL, path, MAX_PATH);
  
  wchar_t drive[_MAX_DRIVE] = { 0 };
  wchar_t dir[_MAX_DIR] = { 0 };
  wchar_t file_name[_MAX_FNAME] = { 0 };
  wchar_t ext[_MAX_EXT] = { 0 };
  _wsplitpath_s(path, drive, _MAX_DRIVE, dir, _MAX_DIR, file_name, _MAX_FNAME,  ext, _MAX_EXT);
  
  // 拼接资源文件的相对路径。
  std::wstring file_path = dir;
  file_path += L"resource/a.txt";
  
  std::fstream file(file_path);
  if (!file.is_open()) {
    std::cout << "Failed!" << std::endl;
  } else {
    std::cout << "Ok!" << std::endl;
  }
  std::cin.get();
  return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值