# Runtime Scripts

These are functions that are defined in your **Runtime** script and are called by SyncBackPro. A runtime script can be used to change what happens when a profile is run. For example, you could stop a profile from being run if certain conditions aren't met, or perform actions when some files are copied, deleted, or renamed. The functions are called by SyncBackPro at the appropriate time. Runtime scripts are [used by profiles](SetupScripts.md) and have access to the [SBRunning](SBRunning.md), [SBSystem](SBSystem.md), [SBVariables](SBVariables.md), and [SBHistory](SBHistory.md) objects.

All the example code below is written in using the [Pascal](PascalScriptLanguage.md) scripting language.

The order in which these routines are called is listed below. However, it may not run exactly in this order depending on the profile settings, e.g. the Run After program may be called after the log file is created. Also, routines may not be called, e.g. it's not a Fast Backup, there is no Run Before program, etc.

***[Ransomware detection]***

RunDisabledCheck

InitialiseVars

RunBeforeConfig

RunDoFullBackup

***[Silently fail if no network connection or no internet connection]***

***[Check is source and/or destination can be reached]***

RunAfterConfig

RunRunBeforeBefore

***[Run Before program]***

RunRunBeforeAfter

***[Connects to FTP etc.]***

***[Prepares the profile log]***

RunLogOpening

RunLogLocationInfoToAdd

RunLogLocationInfoCaption

RunLogLocationInfoInfo

RunDeleteAll

RunBeforeScanning

***[Scans source and destination]***

RunBeforeFileCompare

RunFileCompareSame / RunFileCompareSameEx

RunFileCompareDiff

RunAfterFileCompare

RunBeforeFolderCompare

RunAfterFolderCompare

RunShowDiffWindow

***[Differences window shown]***

RunDiffColumnsCount

RunDiffColumnTitle

RunDiffOpened

RunDiffColumnText

RunDiffColumnHint

RunDiffColumnSort

RunDiffFocusChanged

RunDiffColumnClicked

RunDiffKeyPress

RunDiffClosed

RunPreCopyCheck

***[Processes each file...]***

RunBeforeCopyFile / BeforeCopyFileEx

RunAfterCopyFile

RunBeforeRenameFile

RunAfterRenameFile

RunBeforeDeleteFile

RunAfterDeleteFile

RunBeforeSetDateTimes

RunAfterSetDateTimes

RunBeforeSetAttrs

RunAfterSetAttrs

RunRunAfterBefore

***[Run After program]***

RunRunAfterAfter

***[Close log, display log]***

RunLogClosing

***[Network disconnect]***

RunProfileResult

***[Email log]***

RunBeforeEmailLog

RunEmailLogAttachToAdd

RunEmailLogAttachFilename

RunAfterEmailLog

**function RunBeforeCopyFile(ToLeft, Filename; var ToDirCreated; var FromFileLocked; var ToFileLocked; var DoneCopy);**

**ToLeft:** True if the left/source file is to be copied from the right/destination

**Filename:** The file to be copied (not including the base path)

**ToDirCreated:** Set to True if a directory was created

**FromFileLocked:** Set to True if the file to be copied is locked

**ToFileLocked:** Set to True if the file to be replaced is locked

**DoneCopy:** Set to True if the file was copied

**Return value:** An error message if the copy failed

This function is called before a file is to be copied, and before any version is made. On failure the function should return an error message (do not return an error message if the script is not copying files). If a directory was created in order to copy the file then ToDirCreated should be returned as True. If the from file is locked then FromFileLocked should be returned as True (and an error message should be returned). If the to file is locked then ToFileLocked should be returned as True (and an error message should be returned). If the file was copied then DoneCopy should be returned as True.

Note that once a script has copied a file then no other scripts will be called to copy the file. This means the order of run-time scripts used in a profile is important.

This function is not called if the run is a [simulation](SBRunning.md#property_simulated).

IMPORTANT: If the profile is using a file integrity database, and you have a [RunBeforeCopyFileEx](RuntimeScripts.md#function_runbeforecopyfileex_toleft__filename__var_todircreated__var_fromfilelocked__var_tofilelocked__var_donecopy__var_integrityhash__var_integritytype__) function, then RunBeforeCopyFileEx will be called instead of RunBeforeCopyFile.

See also [RunAfterCopyFile](RuntimeScripts.md#procedure_runaftercopyfile_toleft__filename__failed__)

**function RunBeforeCopyFileEx(ToLeft, Filename; var ToDirCreated; var FromFileLocked; var ToFileLocked; var DoneCopy; var IntegrityHash; var IntegrityType);**

**ToLeft:** True if the left/source file is to be copied from the right/destination

**Filename:** The file to be copied (not including the base path)

**ToDirCreated:** Set to True if a directory was created

**FromFileLocked:** Set to True if the file to be copied is locked

**ToFileLocked:** Set to True if the file to be replaced is locked

**DoneCopy:** Set to True if the file was copied

**IntegrityHash:** Set this to a hash value for integrity checking

**IntegrityType:** Set this to the type of hash value ([TIntegrityType](ScriptConstants.md#tintegritytype))

**Return value:** An error message if the copy failed

This function is called before a file is to be copied, and before any version is made. On failure the function should return an error message (do not return an error message if the script is not copying files). If a directory was created in order to copy the file then ToDirCreated should be returned as True. If the from file is locked then FromFileLocked should be returned as True (and an error message should be returned). If the to file is locked then ToFileLocked should be returned as True (and an error message should be returned). If the file was copied then DoneCopy should be returned as True.

IntegrityHash and IntegrityType are for the file integrity database. If you cannot return a file hash then return an empty string and IntegrityType as EIT_None.

Note that once a script has copied a file then no other scripts will be called to copy the file. This means the order of run-time scripts used in a profile is important.

This function is not called if the run is a [simulation](SBRunning.md#property_simulated).

IMPORTANT: RunBeforeCopyFileEx is only called if the profile is using a file integrity database, otherwise [RunBeforeCopyFile](RuntimeScripts.md#function_runbeforecopyfile_toleft__filename__var_todircreated__var_fromfilelocked__var_tofilelocked__var_donecopy__) is called instead.

See also [RunAfterCopyFile](RuntimeScripts.md#procedure_runaftercopyfile_toleft__filename__failed__)

**function RunBeforeDeleteFile(Left, Filename; var FileLocked; var DoneDelete);**

**Left:** True if the left/source file is to be deleted

**Filename:** The file to be deleted (not including the base path)

**FileLocked:** Set to True if the file to be deleted is locked

**DoneDelete:** Set to True if the file was deleted

**Return value:** An error message if the delete failed

This function is called before a file is to be deleted (and before a version has been made). On failure the function should return an error message (do not return an error message if the script is not deleting files). If the file is locked then FileLocked should be returned as True (and an error message should be returned). If the file was deleted then DoneDelete should be returned as True.

Note that once a script has deleted a file then no other scripts will be called to delete the file. This means the order of run-time scripts used in a profile is important. Obviously a file can only be deleted once.

This function is not called if the run is a [simulation](SBRunning.md#property_simulated).

See also [RunAfterDeleteFile](RuntimeScripts.md#procedure_runafterdeletefile_left__filename__failed__)

**function RunBeforeEmailLog(ProfileResult, Failed, Diffs, NoDiffs);**

**ProfileResult:** The [result](ScriptConstants.md#results) of the profile run

**Failed:** True if the profile run had failures

**Diffs:** True if the profile found differences between the left/source and destination/right and the profile is set to email if there are differences

**NoDiffs:** True if the profile found no differences between the left/source and destination/right and the profile is set to email if there are no differences

**Return value:** Return False to not send the email, else return True

This function is called before the log is to be emailed. This gives the script an opportunity to not send the email.

Note this subroutine is not called if the profile is not configured to send the log via email.

The NoDiffs parameter is optional (to remain compatible with pre-V10 scripts).

IMPORTANT: This function is called in the context of the main user interface thread. This means, for example, that the script global variables will not be as expected. Also, SyncBack will retry sending an email if it thinks the email cannot be sent if the attachments are too large. This means this function may be called twice.

**function RunBeforeRenameFile(Left, FromFilename, ToFilename; var ToDirCreated; var FileLocked; var DoneRename);**

**Left:** True if the left/source file is to be renamed

**FromFilename:** The old name of the file (not including the base path)

**ToFilename:** The new name of the file (not including the base path)

**ToDirCreated:** Set to True if the directory for ToFilename was created

**FileLocked:** Set to True if one of the files is locked so cannot be renamed

**DoneRename:** Set to True if the file was renamed

**Return value:** An error message if the rename failed

This function is called before a file is to be renamed. On failure the function should return an error message (do not return an error message if the script is not renaming files). If a directory was created in order to rename the file then ToDirCreated should be returned as TRUE. If one of the files is locked then FileLocked should be returned as TRUE (and an error message should be returned). If the file was renamed then DoneRename should be returned as True.

Note that once a script has renamed a file then no other scripts will be called to rename the file. This means the order of run-time scripts used in a profile is important. Obviously a file can only be renamed once.

This function is not called if the run is a [simulation](SBRunning.md#property_simulated).

See also [RunAfterRenameFile](RuntimeScripts.md#procedure_runafterrenamefile_left__fromfilename__tofilename__failed__)

**function RunBeforeSetAttrs(Left, Filename, useAttrs; var DoneSet);**

**Left:** True if the left/source files attributes are to be changed

**Filename:** The name of the file (not including the base path)

**useDateTime:** The attributes to use

**DoneSet:** Set to True if the files attributes were changed

**Return value:** An error message on failure

This function is called when a files filesystem attributes are going to be changed. On error return an error message (do not return an error message if the script is not changing the files attributes). If the files attributes were changed then DoneSet should be returned as True. It is called only when the action is [CACTION_USE_SRC_DETAILS](ScriptConstants.md#actions) or [CACTION_USE_DEST_DETAILS](ScriptConstants.md#actions), and is not called when a file is copied and its attributes are to be changed, for example.

Note that once a script has set a files attributes then no other scripts will be called to set the files attributes. This means the order of run-time scripts used in a profile is important.

This function is not called if the run is a [simulation](SBRunning.md#property_simulated).

See also [RunAfterSetAttrs](RuntimeScripts.md#procedure_runaftersetattrs_left__filename__useattrs__failed__)

**function RunBeforeSetDateTimes(Left, Filename, ModDateTime, CreateDateTime; var DoneModSet; var DoneCreateSet);**

**Left:** True if the left/source files date & time is to be changed

**Filename:** The name of the file (not including the base path)

**ModDateTime:** The modification date & time to change it to (local timezone). Ignore if <= 1.0.

**CreateDateTime:** The creation date & time to change it to (local timezone). Ignore if <= 1.0.

**DoneModSet:** Set to True if the files modification date & times was changed

**DoneCreateSet:** Set to True if the files creation date & times was changed

**Return value:** An error message on failure

This function is called when a files last modification date & time and/or creation date & time is going to be set. On error return an error message (do not return an error message if the script is not setting the files date & time).

If the files modification date & time was changed then DoneModSet should be returned as True. If the files creation date & time was changed then DoneCreateSet should be returned as True.

It is called only when the action is [CACTION_USE_SRC_DETAILS](ScriptConstants.md#actions) or [CACTION_USE_DEST_DETAILS](ScriptConstants.md#actions), and is not called when a file is copied and its date & time is changed, for example.

Note that once a script has set a files date & time then no other scripts will be called to set the files date & time. This means the order of run-time scripts used in a profile is important.

This function is not called if the run is a [simulation](SBRunning.md#property_simulated).

See also [RunAfterSetDateTimes](RuntimeScripts.md#procedure_runaftersetdatetimes_left__filename__moddatetime__createdatetime__failed__)

**function RunBeforeSetModDateTime(Left, Filename, useDateTime; var DoneSet);**

**Left:** True if the left/source files date & time is to be changed

**Filename:** The name of the file (not including the base path)

**useDateTime:** The date & time to change it to (local timezone)

**DoneSet:** Set to True if the files date & time was changed

**Return value:** An error message on failure

Note that this is a legacy function. You should now use [RunBeforeSetDateTimes](RuntimeScripts.md#function_runbeforesetdatetimes_left__filename__moddatetime__createdatetime__var_donemodset__var_donecreateset__)

This function is called when a files last modification date & time is going to be set. On error return an error message (do not return an error message if the script is not setting the files date & time). If the files date & time was changed then DoneSet should be returned as True. It is called only when the action is [CACTION_USE_SRC_DETAILS](ScriptConstants.md#actions) or [CACTION_USE_DEST_DETAILS](ScriptConstants.md#actions), and is not called when a file is copied and its date & time is changed, for example.

Note that once a script has set a files date & time then no other scripts will be called to set the files date & time. This means the order of run-time scripts used in a profile is important.

This function is not called if the run is a [simulation](SBRunning.md#property_simulated).

See also [RunAfterSetModDateTime](RuntimeScripts.md#procedure_runaftersetmoddatetime_left__filename__usedatetime__failed__)

**function RunDeleteAll(Left, WillDeleteAll);**

**Left:** True if the check is for the Left/Source

**WillDeleteAll:** True if the profile is currently set to delete all

**Return value:** Return False to not delete all, else True to delete all

This function is called before any attempt is made to delete all the files and folders in either the source/left or destination/right.

**function RunDiffColumnHint(Col, IsFile, Filename);**

**Col:** The column number

**IsFile:** True if Filename refers to a file, else it's a folder

**Filename:** The name of the file/folder (not including the base path)

**Return value:** The hint string to display

This subroutine is called from the Differences window when a custom column hint is required. The first custom column is column zero (0). The script is only called for its custom columns and not for columns created by other scripts.

```
function RunDiffColumnHint(Col, IsFile, Filename);
begin
  Result:=Filename;
end;
```

**function RunDiffColumnsCount;**

**Return value:** The number of custom columns, or zero if none are required

This function is called from the Differences window to ask the script how many custom columns it wants created in the Differences window. Note that this value is cached so the function is only called once (when the Differences window appears).

```
fnction RunDiffColumnsCount;
begin
  Result:=2;
end;
```

**function RunDiffColumnSort(Col, IsFile1, IsFile2, Filename1, Filename2);**

**Col:** The column the display is being sorted on

**IsFile1:** True if Filename1 is a file, otherwise it's a folder

**IsFile2:** True if Filename2 is a file, otherwise it's a folder

**Filename1:** The name of a file/folder

**Filename2:** The name of a file/folder

**Return value:** An integer (<0 if file 1 should go before file 2, 0=same filename, > 0 if file 1 should go after file 2)

This function is called from the Differences window when a custom column is being sorted. The first custom column is column zero. The script is only called for its custom columns and not for columns created by other scripts.

Note that sorting can be extremely slow if there are hundreds of thousands of items to sort.

See also [RunDiffColumnsCount](RuntimeScripts.md#function_rundiffcolumnscount_)

**function RunDiffColumnText(Col, IsFile, Filename);**

**Col:** The column number

**IsFile:** True if Filename refers to a file, else it's a folder

**Filename:** The name of the file/folder (not including the base path)

**Return value:** The columns text

This subroutine is called from the Differences window when text for a custom column is required. The first custom column is column zero (0). The script is only called for its custom columns and not for columns created by other scripts.

```
function RunDiffColumnText(Col, IsFile, Filename);
begin
  If (Col = 0) Then
    Result:='Custom Column 1: ' + Filename
  Else
    Result:='Custom Column 2: ' + Filename;
end;
```

See also [RunDiffColumnsCount](RuntimeScripts.md#function_rundiffcolumnscount_)

**function RunDiffColumnTitle(Col; var Width);**

**Col:** The column number

**Width:** Set it to the width the column should be (in pixels)

**Return value:** The columns title

This subroutine is called from the Differences window when the title for a custom column is required. The first custom column is column zero (0). The script is only called for its custom columns and not for columns created by other scripts.

```
function RunDiffColumnTitle(Col, Width);
begin
  if (Col = 0) then begin
    Result:='Custom Column 1';
    Width:=100;
  end else begin
    Result:='Custom Column 2';
    Width:=150;
  end;
end;
```

**function RunDisabledCheck(var NoLog);**

**NoLog:** Set this to TRUE if a log should not be created

**Return value:** A reason why the script should not continue running

This function is called very early on in the profile run and gives the script a chance to stop the profile from running. If the script does not want the profile to run it should return the reason, otherwise it should return an empty string if the profile should continue.

To stop a log file from being produced then set NoLog to True. For example, you may expect certain conditions, e.g. the network being unavailable, and so do not want a log file to be produced.

NOTE: The error message from the profile run indicates the profile is disabled. However, it is not. It is just that run that was disabled (aborted).

```
function RunDisabledCheck(var NoLog);
begin
  NoLog:=FALSE;
  if SBRunning.Restore Then
    Result:='You cannot restore your files'
  else
    Result:='';
end;
```

**function RunEmailLogAttachFilename(Cnt);**

**Cnt:** On the first call this is zero, and then incremented on each call

**Return value:** The filename of the file to attach. The file must exist and be readable.

This function is called when the log file is about to be emailed. It gives the script an opportunity to add custom file attachments to the email.

Note that [RunEmailLogAttachToAdd](RuntimeScripts.md#function_runemaillogattachtoadd_) is called first, and then RunEmailLogAttachFilename() is called the appropriate number of times.

IMPORTANT: This function is called in the context of the main user interface thread. This means, for example, that the script global variables will not be as expected.

See [RunEmailLogAttachToAdd](RuntimeScripts.md#function_runemaillogattachtoadd_) for an example.

**function RunEmailLogAttachToAdd;**

**Return value:** The number of files to attach

This function is called when the log file is about to be emailed. It gives the script an opportunity to add custom file attachments to the email.

Note that RunEmailLogAttachToAdd is called first, and then [RunEmailLogAttachFilename](RuntimeScripts.md#function_runloglocationinfoinfo_left__cnt__) is called the appropriate number of times.

IMPORTANT: This function is called in the context of the main user interface thread. This means, for example, that the script global variables will not be as expected. Also, SyncBack will retry sending an email if it thinks the email cannot be sent if the attachments are too large. This means this function will not be called if it tries resending without attachments.

```
function RunEmailLogAttachToAdd;
begin
  Result:=2;
end;
function RunEmailLogAttachFilename(Cnt);
begin
  If (Cnt = 0) Then
    Result:='c:\path\filename1.txt'
  Else
    Result:='c:\path\filename2.txt';
end;
```

**function RunLogLocationInfoCaption(Left, Cnt);**

**Left:** True is this call is for information on the left/source

**Cnt:** On the first call this is zero, and then incremented on each call

**Return value:** The caption string to use

This function is called when the log file is being created. It gives the script an opportunity to add custom information to the log file about the left/source and/or right/destination locations.

Note that [RunLogLocationInfoToAdd](RuntimeScripts.md#function_runloglocationinfotoadd_left__) is called first, and then RunLogLocationInfoCaption() is called the appropriate number of times.

See [RunLogLocationInfoToAdd](RuntimeScripts.md#function_runloglocationinfotoadd_left__) for an example.

**function RunLogLocationInfoInfo(Left, Cnt);**

**Left:** True is this call is for information on the left/source

**Cnt:** On the first call this is zero, and then incremented on each call

**Return value:** The information string to use

This function is called when the log file is being created. It gives the script an opportunity to add custom information to the log file about the left/source and/or right/destination locations.

Note that [RunLogLocationInfoToAdd](RuntimeScripts.md#function_runloglocationinfotoadd_left__) is called first, and then RunLogLocationInfoInfo is called the appropriate number of times.

See [RunLogLocationInfoToAdd](RuntimeScripts.md#function_runloglocationinfotoadd_left__) for an example.

**function RunLogLocationInfoToAdd(Left);**

**Left:** True if this call is for information on the left/source

**Return value:** The number of caption/info calls to make

This function is called when the log file is being created. It gives the script an opportunity to add custom information to the log file about the left/source and/or right/destination locations.

Note that RunLogLocationInfoToAdd is called first, and then [RunLogLocationInfoInfo](RuntimeScripts.md#function_runloglocationinfoinfo_left__cnt__) is called the appropriate number of times.

```
function RunLogLocationInfoToAdd(Left);
begin
  if Left then
    Result:=2
  else
    Result:=0;
end;
function RunLogLocationInfoCaption(Left, Cnt);
begin
  if Left then begin
    if (Cnt = 0) then
      Result:='Caption 1'
    else
      Result:='Caption 2';
  end else
    Resul:='';
end;
function RunLogLocationInfoInfo(Left, Cnt);
begin
  if Left then begin
    if (Cnt = 0) then
      Resul:='Info 1'
    else
      Resul:='Info 2';
  end else
    Resul:='';
end;
```

**function RunPreCopyCheck;**

**Return value:** A reason why the script should not continue running

This function is called after the files and folders have been compared, and after the Differences window is displayed (if it is to be displayed). It is called before any files are copied, moved, deleted, or renamed, and gives the script a chance to abort the profile, e.g. the script may decide there is not enough free space to copy everything and so abort. If the script does not want the profile to run it should return the reason, otherwise it should return an empty string if the profile should continue.

```
function RunPreCopyCheck;
begin
  if NotEnoughDiskSpace Then
    Result:='There is not enough disk space'
  else
    Result:='';
end;
```

**function RunRunAfterBefore(Filename);**

**Filename:** The full filename and command line parameters of program to be called in Run After

**Return value:** The filename and command line parameters of program to be called in Run After

This function is called before the Run After program is called. It is passed the full and expanded filename (and any command line arguments) that are going to be used, which could be an empty string. This function can decide not to run the program (by returning an empty string) or it could change the string to have a different program be called. If it wants the same program to be called it should return what was passed in Filename.

See also [RunRunAfterAfter](RuntimeScripts.md#procedure_runrunafterafter_filename__returnvalue__returnerrmsg__timedout__) and [RunRunBeforeBefore](RuntimeScripts.md#function_runrunbeforebefore_filename__)

**function RunRunBeforeBefore(Filename);**

**Filename:** The full filename and command line parameters of program to be called in Run Before

**Return value:** The filename and command line parameters of program to be called in Run Before

This function is called before the Run Before program is called. It is passed the full and expanded filename (and any command line arguments) that are going to be used, which could be an empty string. This function can decide not to run the program (by returning an empty string) or it could change the string to have a different program be called. If it wants the same program to be called it should return what was passed in Filename. If an empty string is returned then nothing is run and [RunRunBeforeAfter](RuntimeScripts.md#procedure_runrunbeforeafter_filename__returnvalue__returnerrmsg__timedout__) will not be called.

See also [RunRunBeforeAfter](RuntimeScripts.md#procedure_runrunbeforeafter_filename__returnvalue__returnerrmsg__timedout__) and [RunRunAfterBefore](RuntimeScripts.md#function_runrunafterbefore_filename__)

**function RunShowDiffWindow(WillShow);**

**WillShow:** Is the Differences window going to be displayed?

**Return value:** True if the Differences window should be displayed

Should the Differences window be displayed? Note that this function is not called if the profile run is unattended. In such cases the Differences window is never displayed.

**procedure InitialiseVars(Checking);**

**Checking:** Passed as True if the variables are being checked to see if they exist

This subroutine is called when the variables are initialised. Checking is passed as FALSE. Note that you need to be careful as many things haven't been initialised or created when this is called, e.g. no locations. It is called very early during the profile run (it is called just after [RunDisabledCheck](RuntimeScripts.md#function_rundisabledcheck_var_nolog__) is called).

If you are setting variables then it is recommended you also make your script a Configuration script. This is so the users can see which variables the script sets, and also they can use the variables, e.g. in the source or destination paths.

In the example below the variable MyScriptVar is set to a dummy value if it's a call to check if the variable is valid.

```
//
// Called very early when a profile is run (Checking is False)
// Also called in profile config when asking what variables the script sets (Checking is True)
//
procedure InitialiseVars(Checking);
begin
  if Checking then begin
    // Profile is being saved
    SBVariables.SetVar('MyScriptVar', '?');
  end else begin
    // Profile is being run
    // Do nothing
  end;
end;
```

**procedure RunAfterConfig;**

This function is called very early on in the profile run and gives the script a chance to do any early initialisation work. It is called before any attempt is made to connect to the left/source or destination/right. It is called after [RunBeforeConfig](RuntimeScripts.md#procedure_runbeforeconfig_) and at this point the left/source folder is known, for example.

**procedure RunAfterCopyFile(ToLeft, Filename, Failed);**

**ToLeft:** True if the file was copied from the right/destination

**Filename:** The name of the file (not including the base path)

**Failed:** True if the copy failed

This function is called after a file has been copied. If Failed is True then either the copy failed or the user has aborted. Note that Failed being False does not necessarily mean the file was actually copied, i.e. it does not guarantee a file was created because the location may not actually copy the file, e.g. it may actually simply send it to a printer. What a script location does when it copies a file is beyond SyncBack's control.

This function is not called if the run is a [simulation](SBRunning.md#property_simulated).

See also [RunBeforeCopyFileEx](RuntimeScripts.md#function_runbeforecopyfileex_toleft__filename__var_todircreated__var_fromfilelocked__var_tofilelocked__var_donecopy__var_integrityhash__var_integritytype__) and [RunBeforeCopyFile](RuntimeScripts.md#function_runbeforecopyfile_toleft__filename__var_todircreated__var_fromfilelocked__var_tofilelocked__var_donecopy__)

**procedure RunAfterDeleteFile(Left, Filename, Failed);**

**Left:** True if the left/source file was deleted

**Filename:** The name of the file (not including the base path)

**Failed:** True if the delete failed

This function is called after a file has been deleted. If Failed is True then either the delete failed or the user has aborted. Note that Failed being False does not necessarily mean the file was actually deleted, e.g. it may not have existed.

This function is not called if the run is a [simulation](SBRunning.md#property_simulated).

See also [RunBeforeDeleteFile](RuntimeScripts.md#function_runbeforedeletefile_left__filename__var_filelocked__var_donedelete__)

**procedure RunAfterEmailLog(ErrMsg);**

**ErrMsg:** An error message (if the log could not be sent via email)

This subroutine is called after the log is emailed. If there was a problem sending the email then ErrMsg contains an error message.

Note this subroutine is not called if the profile is not configured to send the log via email.

IMPORTANT: This function is called in the context of the main user interface thread. This means, for example, that the script global variables will not be as expected. Also, SyncBack will retry sending an email if it thinks the email cannot be sent if the attachments are too large. This means this function may be called twice.

**procedure RunAfterFileCompare(Filename, Diff, WhyIgnored; var Action);**

**Filename:** The name of the file (not including the base path)

**Diff:** The differences between the files

**WhyIgnored:** The reason why the file is being ignored (if it is)

**Action:** The [action](ScriptConstants.md#actions) that has been decided upon based on the profiles settings

This function is called after a file is compared. The script can change the [Action](ScriptConstants.md#actions) to something else, or leave it as-is. Note that it is not called for files that are considered identical. Also, the action can only be changed to a valid action. For example, you cannot use CACTION_DELBOTH unless the file is in the source and destination.

See also [RunBeforeFileCompare](RuntimeScripts.md#procedure_runbeforefilecompare_filename__var_skip__)

**procedure RunAfterFolderCompare(Filename; var Action);**

**Filename:** The name of the folder (not including the base path)

**Action:** The [action](ScriptConstants.md#actions) that has been decided upon based on the profiles settings

This function is called after a folder (directory) is compared. The script can change the [Action](ScriptConstants.md#actions) to something else, or leave it as-is.

See also [RunBeforeFolderCompare](RuntimeScripts.md#procedure_runbeforefoldercompare_filename__var_skip__)

**procedure RunAfterRenameFile(Left, FromFilename, ToFilename, Failed);**

**Left:** True if the left/source file was renamed

**FromFilename:** The old name of the file (not including the base path)

**ToFilename:** The new name of the file (not including the base path)

**Failed:** True if the rename failed

This function is called after a file has been renamed. If Failed is True then either the rename failed or the user has aborted. Note that Failed being False does not necessarily mean the file was actually renamed, i.e. it does not guarantee a file was renamed because the location may not actually rename the file. What a script location does when it renames a file is beyond SyncBack's control.

This function is not called if the run is a [simulation](SBRunning.md#property_simulated).

See also [RunBeforeRenameFile](RuntimeScripts.md#function_runbeforerenamefile_left__fromfilename__tofilename__var_todircreated__var_filelocked__var_donerename__)

**procedure RunAfterSetAttrs(Left, Filename, useAttrs, Failed);**

**Left:** True if the left/source files attributes were changed

**Filename:** The name of the file (not including the base path)

**useAttrs:** The attributes that were used

**Failed:** True if the change failed

This function is called after a files filesystem attributes have been changed. It is called only when the action was [CACTION_USE_SRC_DETAILS](ScriptConstants.md#actions) or [CACTION_USE_DEST_DETAILS](ScriptConstants.md#actions), and is not called when a file is copied and its attributes are changed, for example. If Failed is True then either the change failed or the user has aborted. Note that Failed being False does not necessarily mean the files attributes were actually changed.

This function is not called if the run is a [simulation](SBRunning.md#property_simulated).

See also [RunBeforeSetAttrs](RuntimeScripts.md#function_runbeforesetattrs_left__filename__useattrs__var_doneset__)

**procedure RunAfterSetDateTimes(Left, Filename, ModDateTime, CreateDateTime, Failed);**

**Left:** True if the left/source files date & time was changed

**Filename:** The name of the file (not including the base path)

**ModDateTime:** The last modification date & time it was changed to (local timezone). Ignore if <= 1.0.

**CreateDateTime:** The creation date & time it was changed to (local timezone). Ignore if <= 1.0.

**Failed:** True if the change failed

This function is called after a files last modification date & time and/or creation date & time has been changed.

It is called only when the action was [CACTION_USE_SRC_DETAILS](ScriptConstants.md#actions) or [CACTION_USE_DEST_DETAILS](ScriptConstants.md#actions), and is not called when a file is copied and its date & time is changed, for example.

If Failed is True then either the change failed or the user has aborted. Note that Failed being False does not necessarily mean the date & time of the file was actually changed.

This function is not called if the run is a [simulation](SBRunning.md#property_simulated).

See also [RunBeforeSetDateTimes](RuntimeScripts.md#function_runbeforesetdatetimes_left__filename__moddatetime__createdatetime__var_donemodset__var_donecreateset__)

**procedure RunAfterSetModDateTime(Left, Filename, useDateTime, Failed);**

**Left:** True if the left/source files date & time was changed

**Filename:** The name of the file (not including the base path)

**useDateTime:** The date & time it was changed to (local timezone)

**Failed:** True if the change failed

Note that this is a legacy function. You should now use [RunAfterSetDateTimes](RuntimeScripts.md#procedure_runaftersetdatetimes_left__filename__moddatetime__createdatetime__failed__)

This function is called after a files last modification date & time has been changed. It is called only when the action was [CACTION_USE_SRC_DETAILS](ScriptConstants.md#actions) or [CACTION_USE_DEST_DETAILS](ScriptConstants.md#actions), and is not called when a file is copied and its date & time is changed, for example. If Failed is True then either the change failed or the user has aborted. Note that Failed being False does not necessarily mean the date & time of the file was actually changed.

This function is not called if the run is a [simulation](SBRunning.md#property_simulated).

See also [RunBeforeSetModDateTime](RuntimeScripts.md#function_runbeforesetmoddatetime_left__filename__usedatetime__var_doneset__)

**procedure RunBeforeConfig;**

This function is called very early on in the profile run and gives the script a chance to do any early initialisation work. It is called before any attempt is made to connect to the left/source or destination/right. It is called after [RunDisabledCheck](RuntimeScripts.md#function_rundisabledcheck_var_nolog__) and before the profile is prepared. Note that very little is initialised at this point, e.g. there is no left/source folder.

See also [RunAfterConfig](RuntimeScripts.md#procedure_runafterconfig_)

**procedure RunBeforeFileCompare(Filename; var Skip);**

**Filename:** The filename of the file (not including the base path)

**Skip:** Set to True to ignore/skip the file

This subroutine is called before a file is compared for differences. Note that the hash values will be probably empty except for: Fast Backup profiles which may have the destination hash value, and when using compression as the hash value is retrieved from the Zip file.

**procedure RunBeforeFolderCompare(Filename; var Skip);**

**Filename:** The name of the folder (not including the base path)

**Skip:** Set to True to skip this folder

This function is called before a folder (directory) is compared. It gives the script an opportunity to skip a folder (it's action will be set to [CACTION_SKIP](ScriptConstants.md#actions))

See also [RunAfterFolderCompare](RuntimeScripts.md#procedure_runafterfoldercompare_filename__var_action__)

**procedure RunBeforeScanning;**

This function is called just before scanning of the files and folders is about to start.

**procedure RunDiffClosed(Aborted);**

**Aborted:** True if the user decided to abort the profile

This subroutine is called from the Differences window when it is closed. The routine is called before the tree is cleared. It is called even if the user aborted or the tree was empty.

See also [RunDiffOpened](RuntimeScripts.md#procedure_rundiffopened_)

**procedure RunDiffColumnClicked(Col, IsFile, Filename);**

**Col:** The column number

**IsFile:** True if Filename refers to a file, else it's a folder

**Filename:** The name of the file/folder (not including the base path)

This subroutine is called from the Differences window when a custom column is clicked. The first custom column is column zero (0). The script is only called for its custom columns and not for columns created by other scripts.

See also [RunDiffKeyPress](RuntimeScripts.md#procedure_rundiffkeypress_key__shift__isfile__filename__)

**procedure RunDiffFocusChanged(IsFile, Filename);**

**IsFile:** True if Filename refers to a file, else it's a folder

**Filename:** The name of the file/folder (not including the base path)

This subroutine is called from the Differences window when the focused node changes.

**procedure RunDiffKeyPress(Key, Shift, IsFile, Filename);**

**Key:** The key that as pressed

**Shift:** The shift state

**IsFile:** True if Filename refers to a file, else it's a folder

**Filename:** The name of the file/folder (not including the base path)

This subroutine is called from the Differences window when a key is pressed. It is called for each selected row. It is not called if the Delete key is pressed (as that is handled by SyncBack itself).

The Key value refers to the virtual key codes.

The Shift state can be a selection of the following values:

0 = No shift state

ssShift = Shift key is pressed

ssAlt = Alt key is pressed

ssCtrl = Ctrl key is pressed

ssLeft = Left mouse button is pressed

ssRight = Right mouse button is pressed

ssMiddle = Middle mouse button is pressed

ssDouble = Mouse double-clicked

ssTouch = Holding a finger on the touch surface

ssPen = Pen is touching the surface of a tablet

ssCommand = CMD key is held down (only on Mac)

ssHorizontal = User is moving a finger horizontally on the touch surface or is rolling the mouse wheel to produce a horizontal displacement

See also [RunDiffColumnClicked](RuntimeScripts.md#procedure_rundiffcolumnclicked_col__isfile__filename__)

```
// This example says the filename if S is pressed
procedure RunDiffKeyPress(Key, ShiftState, IsFile, Filename);
begin
  If (Key = 83) Then
    SBSystem.Say(Filename);
end;
```

**procedure RunDiffOpened;**

This subroutine is called from the Differences window when it is opened and displayed. The routine is called after the tree has been loaded and sorted. Note that if the user aborts the loading of the Differences window, or the tree is empty and the profile is configured to close the Differences window automatically if empty, then this routine is not called.

See also [RunDiffClosed](RuntimeScripts.md#procedure_rundiffclosed_aborted__)

**procedure RunDoFullBackup(LeftDir, RightDir; var FullBackup);**

**LeftDir:** The base directory of the left/source

**RightDir:** The base directory of the right/destination

**FullBackup:** True if this is a full backup run. Change as required.

This function is called when a decision must be made on whether the profile run should be a full backup or an incremental/differential backup.

Note that once a script has decided on wheter it is a full backup or not then no other scripts will be called to decide. This means the order of run-time scripts used in a profile is important.

See also [FullBackup](SBRunning.md#property_fullbackup)

**procedure RunFileCompareDiff(Filename, Diff, WhyIgnored; var Skip);**

**Filename:** The filename of the file (not including the base path)

**Diff:** The differences between the files

**WhyIgnored:** The reason why the file is being ignored (if it is)

**Skip:** Set to True to ignore/skip the file

This subroutine is called after a file has been compared for differences and the left/source and right/destination files are different.

**procedure RunFileCompareSame(Filename; var Diff);**

**Filename:** The filename of the file (not including the base path)

**Diff:** Set to the difference between the files, or CDIFF_IDENTICAL

This subroutine is called after a file has been compared for differences and the left/source and right/destination files are considered, based on the profile settings, to be identical. This can be used, for example, by a script to make further comparisons and change it to not be identical.

This function is deprecated and RunFileCompareSameEx should be used instead. If you have [RunFileCompareSameEx](RuntimeScripts.md#procedure_runfilecomparesameex_filename__whyignored__var_diff__) defined then that will be called instead.

**procedure RunFileCompareSameEx(Filename; WhyIgnored; var Diff);**

**Filename:** The filename of the file (not including the base path)

**WhyIgnored:** The reason the file was ignored (TIgnoreReason)

**Diff:** Set to the difference between the files, or CDIFF_IDENTICAL

This subroutine is called after a file has been compared for differences and the left/source and right/destination files are considered, based on the profile settings, to be identical. This can be used, for example, by a script to make further comparisons and change it to not be identical.

This function was added in SyncBackPro V12.

**procedure RunLogClosing(ProfileStatus);**

**ProfileStatus:** 0 = success, >=1 means profile failed, else unknown

This function is called when logging is ending and the log file is about to be closed.

See also [RunLogOpening](RuntimeScripts.md#procedure_runlogopening_logformat__filename__folder__appending__)

This script function was introduced in V12.

**procedure RunLogException(ExceptionReport);**

**ExceptionReport:** The exception report (which can be several kilobytes in length)

This function is called when SyncBack encounters an exception. As exception reports can be very large, and an exception can trigger cascades of exceptions (e.g. if out of memory) then only the first 10 exceptions are logged.

This script function was introduced in V12.

**procedure RunLogIgnoreReason(FileStatus, ListFilename, ActualFilename, Reason);**

**FileStatus:** See [TLogFileStatus](ScriptConstants.md#tlogfilestatus)

**ListFilename:** The list filename (may be blank). This is the relative filename.

**ActualFilename:** The actualy (full) filename.

**Reason:** The reason the file was ignored (see [IgnoredReason](ScriptConstants.md#ignoredreason))

This function is called when an entry is added to the log file in regards to a file being ignored.

See also [RunLogStatus](RuntimeScripts.md#procedure_runlogstatus_filestatus__listfilename__actualfilename__status__)

This script function was introduced in V12.

**procedure RunLogOpening(LogFormat, Filename, Folder, Appending);**

**LogFormat:** The format of the log file ([TLogFormat](ScriptConstants.md#tlogformat))

**Filename:** The expanded filename of the log file (note that if page

**Folder:** The expanded folder name where the log file will go

**Appending:** TRUE is appending

This function is called when logging begins. It is called even if no log files are being created.

See also [RunLogClosing](RuntimeScripts.md#procedure_runlogclosing_profilestatus__) and also variables such as %LOGERRORSCNT%

This script function was introduced in V12.

numbers are used then the page number variable %PAGE% is not expanded)

**procedure RunLogStatus(FileStatus, ListFilename, ActualFilename, Status);**

**FileStatus:** See [TLogFileStatus](ScriptConstants.md#tlogfilestatus)

**ListFilename:** The list filename (may be blank). This is the relative filename.

**ActualFilename:** The actualy (full) filename.

**Status:** The success, error or warning message.

This function is called when an entry is added to the log file.

See also [RunLogIgnoreReason](RuntimeScripts.md#procedure_runlogignorereason_filestatus__listfilename__actualfilename__reason__)

This script function was introduced in V12.

**procedure RunProfileResult(ProfileResult, ErrMsg);**

**ProfileResult:** The [result](ScriptConstants.md#results) of the profile run

**ErrMsg:** If a fatal error occurred, this is the error message

This function is called when the result of the profile run is known and has been saved. It is usually done before the profile finishes. For example:

```
procedure RunProfileResult(ProfileResult, ErrMsg);
begin
  SBRunning.DebugOut(ProfileResult, ErrMsg, 1);
end;
```

**procedure RunRunAfterAfter(Filename, ReturnValue, ReturnErrMsg, TimedOut);**

**Filename:** The full filename and command line parameters of program called in Run After

**ReturnValue:** The numeric return value of the program

**ReturnErrMsg:** If the program could not be run then this is the error message

**TimedOut:** If the program timed out then this is TRUE

This function is called after the Run After program has been called. It is passed the full and expanded filename (and any command line arguments) that were used. If there was a problem running the program then ReturnErrMsg will contain an error message. RetVal will contain the numeric return value from the program, but note that this value should be ignored if the program failed to run, if TimedOut is TRUE, or if the profile was not configured to wait for the program to finish. TimedOut is TRUE if the program took too long to run.

See also [RunRunBeforeAfter](RuntimeScripts.md#procedure_runrunbeforeafter_filename__returnvalue__returnerrmsg__timedout__) and [RunRunAfterBefore](RuntimeScripts.md#function_runrunafterbefore_filename__)

**procedure RunRunBeforeAfter(Filename, ReturnValue, ReturnErrMsg, TimedOut);**

**Filename:** The full filename and command line parameters of program called in Run Before

**ReturnValue:** The numeric return value of the program

**ReturnErrMsg:** If the program could not be run then this is the error message

**TimedOut:** If the program timed out then this is TRUE

This function is called after the Run Before program has been called. It is passed the full and expanded filename (and any command line arguments) that were used. If there was a problem running the program then ReturnErrMsg will contain an error message. RetVal will contain the numeric return value from the program, but note that this value should be ignored if the program failed to run, if TimedOut is TRUE, or if the profile was not configured to wait for the program to finish. TimedOut is TRUE if the program took too long to run. If [RunRunBeforeBefore](RuntimeScripts.md#function_runrunbeforebefore_filename__) returned an empty string then this procedure is not called.

See also [RunRunBeforeBefore](RuntimeScripts.md#function_runrunbeforebefore_filename__) and [RunRunAfterAfter](RuntimeScripts.md#procedure_runrunafterafter_filename__returnvalue__returnerrmsg__timedout__)

All Content: 2BrightSparks Pte Ltd © 2003-2026
