On Windows, system and hidden files are now ignored in all file

enumeration loops.
Should fix "desktop.ini still displaying error" #1761
This commit is contained in:
bubnikv 2019-02-03 15:30:37 +01:00
parent 14a623f50e
commit f9743d17e9
8 changed files with 70 additions and 49 deletions

View File

@ -8,6 +8,8 @@
#include "libslic3r.h"
namespace boost { namespace filesystem { class directory_entry; }}
namespace Slic3r {
extern void set_logging_level(unsigned int level);
@ -61,6 +63,12 @@ extern int rename_file(const std::string &from, const std::string &to);
// Copy a file, adjust the access attributes, so that the target is writable.
extern int copy_file(const std::string &from, const std::string &to);
// Ignore system and hidden files, which may be created by the DropBox synchronisation process.
// https://github.com/prusa3d/Slic3r/issues/1298
extern bool is_plain_file(const boost::filesystem::directory_entry &path);
extern bool is_ini_file(const boost::filesystem::directory_entry &path);
extern bool is_idx_file(const boost::filesystem::directory_entry &path);
// File path / name / extension splitting utilities, working with UTF-8,
// to be published to Perl.
namespace PerlUtils {

View File

@ -30,7 +30,13 @@
#include <tbb/task_scheduler_init.h>
#include <tbb/task_scheduler_init.h>
#if defined(__linux) || defined(__GNUC__ )
#include <strings.h>
#endif /* __linux */
#ifdef _MSC_VER
#define strcasecmp _stricmp
#endif
namespace Slic3r {
@ -248,6 +254,30 @@ int copy_file(const std::string &from, const std::string &to)
return 0;
}
// Ignore system and hidden files, which may be created by the DropBox synchronisation process.
// https://github.com/prusa3d/Slic3r/issues/1298
bool is_plain_file(const boost::filesystem::directory_entry &dir_entry)
{
if (! boost::filesystem::is_regular_file(dir_entry.status()))
return false;
#ifdef _MSC_VER
DWORD attributes = GetFileAttributesW(boost::nowide::widen(dir_entry.path().string()).c_str());
return (attributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) == 0;
#else
return true;
#endif
}
bool is_ini_file(const boost::filesystem::directory_entry &dir_entry)
{
return is_plain_file(dir_entry) && strcasecmp(dir_entry.path().extension().string().c_str(), ".ini") == 0;
}
bool is_idx_file(const boost::filesystem::directory_entry &dir_entry)
{
return is_plain_file(dir_entry) && strcasecmp(dir_entry.path().extension().string().c_str(), ".idx") == 0;
}
} // namespace Slic3r
#ifdef WIN32

View File

@ -249,10 +249,10 @@ bool Snapshot::equal_to_active(const AppConfig &app_config) const
boost::filesystem::path path2 = snapshot_dir / subdir;
std::vector<std::string> files1, files2;
for (auto &dir_entry : boost::filesystem::directory_iterator(path1))
if (boost::filesystem::is_regular_file(dir_entry.status()) && boost::algorithm::iends_with(dir_entry.path().filename().string(), ".ini"))
if (Slic3r::is_ini_file(dir_entry))
files1.emplace_back(dir_entry.path().filename().string());
for (auto &dir_entry : boost::filesystem::directory_iterator(path2))
if (boost::filesystem::is_regular_file(dir_entry.status()) && boost::algorithm::iends_with(dir_entry.path().filename().string(), ".ini"))
if (Slic3r::is_ini_file(dir_entry))
files2.emplace_back(dir_entry.path().filename().string());
std::sort(files1.begin(), files1.end());
std::sort(files2.begin(), files2.end());
@ -343,7 +343,7 @@ static void copy_config_dir_single_level(const boost::filesystem::path &path_src
throw std::runtime_error(std::string("Slic3r was unable to create a directory at ") + path_dst.string());
for (auto &dir_entry : boost::filesystem::directory_iterator(path_src))
if (boost::filesystem::is_regular_file(dir_entry.status()) && boost::algorithm::iends_with(dir_entry.path().filename().string(), ".ini"))
if (Slic3r::is_ini_file(dir_entry))
boost::filesystem::copy_file(dir_entry.path(), path_dst / dir_entry.path().filename(), boost::filesystem::copy_option::overwrite_if_exists);
}

View File

@ -297,7 +297,7 @@ std::vector<Index> Index::load_db()
std::vector<Index> index_db;
std::string errors_cummulative;
for (auto &dir_entry : boost::filesystem::directory_iterator(cache_dir))
if (boost::filesystem::is_regular_file(dir_entry.status()) && boost::algorithm::iends_with(dir_entry.path().filename().string(), ".idx")) {
if (Slic3r::is_idx_file(dir_entry)) {
Index idx;
try {
idx.load(dir_entry.path());

View File

@ -635,35 +635,32 @@ void ConfigWizard::priv::load_vendors()
const auto rsrc_vendor_dir = fs::path(resources_dir()) / "profiles";
// Load vendors from the "vendors" directory in datadir
for (fs::directory_iterator it(vendor_dir); it != fs::directory_iterator(); ++it) {
if (it->path().extension() == ".ini") {
for (auto &dir_entry : boost::filesystem::directory_iterator(vendor_dir))
if (Slic3r::is_ini_file(dir_entry)) {
try {
auto vp = VendorProfile::from_ini(it->path());
auto vp = VendorProfile::from_ini(dir_entry.path());
vendors[vp.id] = std::move(vp);
}
catch (const std::exception& e) {
BOOST_LOG_TRIVIAL(error) << boost::format("Error loading vendor bundle %1%: %2%") % it->path() % e.what();
BOOST_LOG_TRIVIAL(error) << boost::format("Error loading vendor bundle %1%: %2%") % dir_entry.path() % e.what();
}
}
}
// Additionally load up vendors from the application resources directory, but only those not seen in the datadir
for (fs::directory_iterator it(rsrc_vendor_dir); it != fs::directory_iterator(); ++it) {
if (it->path().extension() == ".ini") {
const auto id = it->path().stem().string();
for (auto &dir_entry : boost::filesystem::directory_iterator(rsrc_vendor_dir))
if (Slic3r::is_ini_file(dir_entry)) {
const auto id = dir_entry.path().stem().string();
if (vendors.find(id) == vendors.end()) {
try {
auto vp = VendorProfile::from_ini(it->path());
vendors_rsrc[vp.id] = it->path().filename().string();
auto vp = VendorProfile::from_ini(dir_entry.path());
vendors_rsrc[vp.id] = dir_entry.path().filename().string();
vendors[vp.id] = std::move(vp);
}
catch (const std::exception& e) {
BOOST_LOG_TRIVIAL(error) << boost::format("Error loading vendor bundle %1%: %2%") % it->path() % e.what();
BOOST_LOG_TRIVIAL(error) << boost::format("Error loading vendor bundle %1%: %2%") % dir_entry.path() % e.what();
}
}
}
}
// Load up the set of vendors / models / variants the user has had enabled up till now
const AppConfig *app_config = GUI::get_app_config();
@ -672,14 +669,15 @@ void ConfigWizard::priv::load_vendors()
} else {
// In case of legacy datadir, try to guess the preference based on the printer preset files that are present
const auto printer_dir = fs::path(Slic3r::data_dir()) / "printer";
for (fs::directory_iterator it(printer_dir); it != fs::directory_iterator(); ++it) {
auto needle = legacy_preset_map.find(it->path().filename().string());
if (needle == legacy_preset_map.end()) { continue; }
for (auto &dir_entry : boost::filesystem::directory_iterator(printer_dir))
if (Slic3r::is_ini_file(dir_entry)) {
auto needle = legacy_preset_map.find(dir_entry.path().filename().string());
if (needle == legacy_preset_map.end()) { continue; }
const auto &model = needle->second.first;
const auto &variant = needle->second.second;
appconfig_vendors.set_variant("PrusaResearch", model, variant, true);
}
const auto &model = needle->second.first;
const auto &variant = needle->second.second;
appconfig_vendors.set_variant("PrusaResearch", model, variant, true);
}
}
}

View File

@ -517,16 +517,6 @@ void PresetCollection::add_default_preset(const std::vector<std::string> &keys,
++ m_num_default_presets;
}
bool is_file_plain(const std::string &path)
{
#ifdef _MSC_VER
DWORD attributes = GetFileAttributesW(boost::nowide::widen(path).c_str());
return (attributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) == 0;
#else
return true;
#endif
}
// Load all presets found in dir_path.
// Throws an exception on error.
void PresetCollection::load_presets(const std::string &dir_path, const std::string &subdir)
@ -538,10 +528,7 @@ void PresetCollection::load_presets(const std::string &dir_path, const std::stri
// (see the "Preset already present, not loading" message).
std::deque<Preset> presets_loaded;
for (auto &dir_entry : boost::filesystem::directory_iterator(dir))
if (boost::filesystem::is_regular_file(dir_entry.status()) && boost::algorithm::iends_with(dir_entry.path().filename().string(), ".ini") &&
// Ignore system and hidden files, which may be created by the DropBox synchronisation process.
// https://github.com/prusa3d/Slic3r/issues/1298
is_file_plain(dir_entry.path().string())) {
if (Slic3r::is_ini_file(dir_entry)) {
std::string name = dir_entry.path().filename().string();
// Remove the .ini suffix.
name.erase(name.size() - 4);

View File

@ -243,7 +243,7 @@ std::string PresetBundle::load_system_presets()
std::string errors_cummulative;
bool first = true;
for (auto &dir_entry : boost::filesystem::directory_iterator(dir))
if (boost::filesystem::is_regular_file(dir_entry.status()) && boost::algorithm::iends_with(dir_entry.path().filename().string(), ".ini")) {
if (Slic3r::is_ini_file(dir_entry)) {
std::string name = dir_entry.path().filename().string();
// Remove the .ini suffix.
name.erase(name.size() - 4);

View File

@ -180,12 +180,11 @@ bool PresetUpdater::priv::get_file(const std::string &url, const fs::path &targe
// Remove leftover paritally downloaded files, if any.
void PresetUpdater::priv::prune_tmps() const
{
for (fs::directory_iterator it(cache_path); it != fs::directory_iterator(); ++it) {
if (it->path().extension() == TMP_EXTENSION) {
BOOST_LOG_TRIVIAL(debug) << "Cache prune: " << it->path().string();
fs::remove(it->path());
for (auto &dir_entry : boost::filesystem::directory_iterator(cache_path))
if (is_plain_file(dir_entry) && dir_entry.path().extension() == TMP_EXTENSION) {
BOOST_LOG_TRIVIAL(debug) << "Cache prune: " << dir_entry.path().string();
fs::remove(dir_entry.path());
}
}
}
// Get Slic3rPE version available online, save in AppConfig.
@ -299,9 +298,9 @@ void PresetUpdater::priv::check_install_indices() const
{
BOOST_LOG_TRIVIAL(info) << "Checking if indices need to be installed from resources...";
for (fs::directory_iterator it(rsrc_path); it != fs::directory_iterator(); ++it) {
const auto &path = it->path();
if (path.extension() == ".idx") {
for (auto &dir_entry : boost::filesystem::directory_iterator(rsrc_path))
if (is_idx_file(dir_entry)) {
const auto &path = dir_entry.path();
const auto path_in_cache = cache_path / path.filename();
if (! fs::exists(path_in_cache)) {
@ -318,7 +317,6 @@ void PresetUpdater::priv::check_install_indices() const
}
}
}
}
}
// Generates a list of bundle updates that are to be performed