Цель - найти любые новые / измененные / удаленные файлы. 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? Вызов ANSI system возвращает int, так что же означает system(str).c_str()?
Другими словами: опубликуйте фактический код, фактические системные вызовы, фактические типы данных, покажите фактический результат.
Вы пробовали запустить программу вне IDE? Что происходит до выполнения команды system?
Я не знаю, как сам код поможет вам, это все то же самое, что я опубликовал изначально. Запуск .exe из папки Debug от имени администратора не работает.
См. Как я могу получить список файлов в каталоге с помощью C или C++?. Не используйте вызов system для простых вещей, таких как получение каталога или списка файлов. C++ и особенно Visual C++ имеют функции для всего, что также поддерживается cmd.exe, потому что cmd.exe также использует только функции ядра Windows, которые также доступны как (Visual) функция C++.
Я рекомендую выполнить поиск перед запросом, например, с помощью [C++] рекурсивный список файлов, который возвращает список из 240 результатов. Итак, как получить список файлов, рекурсивных в приложении C++, действительно спрашивали и уже достаточно ответили на Stack Overflow, и я совершенно уверен также на тысячах других веб-страниц, поскольку все библиотеки C++ предлагают функции для всех обращений к файловой системе.
@Mofi, так почему же команда не работает для каталога C: \ Windows \ System32? Можете ли вы предоставить подтверждение того, что, например, std :: filesystem работает быстрее? Я забочусь об эффективности с точки зрения скорости и памяти.
@Mofi: Нет, system будет использовать «выполняется командным процессором» системы; который по умолчанию имеет значение CMD.EXE в Windows (и, скажем, sh в UNIX).
@Ironwing Запуск нового процесса / исполняемого файла, такого как cmd.exe, в фоновом режиме или на переднем плане, который сам написан на C / C++ / C# и использует функции ядра Windows, всегда намного медленнее, чем использование соответствующих функций ядра Windows напрямую. Это можно увидеть с помощью Sysinternals Монитор процесса или путем кодирования обоих вариантов и измерения времени выполнения с помощью таймера высокой точности Windows.
Вы можете использовать Process Monitor, чтобы увидеть причину вывода File Not Found на вашем ПК. Я полагаю, вы скомпилировали свой код как приложение x86, что привело к доступу к %SystemRoot%\SysWOW64, который не содержит подпапки 00tobedeleted, потому что вы создали эту подпапку в %SystemRoot%\System32. См. Документацию Microsoft по перенаправитель файловой системы. Вам нужно будет использовать в своем 32-битном приложении "C:\\Windows\\Sysnative\\00tobedeleted", чтобы получить список файлов для нужного каталога.
@Mofi Я пробовал использовать recursive_directory_iterator из std :: filesystem. На сканирование C: \ Windows ушло 60 секунд. Использование метода с cmd занимает 10 секунд.
Протестируйте следующий код, смените каталог для сохранения: pastebin.com/iJnGc7B9 Может я что-то делаю не так?
На данный момент я установил только Visual Studio 2010, в которой нет поддержки библиотеки filesystem, которая была представлена в Visual Studio 2015 как экспериментальная и, наконец, включена в стандарт C++ 17. Похоже, что Microsoft действительно плохо написала библиотеку filesystem. Я помню, что другой разработчик, использующий Visual Studio 2017, столкнулся с тем же при использовании библиотеки filesystem. Я все еще использую FindFirstFile / FindFirstFileEx / FindNextFile, также как и cmd.exe.
Использование FindFirstFile / FindFirstFileEx / FindNextFile требует (один раз после написания класса) для записи большего количества кода, чем одна строка, и, кроме того, имеет недостаток в том, что поддерживается только в Windows из-за того, что они являются функциями ядра Windows. Я действительно не знаю, почему библиотека filesystem была так плохо реализована Microsoft для Windows.
@Ironwing: Вы пытались отладить проблему с помощью этой системы (("echo" + path_to_check + "/ s / b> filepaths.txt"). C_str ()); Если у вас все хорошо, а если нет, попробуйте и расскажите нам, что сохраняется в filepaths.txt.





Используйте двойной / для вашей командной строки.
Системная функция преобразует вашу строку с другой 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 в неправильный оператор каталога, поэтому я думаю, что это не сработает. Тем не менее, спасибо
ОК. Значит, это должно быть из-за окон. Попробуйте повторить путь к файлу, а затем прочитать его. Я думаю, что раньше, когда вы пытались скомпилировать строку, а затем проверить ее содержимое, вы, должно быть, использовали что-то похожее на printf. Благодаря этому вы точно будете знать, что получает командная строка. Не забудьте запустить команду echo с помощью системной функции с указанием пути к файлу в качестве аргумента.
Нет, в C (и подобных ему языках) двойная обратная косая черта уже заменяет единицу. Итак, \\ получится как \, что и предполагалось.
@ Christian.K: Я написал ответ на основе проведенного мной теста, а не просто на основе моего мнения, знаний или того, что я прочитал в Интернете. В настоящее время я использую MacBook Air, поэтому я заявляю об отказе от ответственности, что тест проводился в системе Linux (на заднем сайте я должен был упомянуть, что это Mac)
@Nitro Я не имел в виду, не говоря уже о том, чтобы написать что-либо из того, что вы сказали выше об исследовании, прежде чем отвечать. Я просто указал, что было не так с ответом, на случай, если другие придут и увидят его (без исправлений). Не обижайся (на случай, если ты обиделся).
@ Christian.K: Помогите мне понять. Вы верите, что весь мой ответ неверен или в какой-то части есть ошибка? Кроме того, как вы уже комментировали ранее, я почувствовал, что вы, должно быть, подумали, что я записал свое мнение. Я также счел необходимым указать, что это было не только мое мнение, и что я написал (и успешно запустил) тестовый код для проверки моей теории. Я знаю, что двойной \\ в строке должен давать вам только \, но по какой-то причине системная функция интерпретирует «\\» как одиночный escape-символ на моем ноутбуке.
@nitro Ты ошибаешься насчет обратной косой черты, уходящей от дела. Не буду судить, отменяет ли это весь ваш ответ. По поводу моего первого комментария: опять же, не обижайтесь на лаконичные ответы / комментарии. Не стоит зачитывать их слишком много. Они здесь обычное дело (хорошо).
@ Christian.K: Я знаю, что не ошибаюсь насчет побега. Я знаю это, потому что проверял. Но если вы хотите поверить в то, что я ошибаюсь, не проверив, правильно ли я прошел тест, тогда, пожалуйста, продолжайте. Тоже не обиделся, просто удивился.
@Nitro Я собираюсь закончить это здесь, но компиляция и запуск следующего #include <stdlib.h> int main() { system("dir c:\\windows\\system32"); } (в Windows) делает правильную вещь (одна обратная реакция плюс одна для выхода, а не четыре).
@ Christian.K есть идеи, что может решить мою проблему? : / Я разместил код ниже, std :: filesystem также не работает для созданной вручную папки ...
Все еще ища решение, 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);
Сначала скомпонуйте всю системную команду в одну строку, чтобы вы могли видеть, что на самом деле передается вызову
system.