Saved by a ZIP File and a Command Line

March 14, 2014 — 5 Comments

boundaries Imagine that you were required to interface with an incompatible codebase. In .NET, we have the GAC (Global Assembly Cache) that helps us overcome situations known as DLL Hell… But times are changing and because we run software on virtual environments, we don’t have the luxury or interest of publishing our dependencies to the GAC.

I build cloud solutions for a living and sometimes, I’m faced with interesting challenges. In a recent project, I was asked to help my team design a public facing API that would interface with a backend. The team building the API solution agreed that it would be wise to keep our dependencies in check and run with the crowd. Remember, Windows Azure releases updates and features every 3 weeks!

Every week, someone from our team checked dependencies and tools for updates. Life was fantastic!

Then, it was time to integrate with, the other team’s code base, “the backend”. This is where things got interesting because our project was on the bleeding edge, but the backend wasn’t. Actually it was a couple versions behind on most of its dependencies. As you can imagine, this threw a wrench in our aspirations to keep up because we didn’t rely on the GAC to manage DLL versions.

Some of our common dependencies were backwards compatible, but others unleashed hidden dragons. Think about this for a second, how do you integrate multiple incompatible code bases to form an ecosystem?

You isolate them!

In order to execute both code bases independently, I decided to wrap the backend with a proxy that would execute in a separate AppDomain. The proxy was built as a console application and the WCF service is hosted in process. This simplified development and testing of the proxy.

Once we had our proxy, we needed to integrate and deploy to our Cloud Service Role instances. This is the step that proved to be a challenge. As it was impossible for us to drop the backend binaries into our API’s output directory, I decided to use post-build events to ZIP the Proxy’s output directory. The resulting archive was then included in the Cloud Service project and copied to its output directory. Then I configured a Startup Task that would UNZIP the proxy in folder located on the same level as bin and launched the Proxy as a background task.

cloud service

But there was a catch, as some of you know, I’m not a big fan of command lines… So I pinged Mathieu Langis, who was kind enough to spend some time to help me finish setting up the Proxy startup task.

Creating an Archive on Build

The first thing I had to do, was to find a way to ZIP the output of each time I built my Proxy in order to place the archive in my Cloud Service.

Bing came up with a few good suggestions and finally decided to use 7zip from the command line.

To set a post-build event, go to the project’s properties and navigate to the Build Events tab. Then click on “Edit Post-Build…”

 project properties & post-build event

We used the following command to create the archive and to drop it into the Cloud Service.

$(ProjectDir)7za.exe a "$(SolutionDir)CloudService\Startup\$(ProjectName).zip" "$(TargetDir)*"

For this to work, you need to place a copy of 7za.exe at your project’s root.

Once the command completes, you will find your archive located in the solution folder “CloudService\Startup\”.

Deploying the Proxy Archive with the Cloud Service

Once the archive is placed in the “CloudService\Startup\” folder, it’s not time to make sure it gets deployed with the Cloud Service.


Be sure to include a copy of “7za.exe” and a copy of “” in the Cloud Service Project. Then right click both of them and set the File Properties so that they are set to “Copy Always”.

File Properties

Configuring the Startup Task

Once all the pieces are in place, it’s time to create and configure our Startup Task.

Add a new cmd file to the Cloud Service under the Startup folder. This location is not important, in our case it’s a matter of convenience.

startup task cmd

Be sure to save the cmd file by setting the encoding to ANSI


We used to following script to extract the Proxy from the archive to a folder located outside the %ROLEROOT%\approot\bin folder.

cd %ROLEROOT%\approot\bin\Startup\
7za.exe e -o..\..\Startup\Proxy –y

Then we use the following script to start the Proxy.

cd %ROLEROOT%\approot\Startup\Proxy
start Proxy.exe

Configuring the startup task consists of editing the ServiceDefinition.csdef located in the Cloud Project. Adding the task to the Startup tag found under both the WorkerRole and the WebRole tags.

  <Task commandLine="Startup/StartupTask.cmd" executionContext="elevated" taskType="background">

The task is configured to execute with elevated rights and as a background task. This will allow the Role to continue it’s startup process without blocking and waiting for the startup task to complete.


Find out More

5 responses to Saved by a ZIP File and a Command Line


    Please note that ‘7za.exe a’ adds files to an archive, it doesn’t overwrite the archive. So if you make changes to your project that’s being packed and some files are removed from the output they will still remain in the archive. This may or may not cause problems so you are better off deleting the archive prior to updating it.


Trackbacks and Pingbacks:

  1. How do you Inject Configurations into Windows Azure Cloud Service Startup Tasks? | Alexandre Brisebois - March 20, 2014

    […] a previous post I used a Startup Task to isolate incompatible code bases, unfortunately this brought about some challenges. One of which might also affect whoever is […]


  2. What!? Windows Azure Cloud Services have Plugins! | Alexandre Brisebois - March 21, 2014

    […] I was looking at using Cloud Service Startup Tasks in order get incompatible code bases to cooperate, I came across plugins. At first, they look very appealing and it was extremely tempting to create […]


  3. Reading Notes 2014-03-24 | Matricis - March 24, 2014

    […] Saved by a ZIP File and a Command Line – Interesting option to zipfile in a Windows Azure startup task. Could it be easier with PowerShell? […]


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 )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.