Click here to Skip to main content
15,885,882 members
Articles / Operating Systems / Windows

An Autoit Program for Automatic BackUp and Encryption of Files

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
15 Jan 2018CPOL3 min read 11K   129   8   4
A program for automatic backup with possibly encrypt

Image 1

Introduction

This is the third article on the use of some advanced features of the Autoit[1] language for receiving notifications from the Operating System (OS) on writing files and to be able to make a copy of these (possibly encrypted).

The previous articles deal with the use of COM (Component Object Model) objects, the first shows how to grab data from an MSWord document by COM objects for MSWord and send them to an internet application using WinHttpRequest COM object which implements the Ajax protocol; the second besides the COM objects for MSWord uses properties and methods of the COM objects for Power Point.

Steps to Receive Notifications from the File System

(See also the article of Thomas Caudal Shell Notifications in C#)

  • Register a message, this should be a string unique in the system:
    Local $iMsg = _WinAPI_RegisterWindowMessage('CHANGENOTIFY')
  • Associates the message with an Autoit function:
    GUIRegisterMsg($iMsg, 'WM_CHANGENOTIFY') ; the message is associated to function WM_CHANGENOTIFY
  • Registers a window that receive notifications from the file system:
    $g_iID = _WinAPI_ShellChangeNotifyRegister($hWnd,$iMsg,$SHCNE_ALLEVENTS,BitOR($SHCNRF_INTERRUPTLEVEL, $SHCNRF_SHELLLEVEL, $SHCNRF_RECURSIVEINTERRUPT), $Path)

The program below is a step to develop the program BackUp object of this article; I used it to test the operation in the case of several contemporary folders.

VB.NET
#include <APIShellExConstants.au3>
#include <WinAPI.au3>
#include <WinAPIShellEx.au3>
#include <GUIConstantsEx.au3>
Opt('TrayAutoPause', 0)
OnAutoItExitRegister('Deregister')
Global $hWnd = GUICreate("Try change on folders", 400, 300)
GUISetState(@SW_SHOW, $hWnd)
Global $ID1 = Guard("D:\Condor", 1)
Global $ID2 = Guard("C:\www", 2)
While 1
	If GUIGetMsg() = $GUI_EVENT_CLOSE Then ExitLoop
WEnd
Func Guard($path, $indx)
	$Message = 'CHANGENOTIFY' & $indx
	Local $iMsg = _WinAPI_RegisterWindowMessage($Message)
	GUIRegisterMsg($iMsg, 'WM_CHANGENOTIFY') ; the message is associated to function WM_CHANGENOTIFY
	;	local $g_iID = _WinAPI_ShellChangeNotifyRegister_
        ($hWnd,$iMsg,  $SHCNE_ALLEVENTS, BitOR($SHCNRF_INTERRUPTLEVEL, $SHCNRF_SHELLLEVEL, _
         $SHCNRF_RECURSIVEINTERRUPT), $Path, true)
	Local $g_iID = _WinAPI_ShellChangeNotifyRegister($hWnd, $iMsg, $SHCNE_UPDATEITEM, _
         BitOR($SHCNRF_INTERRUPTLEVEL, $SHCNRF_SHELLLEVEL, $SHCNRF_RECURSIVEINTERRUPT), $path)
	If @error Then
		MsgBox(BitOR($MB_ICONERROR, $MB_SYSTEMMODAL), 'Error', 'Window does not registered.')
		Exit
	EndIf
	Return $g_iID
EndFunc   ;==>Guard
Func WM_CHANGENOTIFY($hWnd, $iMsg, $wParam, $lParam)
	#forceref $hWnd, $iMsg
	Local $sPath = _WinAPI_ShellGetPathFromIDList(DllStructGetData(DllStructCreate
                   ('dword Item1; dword Item2', $wParam), 'Item1'))
	If $SHCNE_UPDATEITEM = $lParam Then ConsoleWrite($sPath & " writed" & @CRLF)
EndFunc   ;==>WM_CHANGENOTIFY
Func Deregister()
	ConsoleWrite("Deregister" & @CRLF)
	If $ID1 Then _WinAPI_ShellChangeNotifyDeregister($ID2)
	If $ID2 Then _WinAPI_ShellChangeNotifyDeregister($ID2)
EndFunc   ;==>Deregister

The Backup Program

As already anticipated in the overlying introduction, the script deals with automatic backup of files when they are modified: a form permits to choose the file(s) to guard, where to backup and a possible encrypt of the copy; this last option is for those who do not trust the storage of their data on the cloud.

Some clarifications on the data and on the operation of the program:

  • The buttons of the form are associated with the functions invoked with the pressure of the same
  • The data in the form is accessible through a dictionary where the key is the name associated to a control, for example, the name of the backup folder is Folder;
  • Finally, every file to watch is stored in a dictionary where the key is fileName to backup (with path) and the value is an array containing:
    • the origin folder
    • the backup file (complete path)
    • the possible encryption password
    • the handle returned by _WinAPI_ShellUPDATENOTIFYRegister
    • the fileName

When the button Guard is pressed, the code below is executed:

VB.NET
Func genGuard($data)
	Local $sDrive = "", $sDir = "", $sExtension = "", $Path = "", $file = ""
	$psw = $data.item("Password")
	$fileToGuard = $data.item("File")
	Local $aPathSplit = _PathSplit($fileToGuard, $sDrive, $Path, $File, $sExtension)
	$destFolder = $data.item("Folder")
	if StringRight($destFolder,1) <> "\" then $destFolder = $destFolder & "\"
	$Path = $sDrive & $Path
	Local $dataFile[] = [$Path,$destFolder,$psw, 0,$File & $sExtension]
	if $data.item("runProgram") = "1" Then ShellExecute($data.item("File"),@SW_MAXIMIZE)
	if isNewFolder($Path) Then
		Local $iMsg = _WinAPI_RegisterWindowMessage('UPDATENOTIFY' & $fileDict.count)
		GUIRegisterMsg($iMsg, 'WM_UPDATENOTIFY')	; the message is associated to _
                                function WM_UPDATENOTIFY
		$dataFile[3] =  _WinAPI_ShellChangeNotifyRegister($data.item("fg_winhandle"), _
						$iMsg, _
						$SHCNE_UPDATEITEM, _	; guard update file system
						BitOR($SHCNRF_INTERRUPTLEVEL, $SHCNRF_SHELLLEVEL, $SHCNRF_RECURSIVEINTERRUPT), _
						$Path)
		If @error Then
			MsgBox(BitOR($MB_ICONERROR, $MB_SYSTEMMODAL),'Error','Window does not registered.')
			Exit
		EndIf
	EndIf
	ConsoleWrite("Folder " & $path & " guarded" & @CRLF)
	$fileDict.Item($fileToGuard) = $dataFile
EndFunc

For every folder to guard must be created a new message by the function _WinAPI_RegisterWindowMessage, this is achieved by creating a message with a constant part and a variable number: 'UPDATENOTIFY' & $fileDict.count.

The file can be opened if the Check Box runProgram is checked by its associated program through the function ShellExecute.

With the function _WinAPI_ShellChangeNotifyRegister, the program tells the Operating System (OS) to call the function WM_UPDATENOTIFY when the event $SHCNE_UPDATEITEM[2] i.e., an update on the folder $Path occurs.

When the event occurs, the OS calls the function WM_UPDATENOTIFY:

VB.NET
Func WM_UPDATENOTIFY($hWnd, $iMsg, $wParam, $lParam)
	#forceref $hWnd, $iMsg
	Local $sPath = _WinAPI_ShellGetPathFromIDList(DllStructGetData_
                   (DllStructCreate('dword Item1; dword Item2', $wParam), 'Item1'))
	If $sPath Then
		if $fileDict.Exists($sPath) Then		; a file has been updated
			Local $dataFile = $fileDict.Item($sPath)
			If $dataFile[2] = "" Then		; there is a password?
				FileCopy($sPath,$dataFile[1], $FC_OVERWRITE + $FC_CREATEPATH)
			Else
				_Crypt_EncryptFile($sPath, $dataFile[1] & $dataFile[4], _
                              $dataFile[2],$CALG_AES_192)	; Encrypt the file.
				If @error <> 0 Then
					consoleWrite("Error when encrypting: " & @error & @CRLF)
				EndIf
			EndIf
			consoleWrite($sPath & " saved")
			if $dataFile[2] <> "" Then ConsoleWrite(" and encrypted")
			ConsoleWrite(@CRLF)
		EndIf
	EndIf
EndFunc   ;==>WM_UPDATENOTIFY

If the event is related to a file under control, this is copied to the backup folder or it is copied encrypted[3] if there is a keyword.

Other Features of the Program

I added a subform to recover the encrypted files and in the menu, under File, the sub menu Show guarded which shows the files currently under control:

VB.NET
...
	& "BL,Restore,Restore,,,Restore the file,Restore;" _
	& "Menu,File,&File;" _
	& "SubMenu,Showguard,&Show guarded,Showguard;" _
...
Func showGuard()
	$aDict = getIniFormat($fileDict)
	Local $iOrgWidth = 500, $iHeight = 300
	Local $hGUI = GUICreate("Files on guard", $iOrgWidth, $iHeight)
	Local $aiGUISize = WinGetClientSize($hGUI)
	Local $idListview = GUICtrlCreateListView(StringFormat_
           ("File   %40s |Folder %40s |Encript key","",""), 10, 10, 480, 240)
	For $i=1 to $aDict[0][0]
		$a = $aDict[$i][1]
		Local $idItem = GUICtrlCreateListViewItem_
           ($aDict[$i][0] & "|" & $a[1] & "|"  & $a[2],$idListview)
	Next
	GUISetState(@SW_SHOW, $hGUI)
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch
    WEnd
	GUIDelete()
EndFunc
Func Restore($data)
	$psw = $data.item("PasswordR")
	$fileToRestore = $data.item("FileR")
	Local $sDrive = "", $sDir = "", $sExtension = "", $Pth = "", $file
	Local $aPathSplit = _PathSplit($fileToRestore, $sDrive, $Pth, $File, $sExtension)
	$File = $File & $sExtension
	$destFile = $data.item("FolderR")
	if StringRight($destFile,1) <> "\" then $destFile = $destFile & "\"
	$destFile = $destFile & $File
	if $psw = "" Then
		FileCopy($fileToRestore,$destFile, $FC_OVERWRITE + $FC_CREATEPATH)
	Else
		_Crypt_DecryptFile($fileToRestore, $destFile, $psw,$CALG_AES_192)	; Decrypt the file.
	EndIf
	msgbox(0,"Restore",$fileToRestore,1.5)
	ConsoleWrite("Restored file " & $fileToRestore & " from " & $Pth & @CRLF)
EndFunc

Notes

  1. ^AutoIt is a free-ware BASIC-like scripting language, an alternative to PowerShell, designed in origin for automating the interaction with Windows GUI. AutoIt can run on Windows interpreted or compiled. It comes with many libraries that enable, among other things, access COM objects and create graphical interfaces; those task are greatly enhanced by the rich Help with examples.
  2. ^In the documentation we can find a list of all events, in particular $SHCNE_ALLEVENTS matches all events.
  3. ^I used the AES (192bit) algorithm but AutoIt supports some others that can be found in the documentation.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Condor Informatique
Italy Italy
Computer literacy (software) : Languages: PHP, Javascript, SQL Autoit,Basic4Android; Frameworks: JOOMLA!
Teaching/Training skills on Office, WEB site development and programming languages.
Others : WEB site development.
UNDP Missions
feb – may 2003 Congo DR Bukavu: ground IT computer course
nov 2003 Burundi Bujumbura: Oracle Data Base course
feb 2005 Burundi Bujumbura: JAVA course
mar 2005 Mali Kati: MS Office course
oct 2006 Mali Kati: MS Office course
jun 2006 Burkina Faso Bobo Dioulasso: MS Office course
jun 2007 Burkina Faso Bobo Dioulasso: MS Office course
may 2007 Argentina Olavarria hospital: Internet application for access to medical records
apr 2008 Burkina Faso Ouagadougou: MS ACCESS and dynamic Internet applications
jun 2008 Niger Niamey: analysis of the computing needs of the Niamey hospital
may 2009 Burkina Faso Ouagadougou: MS ACCESS and dynamic Internet applications
oct 2010 Niger Niamey: analysis of the computing needs of the Niamey hospital (following)
Region Piedmont project Evaluation
mar 2006 Burkina Faso, Niger
mar 2007 Benin, Burkina Faso, Niger
sep 2008 Benin, Burkina Faso, Niger
Others
feb 2010 Burundi Kiremba hospital: MS Office course
feb 2011 Congo DR Kampene hospital: MS Office course

Comments and Discussions

 
QuestionLanguage Pin
Michael Haephrati15-Jan-18 11:38
professionalMichael Haephrati15-Jan-18 11:38 
AnswerRe: Language Pin
Jim Meadors16-Jan-18 15:54
Jim Meadors16-Jan-18 15:54 
AnswerRe: Language Pin
Michael Haephrati17-Jan-18 4:39
professionalMichael Haephrati17-Jan-18 4:39 
GeneralRe: Language Pin
Jim Meadors17-Jan-18 16:27
Jim Meadors17-Jan-18 16:27 
Thumbs Up | :thumbsup: Smile | :)

<sig notetoself="think of a better signature">
<first>Jim</first> <last>Meadors</last>
</sig>

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.