Click here to Skip to main content
Click here to Skip to main content

How to quickly improve and optimze the backup of your company

, 1 Jun 2007
Rate this:
Please Sign up or sign in to vote.
This project shows a technique to archive old files and to optimize the backup of your company.

Screenshot - img.jpg

Introduction

This sample project shows a technique to programmatically reduce the storage size of a full file system and to archive older files to a different location. In the last few years, the number of files used by a company has exponentially grown. This has been caused by many factors, first of all the diffusion of email as a vehicle of any sort of document. The documents are written, corrected, reviewed, published, and sometimes inserted in a knowledge base and often they get forgotten. During this process, many copies are stored on a file system and then backed up. A lot of these documents, after being published, get "dead": they are archived, and accessed only for reading. Archive systems are based on an access ranking. While the document is still reviewed, it must be quickly accessible and updateable and backed up daily. Once the file gets archived, it could be marked as read-only and it could not be backed up often.

Background

Screenshot - FS.jpg

Using the code

Firstly, it is necessary to identify which files and which directory contains the archived documents and then it is necessary to define after how much time the documents can be moved in to the archive storage. After this process, the document is moved to a different location (store or server) and it is substituted with a shortcut. The form has two radio buttons where the user can choose if the archiving process works on files older than a specific date rather than a number of months. The user must also select the root directory, where the process starts, and the destination archive directory. You must pay attention because the destination directory is used as the "destination path" in the shortcuts, hence it must be a location accessible to all users that could see the shortcuts. The better choice is to use an UNC path which points to a share. By checking "Analysis only", you can only preview the results. This feature inserts into a JET database all files which would be archived, so the user can preview how much storage will be freed by the process.

Try it

In the project directory, there are two sample directories: "SOURCE FOLDER" and "ARCHIVE FOLDER". The source folder contains the sample files. Make sure that the archive folder is shared and is accessible for reading and writing from "\\127.0.01\archive folder". Run the project and select today as the specific date. After executing the archive process, you can view the text file that has been moved to the archive folder, and in the source directory, it has been replaced by a shortcut pointing to "\\127.0.0.1\archivefolder\text document.txt".

Points of interest

The main process is performed by the function ArchiveFile which take an input parameter of type FileInfo. This function checks if the input file is older enough to be archived, if so, builds the new path, moves the file in to the new location, and creates the shortcut.

Private Sub ArchiveFile(ByVal fi As FileInfo)

    Dim d As Date
    'Check the date limit

    If Me.RadioButton1.Checked Then
        d = Me.DateTimePicker1.Value
    Else
        d = Date.Now.AddMonths(-CInt(Me.TextBox3.Text))
    End If

    'check the last modification

    If fi.LastWriteTimeUtc < d Then
        Dim sf As String = fi.FullName
        Dim df As String = Me.dest_path.FullName

        'remove the start path.

        sf = sf.Remove(0, Me.start_path.FullName.Length)
        'Append relative path to root destination

        df += sf

        Dim nfi As FileInfo
        nfi = New FileInfo(df)
        'Check if destination path exists, else create it

        Dim ndi As DirectoryInfo = New DirectoryInfo(nfi.DirectoryName)
        If Not ndi.Exists Then
            ndi.Create()
        End If

        'archive process

        Dim oldfi As FileInfo
        Try
            'Save the old position

            oldfi = New FileInfo(fi.FullName)
            'Move to archive directory

            fi.MoveTo(df)
            Debug.WriteLine("Archived: " & nfi.FullName)
            'Mark as readonly

            fi.Attributes = fi.Attributes And Not FileAttributes.ReadOnly
            'create the shortcut 

            Me.CreateShortCut(oldfi, fi)

        Catch ioex As System.IO.IOException
            'Don't stop on error

            Debug.WriteLine(ioex.Message)

        End Try

    End If
End Sub

Private Sub CreateShortCut(ByVal fi As FileInfo, ByVal tfi As FileInfo)
    m_Shortcut = New ShellShortcut(fi.DirectoryName & "\" & fi.Name & ".lnk")
    With m_Shortcut
        .Path = tfi.FullName
        .WorkingDirectory = tfi.DirectoryName
        .Description = ""
        .WindowStyle = ProcessWindowStyle.Normal
        .Save()
    End With

    fi = New FileInfo(fi.DirectoryName & "\" & fi.Name & ".lnk")
    fi.Attributes += FileAttributes.ReadOnly
End Sub

Another interesting point is the class ShellShortcut that allows the creation of system shortcuts which use a wrapper class to the WinAPI.

'
' .NET friendly wrapper for the ShellLink class
'

Public Class ShellShortcut
    Implements IDisposable

    Private Const INFOTIPSIZE As Integer = 1024
    Private Const MAX_PATH As Integer = 260

    Private Const SW_SHOWNORMAL As Integer = 1
    Private Const SW_SHOWMINIMIZED As Integer = 2
    Private Const SW_SHOWMAXIMIZED As Integer = 3
    Private Const SW_SHOWMINNOACTIVE As Integer = 7


#If [UNICODE] Then
    Private m_Link As IShellLinkW
#Else
    Private m_Link As IShellLinkA
#End If
    Private m_sPath As String

    '
    ' linkPath: Path to new or existing shortcut file (.lnk).
    '

    Public Sub New(ByVal linkPath As String) […]

    Public Sub Dispose() Implements IDisposable.Dispose

    '
    ' Gets or sets the argument list of the shortcut.
    '

    Public Property Arguments() As String […]

    '
    ' Gets or sets a description of the shortcut.
    '

    Public Property Description() As String […]

    '
    ' Gets or sets the working directory
    ' (aka start in directory) of the shortcut.
    '

    Public Property WorkingDirectory() As String […]

    '
    ' Gets or sets the target path of the shortcut.
    '

    Public Property Path() As String […]

    '
    ' Gets or sets the path of the Icon assigned to the shortcut.
    '

    Public Property IconPath() As String […]

    '
    ' Gets or sets the index of the Icon assigned to the shortcut.
    ' Set to zero when the IconPath property specifies a .ICO file.
    '

    Public Property IconIndex() As Integer […]

    '
    ' Retrieves the Icon of the shortcut as it will appear in Explorer.
    ' Use the IconPath and IconIndex properties to change it.
    '

    Public ReadOnly Property Icon() As Icon […]

    '
    ' Gets or sets the System.Diagnostics.ProcessWindowStyle value
    ' that decides the initial show state of the shortcut target. Note that
    ' ProcessWindowStyle.Hidden is not a valid property value.
    '

    Public Property WindowStyle() As ProcessWindowStyle […]

    '
    ' Gets or sets the hotkey for the shortcut.
    '

    Public Property Hotkey() As Keys […]

    '
    ' Saves the shortcut to disk.
    '

    Public Sub Save()[…]

    '
    ' Returns a reference to the internal ShellLink object,
    ' which can be used to perform more advanced operations
    ' not supported by this wrapper class, by using the
    ' IShellLink interface directly.
    '

    Public ReadOnly Property ShellLink() As Object […]

End Class

Notice

This technique works if nobody moves the archived folder or if nobody changes the file system structure or, again, if nobody deletes the files or the shortcuts. To prevent these issues, I've set (manually) ACEs on files and directories with these restrictions.

Improvements

I think that this tool can be modified to become windowless and take the parameters from an XML configuration file. It can manage several tasks, each one for a specific directory. So, it can manage: directory1, only files not modified since 6 months ago. directory2, only files not modified since 12 months ago. And so on... This way, it can be scheduled weekly or monthly.

License

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

About the Author

FrankNight
CEO Gekoproject.com
Italy Italy
No Biography provided

Comments and Discussions

 
Question? Pinmemberjames11156782-Jun-07 23:11 

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

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

| Advertise | Privacy | Mobile
Web03 | 2.8.140721.1 | Last Updated 1 Jun 2007
Article Copyright 2007 by FrankNight
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid