如何在系统路径中搜索文件?

时间:2014-03-20 15:23:59

标签: c++ winapi

我在某个文件夹中有x.dll,这是系统路径的一部分。我在同一文件夹中还有另一个文件x.zzz,这不是可执行文件。

在C ++程序中,我想在不加载x.zzz的情况下搜索x.dll。但我希望这与LoadLibrary函数完全一样。即,它应与LoadLibrary的搜索顺序相同。

这可能吗?

PS: 我检查了SearchPath()函数,但documentation中有一条评论说这不应该用于此目的。

  

建议不要将SearchPath函数用作查找.dll文件的方法       输出的预期用途是调用LoadLibrary函数。这可能导致       在找到错误的.dll文件,因为SearchPath函数的搜索顺序       与LoadLibrary函数使用的搜索顺序不同。如果你需要找到       并加载.dll文件,使用LoadLibrary函数。

2 个答案:

答案 0 :(得分:2)

使用任何内置函数的问题是他们将专门寻找可执行文件或dll。我说最好的办法是实际解析路径变量并手动遍历目录。这可以通过目录迭代的C函数来完成。以下内容适用于大多数平台。

#include <dirent.h>
#include <cstdlib>
#include <iostream>
#include <string>
...
std::string findInPath(const std::string &key, char delim = ';');
std::string findInDir(const std::string &key, const std::string &dir);
...
std::string findInDir(const std::string &key, const std::string &directory)
{
  DIR *dir = opendir(directory.c_str());
  if(!dir)
    return "";

  dirent *dirEntry;
  while(dirEntry = readdir(dir))
  {
    if(key == dirEntry->d_name) // Found!
      return directory+'/'+key;
  }
  return "";
}

std::string findInPath(const std::string &key, char delim)
{
  std::string path(std::getenv("PATH"));
  size_t posPrev = -1;
  size_t posCur;
  while((posCur = path.find(delim, posPrev+1)) != std::string::npos)
  {
    // Locate the next directory in the path
    std::string pathCurrent = path.substr(posPrev+1, posCur-posPrev-1);

    // Search the current directory
    std::string found = findInDir(key, pathCurrent);
    if(!found.empty())
      return found;

    posPrev = posCur;
  }

  // Locate the last directory in the path
  std::string pathCurrent = path.substr(posPrev+1, path.size()-posPrev-1);

  // Search the current directory
  std::string found = findInDir(key, pathCurrent);
  if(!found.empty())
    return found;

  return "";
}

答案 1 :(得分:0)

如何使用带有标志LOAD_LIBRARY_AS_IMAGE_RESOURCE的LoadLibraryEx()?

来自LoadLibraryEx documentation

  

如果使用此值,系统会将文件作为图像文件映射到进程的虚拟地址空间。但是,加载程序不会加载静态导入或执行其他常用的初始化步骤。如果要仅加载DLL以从中提取消息或资源,请使用此标志。

我意识到你说“没有加载”......但是使用这种技术会使.dll的函数和变量不会污染你的命名空间等等。如果你有性能要求,或者其他一些特定的理由来指定“不加载” “,请继续扩展。