You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同一DIR命令在CMD与Visual Studio中执行异常的解决咨询

解决Visual Studio中调用system执行dir命令提示"File Not Found"及获取所有文件路径的问题

咱们一步步拆解你遇到的问题,逐个击破:

1. 先搞定最直接的路径问题

你的path_to_check末尾多了一个空格:"C:\\Windows\\System32\\00tobedeleted ",这会让CMD误以为要找带空格后缀的文件夹,但实际你的文件夹是00tobedeleted——这大概率是触发"File Not Found"的直接原因。

另外,哪怕路径现在没空格,拼接CMD命令时也必须给路径套双引号(否则以后路径含空格时直接报错)。修正后的命令拼接应该是这样:

string cmd = "dir \"" + path_to_check + "\" /s /b /a > \"" + path_to_save + "filepaths.txt\"";
system(cmd.c_str());

这里加的/a参数是让dir显示所有属性的文件(包括隐藏、系统文件),刚好满足你要获取所有文件的需求。

2. 处理System32的文件系统重定向坑

如果你的Visual Studio项目是32位的,在64位Windows系统上,程序访问C:\Windows\System32会被自动重定向到C:\Windows\SysWOW64——而你的00tobedeleted文件夹是在真实的System32里,所以32位程序根本找不到它。

解决办法二选一:

  • 把项目改成64位:在VS解决方案资源管理器右键项目→属性→配置属性→常规→平台工具集,选择x64后重新编译;
  • 必须用32位程序的话,调用Windows API关闭重定向:
    #include <Windows.h>
    
    void Database::set_files_checksum(string path_to_check, string path_to_save) {
        PVOID oldValue = nullptr;
        // 关闭64位文件系统重定向
        Wow64DisableWow64FsRedirection(&oldValue);
    
        string cmd = "dir \"" + path_to_check + "\" /s /b /a > \"" + path_to_save + "filepaths.txt\"";
        system(cmd.c_str());
    
        // 用完恢复重定向
        Wow64RevertWow64FsRedirection(oldValue);
    }
    

3. 更可靠的替代方案:抛弃system,用原生API

调用system()依赖CMD.exe,容易受环境变量、权限、路径解析等问题影响。推荐用更可控的方式获取文件路径:

方案A:C++17 filesystem库(推荐)

这是标准库的一部分,跨平台且代码简洁:

#include "database.h"
#include <filesystem>
#include <fstream>
#include <string>

namespace fs = std::filesystem;

using namespace std;

void Database::set_files_checksum(const string& path_to_check, const string& path_to_save) {
    ofstream out_file(path_to_save + "filepaths.txt");
    if (!out_file.is_open()) {
        // 处理文件打开失败的情况,比如权限不足
        return;
    }

    // 递归遍历目录,跳过权限不足的文件夹,获取所有常规文件(含隐藏)
    for (const auto& entry : fs::recursive_directory_iterator(
        path_to_check, 
        fs::directory_options::skip_permission_denied | 
        fs::directory_options::follow_directory_symlinks)) {
        if (fs::is_regular_file(entry)) {
            out_file << entry.path().string() << '\n';
        }
    }
}

注意:需要在VS项目属性里开启C++17或更高版本,或者添加/std:c++17编译选项。

方案B:Windows原生FindFirstFile/FindNextFile API

如果要兼容C++17之前的版本,或者更精细控制文件属性,可以用Windows原生API:

#include "database.h"
#include <Windows.h>
#include <fstream>
#include <string>

using namespace std;

void traverse_directory(const string& dir_path, ofstream& out_file) {
    string search_path = dir_path + "\\*";
    WIN32_FIND_DATA find_data;
    HANDLE hFind = FindFirstFile(search_path.c_str(), &find_data);

    if (hFind == INVALID_HANDLE_VALUE) {
        return;
    }

    do {
        // 跳过.和..目录
        if (strcmp(find_data.cFileName, ".") == 0 || strcmp(find_data.cFileName, "..") == 0) {
            continue;
        }

        string full_path = dir_path + "\\" + find_data.cFileName;

        // 如果是目录,递归遍历
        if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
            traverse_directory(full_path, out_file);
        } else {
            // 写入所有类型的文件路径(含隐藏、系统文件)
            out_file << full_path << '\n';
        }
    } while (FindNextFile(hFind, &find_data));

    FindClose(hFind);
}

void Database::set_files_checksum(string path_to_check, string path_to_save) {
    ofstream out_file(path_to_save + "filepaths.txt");
    if (!out_file.is_open()) {
        return;
    }

    traverse_directory(path_to_check, out_file);
}

总结

  1. 先去掉path_to_check末尾的多余空格,给路径套双引号,加上/a参数获取所有文件;
  2. 如果是32位程序,要么改成64位,要么关闭文件系统重定向;
  3. 长期来看,用C++标准库或Windows原生API替代system(),能避免很多依赖CMD的坑。

内容的提问来源于stack exchange,提问作者Ironwing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:26:56