July 7, 2010

Ad-Hoc Build – Zip – Rename – Deploy ‘Automation’

Filed under: Uncategorized — Tags: , , — yasi8h @ 8:15 am

At work i wanted to automate the build releasing process (of mostly c# desktop/mobile applications which are developed using VS and distributed as installers). This is basically giving the QA a fresh versioned build of whatever the software that is being developed. Although it sound pretty easy and straightforward. It is not. And i have come to hate doing this manually, because it takes a lot of time and its repetitive work, so its very… boring!. The following CLI program that i wrote just automates:

  • Update the working folder from the SVN repo
  • Clean
  • Build (using Release config).
  • Zip (only the Installer(s) resulting from the final build).
  • Extract the version of the resulting executables by reading the AssemblyInfo.cs of the main project.
  • Name the zip file according to all the conventions (boring…).
  • Copy it over to the QA’s SMB share, and put it in a folder structure (again some more naming conventions come in to play).

I know this is not the nicest way of doing this. I should probably be using MSBuild/nAnt/a continues integration server…etc to do it. But, it felt a bit more complicated, and it required me to spend a little bit of time learning stuff. So… i ended up writing this.


using System;
using System.Diagnostics;
using System.IO;


namespace auto_build
    internal class Program
        private const string Title = "auto_build v0.01";

        private static void Main(string[] args)
            Console.Title = Title;
            var settings = Settings.Default;



            P("Updating Source from SVN...");
            Run(settings.SvnPath, string.Format(settings.SvnUpdateCommand, settings.SolutionRoot));

            P("Cleaning Solution...");
            Run(settings.DevenvPath, string.Format(settings.DevenvClean, settings.SolutionPath, settings.SolutionName));

            P("Building (Release Config) Solution...");
                string.Format(settings.DevenvBuildRelease, settings.SolutionPath, settings.SolutionName));

            P("Zipping the Setup...");
            //ex: "NAME-SG v1.0.0.3106 Setup 06-Jul-2010 10-40"
            var zipFilePath = string.Format("{0}\\Release", settings.SetupProjectPath);
            var zipFileName = string.Format(settings.ZipFileNameFormat, settings.ZipFileApplicationName,
                string.Format(settings.WinrarPathArgsForCreatingAnArchive, zipFileName, zipFilePath));

            P("Coping the zipped archive to the destanation...");
            var directory =
                Directory.CreateDirectory(string.Format("{0}//v{1}", settings.DestPath, GetProjectVersion()));
            File.Move(string.Format("{0}//{1}", zipFilePath, zipFileName),
                      string.Format("{0}//{1}", directory.FullName, zipFileName));

            P("Press any key to exit...");

        private static string GetProjectVersion()
            using (
                var reader =
                    new StreamReader(
                        new FileStream(string.Format(Settings.Default.AssemblyInfoPath, Settings.Default.SolutionPath),
                                       FileMode.Open, FileAccess.Read)))
                while (!reader.EndOfStream)
                    var line = reader.ReadLine();
                    if (!line.Contains("// [assembly: AssemblyVersion(\"") &&
                        line.Contains("[assembly: AssemblyVersion(\""))
                        var start = line.IndexOf("[assembly: AssemblyVersion(\"") +
                                    "[assembly: AssemblyVersion(\"".Length;
                        var end = line.IndexOf("\")]");
                        var length = end - start;

                        return line.Substring(start, length);

            return "x.x.x.x"; //couldn't find the assebmly version

        private static string Run(string command, string paras)
            var pProcess = new Process
                                   StartInfo =
                                           FileName = command,
                                           Arguments = paras,
                                           UseShellExecute = false,
                                           RedirectStandardOutput = true

            //Get program output
            var strOutput = pProcess.StandardOutput.ReadToEnd();
            return strOutput;

        #region Console Text Output Helpers

        private static void P(string text)

        private static void PBlankLine()

        private static void PSeperator()


The program above uses a settings file to get most of the information it requires. you can get the settings file and the above posted file here.


Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at

%d bloggers like this: