From 669df123648aaa6aeccc70206b5417bc48b4e9ae Mon Sep 17 00:00:00 2001 From: Daniel Wilhelm Date: Fri, 18 Apr 2014 17:26:50 +0200 Subject: 5.19 --- Application.cpp | 315 ++++++--- BUILD/Changelog.txt | 26 +- BUILD/FreeFileSync.chm | Bin 432107 -> 434207 bytes BUILD/Help/FreeFileSync.hhc | 4 +- BUILD/Help/FreeFileSync.hhp | 2 +- BUILD/Help/html/Command line.html | 138 ++++ BUILD/Help/html/Links.html | 4 +- BUILD/Help/html/RealtimeSync.html | 90 +-- BUILD/Help/html/Run as Service.html | 34 +- BUILD/Help/html/Schedule a Batch Job.html | 61 +- BUILD/Help/html/Variable Drive Letters.html | 68 +- BUILD/Help/img/RealtimeSync.png | Bin 31170 -> 31399 bytes BUILD/Help/img/ScheduleBatch.png | Bin 23029 -> 23027 bytes BUILD/Help/img/WatchUsbInsert.png | Bin 30567 -> 30701 bytes BUILD/Help/img/create_shortcut.png | Bin 16086 -> 16019 bytes BUILD/Help/img/schedule_realtimesync.png | Bin 29072 -> 29315 bytes BUILD/Help/img/shortcut_properties.png | Bin 29921 -> 30148 bytes BUILD/Help/img/win7scheduler.png | Bin 28955 -> 28814 bytes BUILD/Languages/arabic.lng | 4 +- BUILD/Languages/croatian.lng | 341 ++++++---- BUILD/Languages/dutch.lng | 264 +++++--- BUILD/Languages/english_uk.lng | 164 +++-- BUILD/Languages/german.lng | 163 +++-- BUILD/Languages/italian.lng | 291 +++++---- BUILD/Languages/lithuanian.lng | 189 +++--- BUILD/Languages/slovenian.lng | 186 +++--- BUILD/Languages/spanish.lng | 185 ++++-- BUILD/Resources.zip | Bin 268137 -> 268644 bytes FreeFileSync.vcxproj | 32 +- RealtimeSync/RealtimeSync.vcxproj | 26 +- RealtimeSync/application.cpp | 27 +- RealtimeSync/gui_generated.cpp | 6 + RealtimeSync/gui_generated.h | 2 +- RealtimeSync/main_dlg.cpp | 88 +-- RealtimeSync/main_dlg.h | 17 +- RealtimeSync/makefile | 2 +- RealtimeSync/monitor.cpp | 281 ++++++++ RealtimeSync/monitor.h | 38 ++ RealtimeSync/tray_menu.cpp | 440 +++++++------ RealtimeSync/tray_menu.h | 10 +- RealtimeSync/watcher.cpp | 202 ------ RealtimeSync/watcher.h | 54 -- RealtimeSync/xml_ffs.cpp | 14 +- RealtimeSync/xml_proc.h | 8 +- algorithm.cpp | 48 +- comparison.cpp | 33 +- file_hierarchy.cpp | 33 +- file_hierarchy.h | 18 +- lib/ShadowCopy/Shadow_Server2003.vcxproj | 8 +- lib/ShadowCopy/Shadow_Windows7.vcxproj | 8 +- lib/ShadowCopy/Shadow_XP.vcxproj | 8 +- lib/Thumbnail/Thumbnail.vcxproj | 8 +- lib/db_file.cpp | 10 +- lib/dir_exist_async.h | 2 +- lib/dir_lock.cpp | 39 +- lib/generate_logfile.h | 4 +- lib/icon_buffer.cpp | 4 +- lib/parallel_scan.cpp | 8 +- lib/parse_lng.h | 7 +- lib/perf_check.cpp | 76 ++- lib/perf_check.h | 30 +- lib/process_xml.cpp | 45 +- lib/process_xml.h | 10 +- lib/resolve_path.cpp | 21 +- lib/shadow.cpp | 11 +- lib/status_handler.cpp | 11 +- lib/status_handler.h | 15 +- lib/versioning.cpp | 7 +- process_callback.h | 4 +- structures.cpp | 36 +- structures.h | 20 +- synchronization.cpp | 99 ++- ui/Taskbar_Seven/Taskbar_Seven.vcxproj | 8 +- ui/batch_status_handler.cpp | 15 +- ui/check_version.cpp | 4 +- ui/custom_grid.cpp | 12 +- ui/dir_name.cpp | 2 +- ui/gui_generated.cpp | 654 +++++++++++-------- ui/gui_generated.h | 153 ++--- ui/gui_status_handler.cpp | 12 +- ui/gui_status_handler.h | 3 +- ui/main_dlg.cpp | 288 ++++---- ui/main_dlg.h | 18 +- ui/msg_popup.h | 9 +- ui/progress_indicator.cpp | 979 ++++++++++++++++++---------- ui/progress_indicator.h | 8 +- ui/small_dlgs.cpp | 15 +- ui/switch_to_gui.h | 2 +- ui/sync_cfg.cpp | 48 +- ui/taskbar.cpp | 10 +- ui/taskbar.h | 4 +- ui/tray_icon.cpp | 224 +++---- ui/tray_icon.h | 38 +- ui/tree_view.cpp | 6 +- version/version.h | 2 +- wx+/dc.h | 127 ++++ wx+/graph.cpp | 495 ++++++++++---- wx+/graph.h | 137 ++-- wx+/grid.cpp | 59 +- wx+/no_flicker.h | 17 +- wx+/rtl.h | 54 -- wx+/shell_execute.h | 11 +- wx+/string_conv.h | 1 - zen/FindFilePlus/FindFilePlus.vcxproj | 4 +- zen/FindFilePlus/find_file_plus.cpp | 38 +- zen/basic_math.h | 9 +- zen/dir_watcher.cpp | 12 +- zen/dir_watcher.h | 4 +- zen/file_error.h | 1 - zen/file_handling.cpp | 90 ++- zen/file_handling.h | 9 +- zen/file_io.cpp | 26 +- zen/file_io.h | 4 +- zen/format_unit.cpp | 50 +- zen/format_unit.h | 13 +- zen/i18n.h | 1 + zen/long_path_prefix.h | 5 + zen/optional.h | 1 + zen/serialize.h | 6 +- zen/stl_tools.h | 3 + zen/string_base.h | 61 +- zen/sys_error.h | 18 +- zen/thread.h | 3 +- zen/type_tools.h | 4 +- zen/type_traits.h | 15 +- zen/win.h | 1 - zen/zstring.cpp | 8 +- zen/zstring.h | 10 +- 128 files changed, 4803 insertions(+), 3407 deletions(-) create mode 100644 BUILD/Help/html/Command line.html create mode 100644 RealtimeSync/monitor.cpp create mode 100644 RealtimeSync/monitor.h delete mode 100644 RealtimeSync/watcher.cpp delete mode 100644 RealtimeSync/watcher.h create mode 100644 wx+/dc.h diff --git a/Application.cpp b/Application.cpp index 7f89efcc..54258cd9 100644 --- a/Application.cpp +++ b/Application.cpp @@ -41,18 +41,21 @@ IMPLEMENT_APP(Application) namespace { +/* boost::thread::id mainThreadId = boost::this_thread::get_id(); void onTerminationRequested() { - std::wstring msg = boost::this_thread::get_id() == mainThreadId ? - L"Termination requested in main thread!\n\n" : - L"Termination requested in worker thread!\n\n"; - msg += L"Please file a bug report at: http://sourceforge.net/projects/freefilesync"; +std::wstring msg = boost::this_thread::get_id() == mainThreadId ? + L"Termination requested in main thread!\n\n" : + L"Termination requested in worker thread!\n\n"; +msg += L"Please file a bug report at: http://sourceforge.net/projects/freefilesync"; - wxSafeShowMessage(_("An exception occurred"), msg); - std::abort(); +wxSafeShowMessage(_("An exception occurred"), msg); +std::abort(); } +*/ + #ifdef _MSC_VER void crtInvalidParameterHandler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved) { assert(false); } #endif @@ -118,7 +121,8 @@ const wxEventType EVENT_ENTER_EVENT_LOOP = wxNewEventType(); bool Application::OnInit() { - std::set_terminate(onTerminationRequested); //unlike wxWidgets uncaught exception handling, this works for all worker threads + //-> this seems rather useless: + //std::set_terminate(onTerminationRequested); //unlike wxWidgets uncaught exception handling, this works for all worker threads #ifdef ZEN_WIN #ifdef _MSC_VER @@ -262,9 +266,10 @@ void Application::onQueryEndSession(wxEvent& event) } -void runGuiMode(const xmlAccess::XmlGuiConfig& guiCfg); -void runGuiMode(const std::vector& cfgFileName); -void runBatchMode(const Zstring& filename, FfsReturnCode& returnCode); +void runGuiMode(); +void runGuiMode(const XmlGuiConfig& guiCfg, const std::vector& referenceFiles); +void runBatchMode(const XmlBatchConfig& batchCfg, const Zstring& referenceFile, FfsReturnCode& returnCode); +void showSyntaxHelp(); void Application::launch(const std::vector& commandArgs) @@ -279,131 +284,247 @@ void Application::launch(const std::vector& commandArgs) //tentatively set program language to OS default until GlobalSettings.xml is read later setLanguage(xmlAccess::XmlGlobalSettings().programLanguage); //throw FileError } - catch (const FileError&) {} //no messagebox: consider batch job! + catch (const FileError&) { assert(false); } //no messagebox: consider batch job! - if (commandArgs.empty()) - runGuiMode(commandArgs); - else + + //parse command line arguments + std::vector leftDirs; + std::vector rightDirs; + std::vector> configFiles; //XmlType: batch or GUI files only { - const bool gotDirNames = std::any_of(commandArgs.begin(), commandArgs.end(), [](const Zstring& dirname) { return dirExists(dirname); }); - if (gotDirNames) //mode 1: create temp configuration based on directory names passed - { - XmlGuiConfig guiCfg; - guiCfg.mainCfg.syncCfg.directionCfg.var = DirectionConfig::MIRROR; + const Zchar optionLeftDir [] = Zstr("-leftdir"); + const Zchar optionRightDir[] = Zstr("-rightdir"); - for (auto it = commandArgs.begin(); it != commandArgs.end(); ++it) + auto syntaxHelpRequested = [](const Zstring& arg) + { + auto it = std::find_if(arg.begin(), arg.end(), [](Zchar c) { return c != Zchar('/') && c != Zchar('-'); }); + const Zstring argTmp(it, arg.end()); + return argTmp == Zstr("help") || + argTmp == Zstr("h") || + argTmp == Zstr("?"); + }; + + for (auto it = commandArgs.begin(); it != commandArgs.end(); ++it) + if (syntaxHelpRequested(*it)) + return showSyntaxHelp(); + else if (*it == optionLeftDir) { - size_t index = it - commandArgs.begin(); - - FolderPairEnh* fp = nullptr; - if (index < 2) - fp = &guiCfg.mainCfg.firstPair; - else + if (++it == commandArgs.end()) { - guiCfg.mainCfg.additionalPairs.resize((index - 2) / 2 + 1); - fp = &guiCfg.mainCfg.additionalPairs.back(); + wxMessageBox(replaceCpy(_("A directory path is expected after %x."), L"%x", utfCvrtTo(optionLeftDir)), L"FreeFileSync - " + _("Syntax error"), wxOK | wxICON_ERROR); + return; } - - if (index % 2 == 0) - fp->leftDirectory = *it; - else - fp->rightDirectory = *it; + leftDirs.push_back(*it); } - - runGuiMode(guiCfg); - } - else //mode 2: try to set config/batch-filename set by %1 parameter - { - std::vector argsTmp = commandArgs; - - for (auto it = argsTmp.begin(); it != argsTmp.end(); ++it) + else if (*it == optionRightDir) { - const Zstring& filename = *it; - + if (++it == commandArgs.end()) + { + wxMessageBox(replaceCpy(_("A directory path is expected after %x."), L"%x", utfCvrtTo(optionRightDir)), L"FreeFileSync - " + _("Syntax error"), wxOK | wxICON_ERROR); + return; + } + rightDirs.push_back(*it); + } + else + { + Zstring filename = *it; if (!fileExists(filename)) //...be a little tolerant { if (fileExists(filename + Zstr(".ffs_batch"))) - *it += Zstr(".ffs_batch"); + filename += Zstr(".ffs_batch"); else if (fileExists(filename + Zstr(".ffs_gui"))) - *it += Zstr(".ffs_gui"); + filename += Zstr(".ffs_gui"); else { - wxMessageBox(replaceCpy(_("Cannot find file %x."), L"%x", fmtFileName(filename)), _("Error"), wxOK | wxICON_ERROR); + wxMessageBox(replaceCpy(_("Cannot open file %x."), L"%x", fmtFileName(filename)), L"FreeFileSync - " + _("Error"), wxOK | wxICON_ERROR); return; } } + + switch (getXmlType(filename)) //throw() + { + case XML_TYPE_GLOBAL: + case XML_TYPE_OTHER: + wxMessageBox(replaceCpy(_("File %x does not contain a valid configuration."), L"%x", fmtFileName(filename)), L"FreeFileSync - " + _("Error"), wxOK | wxICON_ERROR); + return; + + case XML_TYPE_GUI: + configFiles.push_back(std::make_pair(filename, XML_TYPE_GUI)); + break; + case XML_TYPE_BATCH: + configFiles.push_back(std::make_pair(filename, XML_TYPE_BATCH)); + break; + } } + } + + if (leftDirs.size() != rightDirs.size()) + { + wxMessageBox(_("Unequal number of left and right directories specified."), L"FreeFileSync - " + _("Syntax error"), wxOK | wxICON_ERROR); + return; + } + + auto hasNonDefaultConfig = [](const FolderPairEnh& fp) + { + return !(fp == FolderPairEnh(fp.leftDirectory, + fp.rightDirectory, + nullptr, nullptr, FilterConfig())); + }; - switch (getMergeType(argsTmp)) //throw () + auto replaceDirectories = [&](MainConfiguration& mainCfg) + { + if (!leftDirs.empty()) + { + //check if config at folder-pair level is present: this probably doesn't make sense when replacing/adding the user-specified directories + if (hasNonDefaultConfig(mainCfg.firstPair) || std::any_of(mainCfg.additionalPairs.begin(), mainCfg.additionalPairs.end(), hasNonDefaultConfig)) { - case MERGE_BATCH: //pure batch config files - if (argsTmp.size() == 1) - runBatchMode(argsTmp[0], returnCode); - else - runGuiMode(argsTmp); - break; + wxMessageBox(_("The config file must not contain settings at directory pair level when directories are set via command line."), L"FreeFileSync - " + _("Syntax error"), wxOK | wxICON_ERROR); + return false; + } - case MERGE_GUI: //pure gui config files - case MERGE_GUI_BATCH: //gui and batch files - runGuiMode(argsTmp); - break; + mainCfg.additionalPairs.clear(); + for (size_t i = 0; i < leftDirs.size(); ++i) + if (i == 0) + { + mainCfg.firstPair.leftDirectory = leftDirs [0]; + mainCfg.firstPair.rightDirectory = rightDirs[0]; + } + else + mainCfg.additionalPairs.push_back(FolderPairEnh(leftDirs [i], + rightDirs[i], + nullptr, nullptr, FilterConfig())); + } + return true; + }; - case MERGE_OTHER: //= none or unknown; - //argsTmp are not empty and contain at least one non-gui/non-batch config file: find it! - std::find_if(argsTmp.begin(), argsTmp.end(), - [](const Zstring& filename) -> bool - { - switch (getXmlType(filename)) //throw() - { - case XML_TYPE_GLOBAL: - case XML_TYPE_OTHER: - wxMessageBox(replaceCpy(_("File %x does not contain a valid configuration."), L"%x", fmtFileName(filename)), _("Error"), wxOK | wxICON_ERROR); - return true; - - case XML_TYPE_GUI: - case XML_TYPE_BATCH: - break; - } - return false; - }); - break; + //distinguish sync scenarios: + //--------------------------- + if (configFiles.empty()) + { + //gui mode: default startup + if (leftDirs.empty()) + runGuiMode(); + //gui mode: default config with given directories + else + { + XmlGuiConfig guiCfg; + guiCfg.mainCfg.syncCfg.directionCfg.var = DirectionConfig::MIRROR; + + if (!replaceDirectories(guiCfg.mainCfg)) return; + runGuiMode(guiCfg, std::vector()); + } + } + else if (configFiles.size() == 1) + { + const Zstring filename = configFiles[0].first; + + //batch mode + if (configFiles[0].second == XML_TYPE_BATCH) + { + XmlBatchConfig batchCfg; + try + { + readConfig(filename, batchCfg); + } + catch (const xmlAccess::FfsXmlError& e) + { + wxMessageBox(e.toString(), L"FreeFileSync - " + _("Error"), wxOK | wxICON_ERROR); //batch mode: break on errors AND even warnings! + raiseReturnCode(returnCode, FFS_RC_ABORTED); + return; + } + if (!replaceDirectories(batchCfg.mainCfg)) return; + runBatchMode(batchCfg, filename, returnCode); + } + //GUI mode: single config + else + { + XmlGuiConfig guiCfg; + try + { + readConfig(filename, guiCfg); + } + catch (const xmlAccess::FfsXmlError& e) + { + if (e.getSeverity() == FfsXmlError::WARNING) + wxMessageBox(e.toString(), L"FreeFileSync - " + _("Warning"), wxOK | wxICON_WARNING); + //what about simulating changed config on parsing errors???? + else + { + wxMessageBox(e.toString(), L"FreeFileSync - " + _("Error"), wxOK | wxICON_ERROR); + return; + } + } + if (!replaceDirectories(guiCfg.mainCfg)) return; + //what about simulating changed config due to directory replacement? + //-> propably fine to not show as changed on GUI and not ask user to save on exit! + + runGuiMode(guiCfg, { filename }); //caveat: guiCfg and filename do not match if directories were set/replaced via command line! + } + } + //gui mode: merged configs + else + { + if (!leftDirs.empty()) + { + wxMessageBox(_("Directories cannot be set for more than one configuration file."), L"FreeFileSync - " + _("Syntax error"), wxOK | wxICON_ERROR); + return; + } + + std::vector filenames; + for (const auto& item : configFiles) + filenames.push_back(item.first); + + XmlGuiConfig guiCfg; //structure to receive gui settings with default values + try + { + readAnyConfig(filenames, guiCfg); //throw FfsXmlError + } + catch (const FfsXmlError& e) + { + if (e.getSeverity() == FfsXmlError::WARNING) + wxMessageBox(e.toString(), L"FreeFileSync - " + _("Warning"), wxOK | wxICON_WARNING); + //what about simulating changed config on parsing errors???? + else + { + wxMessageBox(e.toString(), L"FreeFileSync - " + _("Error"), wxOK | wxICON_ERROR); + return; } } + runGuiMode(guiCfg, filenames); } } -void runGuiMode(const xmlAccess::XmlGuiConfig& guiCfg) +void runGuiMode() { MainDialog::create(); } + + +void runGuiMode(const xmlAccess::XmlGuiConfig& guiCfg, + const std::vector& referenceFiles) { - MainDialog::create(guiCfg, true); + MainDialog::create(guiCfg, referenceFiles, nullptr, true); //startComparison == true! } -void runGuiMode(const std::vector& cfgFileNames) +void showSyntaxHelp() { - MainDialog::create(cfgFileNames); + wxMessageBox(_("Syntax:") + L"\n" + + L"FreeFileSync [" + _("config files") + L"]\n[-leftdir " + _("directory") + L"] [-rightdir " + _("directory") + L"]" + L"\n" + + L"\n" + + _("config files") + L"\n" + + _("Any number of FreeFileSync .ffs_gui and/or .ffs_batch configuration files.") + L"\n\n" + + L"-leftdir " + _("directory") + L" -rightdir " + _("directory") + L"\n" + + _("Any number of alternative directories for at most one config file."), + L"FreeFileSync - " + _("Command line"), wxOK | wxICON_INFORMATION); } -void runBatchMode(const Zstring& filename, FfsReturnCode& returnCode) +void runBatchMode(const XmlBatchConfig& batchCfg, const Zstring& referenceFile, FfsReturnCode& returnCode) { - //load XML settings - XmlBatchConfig batchCfg; - try - { - readConfig(filename, batchCfg); - } - catch (const xmlAccess::FfsXmlError& e) - { - wxMessageBox(e.toString(), _("Error"), wxOK | wxICON_ERROR); //batch mode: break on errors AND even warnings! - raiseReturnCode(returnCode, FFS_RC_ABORTED); - return; - } - auto notifyError = [&](const std::wstring& msg) { if (batchCfg.handleError == ON_ERROR_POPUP) - wxMessageBox(msg.c_str(), _("Error"), wxOK | wxICON_ERROR); + wxMessageBox(msg.c_str(), L"FreeFileSync - " + _("Error"), wxOK | wxICON_ERROR); else //"exit" or "ignore" logError(utfCvrtTo(msg)); @@ -445,11 +566,11 @@ void runBatchMode(const Zstring& filename, FfsReturnCode& returnCode) const TimeComp timeStamp = localTime(); - const SwitchToGui switchBatchToGui(filename, batchCfg, globalCfg); //prepare potential operational switch + const SwitchToGui switchBatchToGui(referenceFile, batchCfg, globalCfg); //prepare potential operational switch //class handling status updates and error messages BatchStatusHandler statusHandler(batchCfg.showProgress, //throw BatchAbortProcess - extractJobName(filename), + extractJobName(referenceFile), timeStamp, batchCfg.logFileDirectory, batchCfg.logfilesCountLimit, diff --git a/BUILD/Changelog.txt b/BUILD/Changelog.txt index b3ffe191..d8e3ad35 100644 --- a/BUILD/Changelog.txt +++ b/BUILD/Changelog.txt @@ -1,6 +1,29 @@ +FreeFileSync 5.19 +----------------- +Redesigned progress dialog including new items graph +New command line syntax: set directory names of a .ffs_gui/.ffs_batch externally +Explicit button on progress dialog to minimize to systray +Fixed progress graph labels being truncated (Debian, Ubuntu, openSUSE) +Resolved main dialog z-order issues during sync (OS X) +Reduced progress dialog layout twitching +Further improved comparison speed by 10% +Use proper config file path in file picker dialog (OS X) +Never interrupt when updating a file with fail-safe file copy after target was deleted +Prevent crash when closing progress dialog while paused (OS X) +Support external command lines starting with whitespace (Windows) +Show warning before starting external applications for more than 10 items +Start external applications synchronously if needed to avoid running out of system resources +Don't show hidden progress dialog when showing an error message in silent batch mode (OS X) +Correctly show file names containing ampersand characters in progress dialog +Adapt size of results dialog to fit contents +Correctly execute file move before parent directory will be deleted +Show a blinking system tray icon on errors instead of a modal dialog in RealtimeSync +Added installation size for Windows' Add/Remove Programs + + FreeFileSync 5.18 ----------------- -Workaround boost 1.54 bug "Procedure Entry Point Not Found in Kernel32.dll" (Windows XP) +Work around boost 1.54 bug "The procedure entry point GetTickCount64 could not be located in the dynamic link library KERNEL32.dll" (Windows XP) FreeFileSync 5.17 @@ -30,6 +53,7 @@ Improved sync progress dialog layout Suppress dubious wxWidgets error message "locale 'es_AR' can not be set". (OS X) Don't show busy cursor on synchronization results dialog Log error message upon retry as type info only +Updated translation files FreeFileSync 5.16 diff --git a/BUILD/FreeFileSync.chm b/BUILD/FreeFileSync.chm index ba059751..d6009619 100644 Binary files a/BUILD/FreeFileSync.chm and b/BUILD/FreeFileSync.chm differ diff --git a/BUILD/Help/FreeFileSync.hhc b/BUILD/Help/FreeFileSync.hhc index bfcd35f9..d3c318d1 100644 --- a/BUILD/Help/FreeFileSync.hhc +++ b/BUILD/Help/FreeFileSync.hhc @@ -20,8 +20,8 @@
  • - - + +
  • diff --git a/BUILD/Help/FreeFileSync.hhp b/BUILD/Help/FreeFileSync.hhp index 38c789d9..713fab68 100644 --- a/BUILD/Help/FreeFileSync.hhp +++ b/BUILD/Help/FreeFileSync.hhp @@ -12,7 +12,7 @@ Title=FreeFileSync - Help [FILES] html\FreeFileSync.html html\Versioning.html -html\Batch scripting.html +html\Command line.html html\Expert settings.html html\Comparison settings.html html\Daylight Saving time.html diff --git a/BUILD/Help/html/Command line.html b/BUILD/Help/html/Command line.html new file mode 100644 index 00000000..3768d036 --- /dev/null +++ b/BUILD/Help/html/Command line.html @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + +

    Command +line

    +

    FreeFileSync +enables additional synchronization scenarios via a command line interface. To get a syntax overview, open the console, go to the directory where FreeFileSync is installed and type:

    +

    +

    FreeFileSync + -h

    +

    +

    +


    +

    +

    1. +Run a FreeFileSync batch job

    +

    In order to start synchronization in batch mode, supply the path of a +*.ffs_batch +configuration as the first argument for FreeFileSync.exe:

    +

    +

    FreeFileSync + "D:\Backup Projects.ffs_batch"

    +

    +

    +

    After +synchronization one of the following status codes is returned:

    +

    +

    Return + Codes
    0 + - Synchronization completed successfully
    1 - Synchronization + completed with warnings
    2 - Synchronization completed with + errors
    3 - Synchronization was aborted
    +

    +

    +

    +

    You +can evaluate these codes from a script (e.g. a *.cmd +or *.bat file on Windows) +and check if synchronization completed successfully:

    +

    +

    "C:\Program + Files\FreeFileSync\FreeFileSync.exe" "D:\Backup + Projects.ffs_batch"
    if + errorlevel 1 (
      
    ::if + return code is 1 or greater, something went wrong, add special + treatment here
      
    echo + Errors occurred during synchronization...
      
    pause
    )

    +

    +

    +

    Instead +of displaying "An error occurred!" you can also send an +email notification (using a third party tool). +

    +


    +

    +

    +

    + Attention
    Make + sure your script is not blocked by a popup dialog. Consider the + following options when setting up a FreeFileSync batch job:
    +

    + +
  • + Disable + checkbox Show + progress dialog or have On completion + automatically close the results dialog after synchronization. +

    + +
  • + Set error handling to Exit instantly or Ignore errors. +

    + +

    +

    +


    +

    +

    2. +Start a FreeFileSync GUI configuration

    +

    If you +pass a *.ffs_gui +file, FreeFileSync will start in GUI mode and immediately start +comparison (but only if all directories exist):

    +

    +

    FreeFileSync + "D:\Manual Backup.ffs_gui"

    +

    +

    +


    +

    +

    3. +Customize an existing configuration

    +

    You can +replace the directories of a given *.ffs_gui +or *.ffs_batch +configuration by using the -leftdir +and -rightdir parameters:

    +

    +

    + FreeFileSync "D:\Manual Backup.ffs_gui" -leftdir C:\NewSource -rightdir D:\NewTarget

    +

    +

    +


    +

    +

    4. +Merge multiple configurations

    +

    When +more than one configuration file is provided, FreeFileSync will merge +everything into a single configuration with multiple folder pairs and +start in GUI mode:

    +

    +

    + FreeFileSync "D:\Manual Backup.ffs_gui" "D:\Backup Projects.ffs_batch"

    +

    +

    +


    +

    + + \ No newline at end of file diff --git a/BUILD/Help/html/Links.html b/BUILD/Help/html/Links.html index 125a8f2b..38c46bf3 100644 --- a/BUILD/Help/html/Links.html +++ b/BUILD/Help/html/Links.html @@ -26,8 +26,8 @@ Links feedback, suggestions and bug-reports
    http://sourceforge.net/projects/freefilesync

    - If you like FreeFileSync consider - supporting the project by a donation:
    Donate + If you like FreeFileSync: consider + supporting the project by a donation
    Donate via PayPal



    diff --git a/BUILD/Help/html/RealtimeSync.html b/BUILD/Help/html/RealtimeSync.html index c147a60e..d765c818 100644 --- a/BUILD/Help/html/RealtimeSync.html +++ b/BUILD/Help/html/RealtimeSync.html @@ -3,9 +3,9 @@ - + - + @@ -26,7 +26,7 @@ Synchronization

    RealtimeSync is a small tool which executes a command line each time it detects -changes in one of the monitored directories or +changes in one of the monitored directories or a directory becomes available (e. g. insert of a USB-stick). Usually this command line will simply trigger a FreeFileSync batch job.

    @@ -39,42 +39,46 @@ combination with FreeFileSync

    RealtimeSync.exe located in FreeFileSync's installation directory. Then specify all folders that shall be monitored. Instead of doing this manually you can import a *.ffs_batch -file via Menu -→ Program → Open. +file via Menu +→ Program → Open. This not only extracts all directories relevant for synchronization but also sets up the command line to execute the *.ffs_batch file each time changes are detected. -Now press Start +Now press Start to begin monitoring.


    -

    -

    Note

    -
  • The + +

    Note

    + +
  • The command should not block progress. Make sure the FreeFileSync batch job does not show any popup - dialogs. See notes in Batch + dialogs. See notes in Batch Scripting.
     

    -
  • The + +

  • The settings dialog can be skipped by passing a RealtimeSync configuration file (*.ffs_real) or a FreeFileSync batch file (*.ffs_batch) as first command line argument to RealtimeSync.exe. This can be integrated into the operating system's auto start facility:
          "C:\Program - Files\FreeFileSync\RealtimeSync.exe" - "C:\SyncJob.ffs_real"
          "C:\Program - Files\FreeFileSync\RealtimeSync.exe" "C:\SyncJob.ffs_batch"
     

    -
  • Using + Files\FreeFileSync\RealtimeSync.exe" "D:\Backup + Projects.ffs_real"
          "C:\Program + Files\FreeFileSync\RealtimeSync.exe" "D:\Backup + Projects.ffs_batch"
     

    + +
  • Using RealtimeSync is not restricted to starting FreeFileSync. It can also be used in other scenarios, like sending an email whenever a certain directory is modified.



    -

    +


    Example: @@ -98,41 +102,37 @@ files are modified in "H:\Data


    -

    -

    Note
    The - full path of the last changed file and the action that triggered - the change notification (create, update or delete) are written - to the environment variables %change_path% - and - %change_action%.

    +

    +

    Note
    The + full path of the last changed file and the action that triggered the + change notification (create, update or delete) are written + to the environment variables %change_path% + and + %change_action%.



    Example: Show names of changed files or directories. (Windows)

    - -

    -

    Show - which file or directory has triggered a change. Enter command - line:
        cmd /c echo - %change_action% "%change_path%" & pause

    Write - a list of all changes to a logfile:
        cmd - /c echo %change_action% "%change_path%" >> - c:\log.txt

    -
    -

    - -


    +

    +

    Show + which file or directory has triggered a change. Enter command + line:
        cmd /c echo %change_action% + "%change_path%" & pause

    Write + a list of all changes to a logfile:
        cmd + /c echo %change_action% "%change_path%" >> + c:\log.txt

    +

    -

    -

    Note
    During - execution of a Windows Batch file (*.bat/*.cmd) a black console - window is shown. You can hide it using the Visual Basic script - "HideConsole.vbs" located in FreeFileSync's installation - directory:

    -

    wscript - "C:\Program files\FreeFileSync\HideConsole.vbs" - C:\MyBatchFile.cmd

    +

    +

    Note
    During + execution of a Windows Batch file (*.bat/*.cmd) a black console + window is shown. You can hide it using the Visual Basic script + "HideConsole.vbs" located in FreeFileSync's installation + directory:

    +

    wscript + "C:\Program files\FreeFileSync\HideConsole.vbs" + C:\MyBatchFile.cmd




    diff --git a/BUILD/Help/html/Run as Service.html b/BUILD/Help/html/Run as Service.html index 2a853717..d04d8115 100644 --- a/BUILD/Help/html/Run as Service.html +++ b/BUILD/Help/html/Run as Service.html @@ -3,9 +3,9 @@ - + - + @@ -27,40 +27,40 @@ is designed as a background process which does not need further attention once it is running. Depending on your requirements there are a number of ways to start it together with the operating system. Generally the goal is to execute a command line like the following: -
    <installation +<installation folder>\RealtimeSync.exe <path to *.ffs_real or *.ffs_batch -file>

    +file>


    Example:

      -

      -

      - "C:\Program - Files\FreeFileSync\RealtimeSync.exe" "C:\some - folder\SyncJob.ffs_real"

      +

      +

      "C:\Program + Files\FreeFileSync\RealtimeSync.exe" "D:\Backup + Projects.ffs_real"




      -
    1. RealtimeSync - should be monitoring only while a specific user is logged in: Create +

    2. RealtimeSync + should be monitoring only while a specific user is logged in: Create a new shortcut, enter the command line from above as target and place it into the user's autostart folder.

      -

      -

      +

      +

       

    3. RealtimeSync should be monitoring while Windows is online irrespective of currently logged in users: Create a new task in your operating systems's task scheduler and have it execute the command line above - when the system starts. See Schedule + when the system starts. See Schedule a Batch Job for an example how to add a new task. Then change - the user to run the task to SYSTEM - - a special user account always running in the background.

      -

      + the user to run the task to
      SYSTEM + - a special user account always + running in the background.

      +


    diff --git a/BUILD/Help/html/Schedule a Batch Job.html b/BUILD/Help/html/Schedule a Batch Job.html index c77dbaad..76393187 100644 --- a/BUILD/Help/html/Schedule a Batch Job.html +++ b/BUILD/Help/html/Schedule a Batch Job.html @@ -3,9 +3,9 @@ - + - + -

    Schedule a batch job

    +

    Schedule +a batch job

    1. Create - a new batch job via FreeFileSync's main dialog: Menu - → Program → Save as batch job...
       

      + a new batch job via FreeFileSync's main dialog: Menu + → Program → Save as batch job...
       

    2. If the batch job shall run without user interaction or as part of an unattended batch script, make sure that no popup dialog stops the - progress:
      Disable checkbox Show - progress dialog to avoid blocking while showing the - result after synchronization. Alternatively you can select the "On - completion" action Close progress dialog located in - synchronization settings.
      Note: Even if the progress - dialog is not shown at the beginning, a user can make it visible - during synchronization by double-clicking the FreeFileSync - systray icon.

      + progress:
      Disable checkbox Show + progress dialog to avoid blocking while showing + the result after synchronization. Alternatively you can select the + "On completion" action Close progress dialog + located in synchronization settings.
      Note: Even if the + progress dialog is not shown at the beginning, a user can make it + visible during synchronization by double-clicking the + FreeFileSync systray icon.

       

    3. In order to prevent error or warning popup messages from stopping - progress, set Error handling - to either Ignore or - Exit.

      + progress, set Error + handling to either Ignore + or Exit.

       

    4. Setup your operating system's scheduler

      @@ -56,13 +57,12 @@ and insert the *.ffs_batch file into Add arguments.

    5. Use - quotation marks to protect spaces in path names, e.g.: "C:\some - folder\SyncJob.ffs_batch"

      + quotation marks to protect spaces in path names, e.g.: "D:\Backup + Projects.ffs_batch"

    -

    -

    - Note
    Beginning +

    +

    Note
    Beginning with Windows Vista the "Program/script" always needs point to an executable file like "FreeFileSync.exe" even if ffs_batch file associations have been set!
    If @@ -77,9 +77,10 @@ XP Scheduled Tasks:

    • Go - to Start → Control Panel - → Scheduled Tasks and select Add - Scheduled Task.

      + to Start + → Control Panel → Scheduled Tasks and + select Add + Scheduled Task.

    • Follow the wizard and select FreeFileSync.exe as program to run.

    • Fill @@ -94,12 +95,12 @@ Gnome-schedule, if necessary: sudo apt-get install gnome-schedule

    • Go - to System - → Preferences → Scheduled tasks

      -
    • Enter - the command as: - <FreeFileSync - installation folder>/FreeFileSync <job name>.ffs_batch

      + to System + → Preferences → Scheduled tasks

      +
    • Enter + the command as: + <FreeFileSync + installation folder>/FreeFileSync <job name>.ffs_batch

    diff --git a/BUILD/Help/html/Variable Drive Letters.html b/BUILD/Help/html/Variable Drive Letters.html index 5d41c4ca..ee95e4a3 100644 --- a/BUILD/Help/html/Variable Drive Letters.html +++ b/BUILD/Help/html/Variable Drive Letters.html @@ -3,9 +3,9 @@ - + - +