Automating the Process of Getting Latest Files from VSS


One fine day, my PSM (Project manager); irritated with taking backups manually, asked me to write a utility for automatically taking the backup of our VSS server.

Well, that was it when I wrote this.

In this article, I will show you how to write an automated process of taking VSS backup. Initially, this application was written with some hard coded settings such as user name, password. and VSS path. I have changed these setting now. Users can specify the settings in the config file.  application. 

So, lets start with, what we are interested in.

  1. The application uses the following namespaces. Well, I dont think anyone would require explanation for these namespaces.

    using System.Configuration;
    using
    SourceSafeTypeLib;
    using
    System.Web;
    using
    System.Web.Mail;

  2. There is a class variable declared in the application for the VSS database. The VSSDatabase property represents an instance of a Visual SourceSafe database.

    private static VSSDatabaseClass VSSDatabase = new VSSDatabaseClass();

  3. Lets move directly to the main method. While still in incipient stage of developing this application, I thought of simply copying the VSS directories from our server to another machine. So, I scribbled a batch file for doing just that. But, then the idea was dropped (because of the lamentations of the programmer inside me). Anyway, thats why there is an If clause in the main method. Well talk about the method for copying the files from the VSS.

    static void Main(string[] args) 

    if (ConfigurationSettings.AppSettings[  "getlatestmethod"].ToString().Equals("1"))
    {
    getProjects();
    }
    else
    {
    string filepath=ConfigurationSettings.AppSettings["BatchFilePath"];
    System.Diagnostics.Process.Start(filepath ,"Backup_" + DateTime.Today.ToString("dd-MM-yyyy"));
    }
    }

  4. The method getProjects() is invoked from the main method of the application. This is the method that starts the VSS backup. Now, here is the method. Ofcourse, we would require vsspath, username, password and the path to the directory, where we want the backup. Once it is done, the connection is made with the VSS. The root project in the vss (from which the Backup starts) is retrieved from the VSS.

  5. The Get method of the VSSItem is used to get files from the database. This method accepts two parameters:

    Local: This optional parameter is a string value set to the complete local path to which you want to get the file. This path includes the file name that you wish to get. The default for this parameter is the LocalSpec of the VSSItem file item.

    iFlags: This optional parameter holds any flag settings you want applied to the Get event. The default for this parameter is 0. The Get method may be called against both file and project objects. When called against a project, all files in the project are gotten regardless of their CheckOut status.

  6. If the items in the specified directory are of the Project type, another method {getfiles()} is called for getting its items. In case of an error , the program halts. In case, the operation is successful, a mail is sent to the user (as specified in the config file). Now, this option of sending the mail can be turned off(in case ,you dont have the SMTS service running on your machine) by commenting the call to the sendmail method.

    Private static void getProjects()
    {
    string rootdir = ConfigurationSettings.AppSettings["copytofolder"] + "\\Backup_" + DateTime.Today.ToString("dd-MM-yyyy");
    string rootproject = ConfigurationSettings.AppSettings["vssproject"];
    string vssIni=ConfigurationSettings.AppSettings["vsspath"];
    string user=ConfigurationSettings.AppSettings["user"];
    string pwd=ConfigurationSettings.AppSettings["pwd"];
    string copydir= rootdir;
    /// <summary>
    /// This is the variable for holding the reference to the VSS Item (or folders).
    ///
    /// </summary>
    VSSItem Item;
    try
    {
    VSSDatabase.Open(@vssIni , user , pwd);
    Item = VSSDatabase.get_VSSItem(rootproject,
    false);
    Item.Get(
    ref rootdir,0);
    foreach (VSSItem VSSItem1 in Item.get_Items(false))
    {
    Console.WriteLine(VSSItem1.Name.ToString());
    if (VSSItem1.Type == (int)VSSItemType.VSSITEM_PROJECT)
    {
    copydir = rootdir + "\\" + VSSItem1.Name.ToString();
    VSSItem1.Get(
    ref copydir,0);
    string ChildProjectPath = VSSItem1.Spec + "/";
    getFiles(ChildProjectPath,copydir);
    }
    }
    }
    catch(Exception ex)
    {
    System.Diagnostics.EventLog.WriteEntry("BackupApplication","Error occured while opening database or connecting to the project" + ex.Message.ToString(),System.Diagnostics.EventLogEntryType.Error);
    //SendMail(" with Failure");
    }
    SendMail(" Successfully");
    }

  7. Now, something about the getfiles method. This is the recursion method for getting all the child items (files and folders) from the VSS. This method gets the items into the local (on the machine) folders, and then again invokes itself with the path of the next child for getting the files. This method returns back after all the children of the given project (or folder) are taken from the VSS.

    /// <summary>
    /// This is the recursion method for doing the getlatest of the files. The path passed from the parent is used for further drilling down of the folders. Each project type item is picked up and it's files are taken from the VSS using the get() method. Once this is done, the path of the current project is passed to this method again so as to find out it's childs.
    /// </summary>
    private static void getFiles(string itemname,string copydir)
    {
    string copydirlocal;
    VSSItem ItemChild = VSSDatabase.get_VSSItem(itemname,
    false);
    foreach (VSSItem VSSItem1 in ItemChild.get_Items(false))
    {
    Console.WriteLine(VSSItem1.Spec.ToString());
    if (VSSItem1.Type == (int)VSSItemType.VSSITEM_PROJECT)
    {
    copydirlocal = copydir + "\\" + VSSItem1.Name.ToString();
    VSSItem1.Get(
    ref copydirlocal,0);
    string ChildProjectPath = VSSItem1.Spec + "/";
    getFiles(ChildProjectPath,copydirlocal);
    }
    }
    }
    <!--The following entries are for the VSS get latest program -->
    <add key="user" value="admin" /> <!--user name for vss account-->
    <add key="pwd" value="badgering" /> <!--password for vssaccount-->
    <!--Vss location-->
    <add key="vsspath" value="\\1016-gf-athena\PrpslGnrtr\srcSafe.ini" />
    <!--vss folder, (from where the files are needed)-->
    <add key="vssproject" value="$/Dynamic/code\treeview/bin" />    
    <!--local folder for getting the files-->
    <add key="copytofolder" value="f:\\xxx" />

  8. Before running the application, there are some settings that need to be changed in the app.config file.

  9. Well, thats it about the application. This utility can be scheduled using the scheduler in the windows.

Comments: Well, I intend to create the setup project for this utility. This setup would prompt the user for all the parameters (like username, password, VSS location, Destination etc.). This would obviate the user from making manual changes to the config file. I hope this helps a few programmers who intend to venture into the VSS automation.