mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	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:
		
							parent
							
								
									14a623f50e
								
							
						
					
					
						commit
						f9743d17e9
					
				
					 8 changed files with 70 additions and 49 deletions
				
			
		| 
						 | 
				
			
			@ -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 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
			}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue