Одна и та же команда CMD делает две разные вещи

Цель - найти любые новые / измененные / удаленные файлы. 00tobedeleted - это папка, которую я создал в C: \ Windows \ System32.

Когда я запускаю следующую команду через CMD:

dir C:\Windows\System32\00tobedeleted /s /b > E:\Database\filepaths.txt

Ничего не случилось, файл создан, все ок.

Когда я пытаюсь сделать то же самое в Visual Studio:

system("dir " + path_to_check + "/s /b > " + path_to_save + "filepaths.txt").c_str();

вывод - "Файл не найден". Может это из-за прав папки / файла (когда сканирую C: \ Windows \ System32 все тоже в порядке). Вопрос в том, как я могу получить пути к файлам для всех файлов (также скрытых и т. д.) С помощью Visual Studio?

path_to_check is obviously "C:\\Windows\\System32\\00tobedeleted "
and path_to_save is "E:\\Database\\"

Основной:

#include "database.h"
using namespace std;

int main()
{
    string path_to_check = "C:\\Windows\\System32\\00tobedeleted ", path_to_save = "E:\\Database\\", export_path = "E:\\Database\\";
    Database database;
    database.set_files_checksum(path_to_check, path_to_save);
}

Установить контрольную сумму:

void Database::set_files_checksum(string path_to_check, string path_to_save)
{
    string file;
    system(("dir " + path_to_check + "/s /b > " + path_to_save + "filepaths.txt").c_str());
}

Сначала скомпонуйте всю системную команду в одну строку, чтобы вы могли видеть, что на самом деле передается вызову system.

Ben 22.05.2018 11:21

Это было одно из первых, что я попробовал, если бы были ошибки, я бы не публиковал здесь :)

Ironwing 22.05.2018 11:23

И что такое system? Вызов ANSI system возвращает int, так что же означает system(str).c_str()?

Ben 22.05.2018 11:23

Другими словами: опубликуйте фактический код, фактические системные вызовы, фактические типы данных, покажите фактический результат.

Ben 22.05.2018 11:24

Вы пробовали запустить программу вне IDE? Что происходит до выполнения команды system?

Robert Andrzejuk 22.05.2018 11:24

Я не знаю, как сам код поможет вам, это все то же самое, что я опубликовал изначально. Запуск .exe из папки Debug от имени администратора не работает.

Ironwing 22.05.2018 11:35

См. Как я могу получить список файлов в каталоге с помощью C или C++?. Не используйте вызов system для простых вещей, таких как получение каталога или списка файлов. C++ и особенно Visual C++ имеют функции для всего, что также поддерживается cmd.exe, потому что cmd.exe также использует только функции ядра Windows, которые также доступны как (Visual) функция C++.

Mofi 22.05.2018 12:04

Я рекомендую выполнить поиск перед запросом, например, с помощью [C++] рекурсивный список файлов, который возвращает список из 240 результатов. Итак, как получить список файлов, рекурсивных в приложении C++, действительно спрашивали и уже достаточно ответили на Stack Overflow, и я совершенно уверен также на тысячах других веб-страниц, поскольку все библиотеки C++ предлагают функции для всех обращений к файловой системе.

Mofi 22.05.2018 12:19

@Mofi, так почему же команда не работает для каталога C: \ Windows \ System32? Можете ли вы предоставить подтверждение того, что, например, std :: filesystem работает быстрее? Я забочусь об эффективности с точки зрения скорости и памяти.

Ironwing 22.05.2018 12:34

@Mofi: Нет, system будет использовать «выполняется командным процессором» системы; который по умолчанию имеет значение CMD.EXE в Windows (и, скажем, sh в UNIX).

Christian.K 22.05.2018 13:16

@Ironwing Запуск нового процесса / исполняемого файла, такого как cmd.exe, в фоновом режиме или на переднем плане, который сам написан на C / C++ / C# и использует функции ядра Windows, всегда намного медленнее, чем использование соответствующих функций ядра Windows напрямую. Это можно увидеть с помощью Sysinternals Монитор процесса или путем кодирования обоих вариантов и измерения времени выполнения с помощью таймера высокой точности Windows.

Mofi 22.05.2018 13:36

Вы можете использовать Process Monitor, чтобы увидеть причину вывода File Not Found на вашем ПК. Я полагаю, вы скомпилировали свой код как приложение x86, что привело к доступу к %SystemRoot%\SysWOW64, который не содержит подпапки 00tobedeleted, потому что вы создали эту подпапку в %SystemRoot%\System32. См. Документацию Microsoft по перенаправитель файловой системы. Вам нужно будет использовать в своем 32-битном приложении "C:\\Windows\\Sysnative\\00tobedeleted", чтобы получить список файлов для нужного каталога.

Mofi 22.05.2018 13:42

@Mofi Я пробовал использовать recursive_directory_iterator из std :: filesystem. На сканирование C: \ Windows ушло 60 секунд. Использование метода с cmd занимает 10 секунд.

Ironwing 22.05.2018 14:14

Протестируйте следующий код, смените каталог для сохранения: pastebin.com/iJnGc7B9 Может я что-то делаю не так?

Ironwing 22.05.2018 14:25

На данный момент я установил только Visual Studio 2010, в которой нет поддержки библиотеки filesystem, которая была представлена ​​в Visual Studio 2015 как экспериментальная и, наконец, включена в стандарт C++ 17. Похоже, что Microsoft действительно плохо написала библиотеку filesystem. Я помню, что другой разработчик, использующий Visual Studio 2017, столкнулся с тем же при использовании библиотеки filesystem. Я все еще использую FindFirstFile / FindFirstFileEx / FindNextFile, также как и cmd.exe.

Mofi 23.05.2018 19:27

Использование FindFirstFile / FindFirstFileEx / FindNextFile требует (один раз после написания класса) для записи большего количества кода, чем одна строка, и, кроме того, имеет недостаток в том, что поддерживается только в Windows из-за того, что они являются функциями ядра Windows. Я действительно не знаю, почему библиотека filesystem была так плохо реализована Microsoft для Windows.

Mofi 23.05.2018 19:31

@Ironwing: Вы пытались отладить проблему с помощью этой системы (("echo" + path_to_check + "/ s / b> filepaths.txt"). C_str ()); Если у вас все хорошо, а если нет, попробуйте и расскажите нам, что сохраняется в filepaths.txt.

Nitro 24.05.2018 05:26
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
17
91
2

Ответы 2

Используйте двойной / для вашей командной строки.

Системная функция преобразует вашу строку с другой escape-последовательностью.

Таким образом, если вы отправите только 2 \ в своей строке, он запустит escape на следующем символе.

Итак, если строка, которую вы отправляете,

"dir C:\\Windows\\System32\\00tobedeleted /s /b > E:\\Database\\filepaths.txt"

Это будет работать как

dir C:WindowsSystem3200tobedeleted /s /b > E:Databasefilepaths.txt

В командной строке.

Вам нужно использовать следующие пути для ваших путей

C:\\\\Windows\\\\System32\\\\00tobedeleted
E:\\\\Database\\\\filepaths.txt

Отказ от ответственности: я тестировал системную команду в системе Linux. Не совсем уверен, будет ли то же самое работать с окнами.

Надеюсь, это поможет.

К сожалению, он перешел из вывода File Not Found в неправильный оператор каталога, поэтому я думаю, что это не сработает. Тем не менее, спасибо

Ironwing 22.05.2018 11:52

ОК. Значит, это должно быть из-за окон. Попробуйте повторить путь к файлу, а затем прочитать его. Я думаю, что раньше, когда вы пытались скомпилировать строку, а затем проверить ее содержимое, вы, должно быть, использовали что-то похожее на printf. Благодаря этому вы точно будете знать, что получает командная строка. Не забудьте запустить команду echo с помощью системной функции с указанием пути к файлу в качестве аргумента.

Nitro 22.05.2018 11:56

Нет, в C (и подобных ему языках) двойная обратная косая черта уже заменяет единицу. Итак, \\ получится как \, что и предполагалось.

Christian.K 22.05.2018 13:11

@ Christian.K: Я написал ответ на основе проведенного мной теста, а не просто на основе моего мнения, знаний или того, что я прочитал в Интернете. В настоящее время я использую MacBook Air, поэтому я заявляю об отказе от ответственности, что тест проводился в системе Linux (на заднем сайте я должен был упомянуть, что это Mac)

Nitro 22.05.2018 13:30

@Nitro Я не имел в виду, не говоря уже о том, чтобы написать что-либо из того, что вы сказали выше об исследовании, прежде чем отвечать. Я просто указал, что было не так с ответом, на случай, если другие придут и увидят его (без исправлений). Не обижайся (на случай, если ты обиделся).

Christian.K 22.05.2018 14:37

@ Christian.K: Помогите мне понять. Вы верите, что весь мой ответ неверен или в какой-то части есть ошибка? Кроме того, как вы уже комментировали ранее, я почувствовал, что вы, должно быть, подумали, что я записал свое мнение. Я также счел необходимым указать, что это было не только мое мнение, и что я написал (и успешно запустил) тестовый код для проверки моей теории. Я знаю, что двойной \\ в строке должен давать вам только \, но по какой-то причине системная функция интерпретирует «\\» как одиночный escape-символ на моем ноутбуке.

Nitro 22.05.2018 14:53

@nitro Ты ошибаешься насчет обратной косой черты, уходящей от дела. Не буду судить, отменяет ли это весь ваш ответ. По поводу моего первого комментария: опять же, не обижайтесь на лаконичные ответы / комментарии. Не стоит зачитывать их слишком много. Они здесь обычное дело (хорошо).

Christian.K 22.05.2018 15:00

@ Christian.K: Я знаю, что не ошибаюсь насчет побега. Я знаю это, потому что проверял. Но если вы хотите поверить в то, что я ошибаюсь, не проверив, правильно ли я прошел тест, тогда, пожалуйста, продолжайте. Тоже не обиделся, просто удивился.

Nitro 22.05.2018 15:20

@Nitro Я собираюсь закончить это здесь, но компиляция и запуск следующего #include <stdlib.h> int main() { system("dir c:\\windows\\system32"); } (в Windows) делает правильную вещь (одна обратная реакция плюс одна для выхода, а не четыре).

Christian.K 23.05.2018 10:45

@ Christian.K есть идеи, что может решить мою проблему? : / Я разместил код ниже, std :: filesystem также не работает для созданной вручную папки ...

Ironwing 23.05.2018 11:01

Все еще ища решение, std :: filesystem не работает для папки 00tobedeleted, кроме того, она работает медленнее.

#include <iostream>
#include <string>
#include <filesystem>
#include <fstream>
namespace fs = std::experimental::filesystem;
using namespace std;
void cmd_method(string path_to_check, string path_to_save)
{
    system(("dir " + path_to_check + " /s /b > " + path_to_save + "filepaths.txt").c_str());
}

void filesystem_method(string path_to_check, string path_to_save)
{   
    ofstream paths_o;
    string file;
    paths_o.open(path_to_save+"filepaths.txt");
    for (auto & p : fs::recursive_directory_iterator(path_to_check))
    {
        paths_o << p << endl;
    }
}

int main()
{
    std::string path_to_check = "C:\\Windows", path_to_save = "E:\\";
    filesystem / cmd _method(path_to_check, path_to_save);
    system("pause");
}

@Редактировать: ShellExecute тоже не помогает

ShellExecute(0, "open", "cmd.exe", "/C dir C:\\Windows\\System32 /s /b > E:\\Database\\out.txt", 0, SW_SHOW);

Другие вопросы по теме