Visual Studio Automatic Version Numbering

Visual Studio (2010+) adds a much-requested feature: the ability to automatically increment assembly versions per build. (Prior to this, the only way to update the assembly version was to include a batch file, build script, or some other mechanism tied to the build machine that would update AssemblyInfo.cs.)

As a refresher, the assembly version resides in the file Properties\AssemblyInfo.cs. The file contains assembly-level declarations, which is to say, annotations for various assembly-level meta-data. (If you ever need to add any assembly-level annotations, like configuration for Eazfuscator, this is the place to do it.)

At the end of the file, you will notice a lovely comment block and two attributes:


// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

The comment indicates how you can specify auto-versioning of the assembly version. You might think “easy, let me update my file like so:”


[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("1.0.0.0")]

But there’s a gotcha here: you need to specify only the AssemblyVersion attribute for the auto-incrementing to work. With this configuration above, you will still see an assembly version of “1.0.*”, strangely enough.

The correct configuration is:


[assembly: AssemblyVersion("1.0.*")]

Save, build, and everything will work.

“Hey, that’s great,” you might be thinking. “Let me just update this through the project properties > Assembly Information button in Visual Studio.” So you blank out the File Version fields, only to be greeted with this:

That’s right — Visual Studio will only let you enter a blank File Version through the AssemblyInfo.cs file, not through the GUI! (Thankfully, if it’s already blank, and you edit some other properties, Visual Studio won’t complain.)

The Generated Number

You might be curious to know how Visual Studio generates the resulting numbers. In fact, you may wonder why it doesn’t start at, say, 1.0.1.1 and increment to 1.0.1.2, etc.

The actual details are specified on this MSDN page. The summary is that:

  • The build number (the third number in the version) is equal to the number of days since January 1st, 2000. So if today is January 23rd, 2012, that’s approximately a value of 4400.
  • The revision number (the final number in the version) is equal to the number of seconds since midnight, divided by two.So a build at midnight will result in 0, while a build at 1am will result in a value of 1800.

The end result is that every build results in a different version number (unless you run two builds at the very same second). The other caveat is that, if you have a build machine, you need to make sure your machine times are synchronized. Or at least be aware of the fact that a build machine in a different timezone may generate a build that seems newer (or older) than it should be.

Posted in Silverlight, Tools, Web, Wndows Forms, WPF | Tagged , , | Leave a comment

Finding Circular Dependencies in SQL Server

SQL Server doesn’t mind circular dependencies in tables. That is, unless you have two tables which refer to each other, and try to add foreign key constraints to both.

Then you’ll see this (infamous) message:

Introducing FOREIGN KEY constraint 'FK_Foo' on table 'Blah' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

This message can mean a couple of things; one of them is two ways a deletion can cascade down to the same table (i.e. delete table T, and there are two foreign key cascade deletions to table D). The other is that you’re trying to add foreign keys in a way that causes a cycle, i.e. it will cascade back to the same table.

Thankfully, Wayne Berry wrote a script to take care of this. It finds and prints out cyclical dependencies, like so:

dba.Foo -> dba.Bar -> dba.Foo

You can find the full script below.


SET NOCOUNT ON

-- WWB: Create a Temp Table Of All Relationship To Improve Overall Performance
CREATE TABLE #TableRelationships (FK_Schema nvarchar(max), FK_Table nvarchar(max),
    PK_Schema nvarchar(max), PK_Table nvarchar(max))

-- WWB: Create a List Of All Tables To Check
CREATE TABLE #TableList ([Schema] nvarchar(max), [Table] nvarchar(max))

-- WWB: Fill the Table List
INSERT INTO #TableList ([Table], [Schema])
SELECT TABLE_NAME, TABLE_SCHEMA
FROM INFORMATION_SCHEMA.TABLES 
WHERE Table_Type = 'BASE TABLE'

-- WWB: Fill the RelationShip Temp Table
INSERT INTO #TableRelationships(FK_Schema, FK_Table, PK_Schema, PK_Table)
SELECT
    FK.TABLE_SCHEMA,
    FK.TABLE_NAME,
    PK.TABLE_SCHEMA,
    PK.TABLE_NAME
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C
      INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK ON 
        C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
      INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK ON 
        C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME
      INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU ON 
        C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
      INNER JOIN (
            SELECT i1.TABLE_NAME, i2.COLUMN_NAME
            FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1
            INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2 ON
             i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME
            WHERE i1.CONSTRAINT_TYPE = 'PRIMARY KEY'
) PT ON PT.TABLE_NAME = PK.TABLE_NAME

CREATE TABLE #Stack([Schema] nvarchar(max), [Table] nvarchar(max))

GO

-- WWB: Drop SqlAzureRecursiveFind
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = 
    OBJECT_ID(N'[dbo].[SqlAzureRecursiveFind]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[SqlAzureRecursiveFind]

GO

-- WWB: Create a Stored Procedure that Recursively Calls Itself
CREATE PROC SqlAzureRecursiveFind
    @BaseSchmea nvarchar(max),
    @BaseTable nvarchar(max),
    @Schmea nvarchar(max),
    @Table nvarchar(max),
    @Fail nvarchar(max) OUTPUT
AS

    SET NOCOUNT ON
              
    -- WWB: Keep Track Of the Schema and Tables We Have Checked
    -- Prevents Looping          
    INSERT INTO #Stack([Schema],[Table]) VALUES (@Schmea, @Table)
    
    DECLARE @RelatedSchema nvarchar(max)
    DECLARE @RelatedTable nvarchar(max)
    
    -- WWB: Select all tables that the input table is dependent on
    DECLARE table_cursor CURSOR LOCAL  FOR
          SELECT PK_Schema, PK_Table
          FROM #TableRelationships
          WHERE FK_Schema = @Schmea AND FK_Table = @Table

    OPEN table_cursor;

    -- Perform the first fetch.
    FETCH NEXT FROM table_cursor INTO @RelatedSchema, @RelatedTable;

    -- Check @@FETCH_STATUS to see if there are any more rows to fetch.
    WHILE @@FETCH_STATUS = 0
    BEGIN
    
        -- WWB: If We have Recurred To Where We Start This
        -- Is a Circular Reference
        -- Begin failing out of the recursions
        IF (@BaseSchmea = @RelatedSchema AND 
                @BaseTable = @RelatedTable)
            BEGIN
                SET @Fail = @RelatedSchema + '.' + @RelatedTable
                RETURN
            END
        ELSE            
        BEGIN
        
            DECLARE @Count int
        
            -- WWB: Check to make sure that the dependencies are not in the stack
            -- If they are we don't need to go down this branch
            SELECT    @Count = COUNT(1)
            FROM    #Stack    
            WHERE    #Stack.[Schema] = @RelatedSchema AND 
                #Stack.[Table] = @RelatedTable
        
            IF (@Count=0) 
            BEGIN
                -- WWB: Recurse
                EXECUTE SqlAzureRecursiveFind @BaseSchmea, 
                    @BaseTable, 
                    @RelatedSchema, @RelatedTable, @Fail OUTPUT
                IF (LEN(@Fail) > 0)
                BEGIN
                    -- WWB: If the Call Fails, Build the Output Up
                    SET @Fail = @RelatedSchema + '.' + @RelatedTable 
                        + ' -> ' + @Fail
                    RETURN
                END
            END
       END
           
       -- This is executed as long as the previous fetch succeeds.
    FETCH NEXT FROM table_cursor INTO @RelatedSchema, @RelatedTable;
    END

    CLOSE table_cursor;
    DEALLOCATE table_cursor;    

GO    

SET NOCOUNT ON

DECLARE @Schema nvarchar(max)
DECLARE @Table nvarchar(max)
DECLARE @Fail nvarchar(max)

-- WWB: Loop Through All the Tables In the Database Checking Each One
DECLARE list_cursor CURSOR FOR
      SELECT [Schema], [Table]
      FROM #TableList

OPEN list_cursor;

-- Perform the first fetch.
FETCH NEXT FROM list_cursor INTO @Schema, @Table;

-- Check @@FETCH_STATUS to see if there are any more rows to fetch.
WHILE @@FETCH_STATUS = 0
BEGIN

    -- WWB: Clear the Stack (Don't you love Global Variables)
    DELETE #Stack
    
    -- WWB: Initialize the Input
    SET @Fail = ''

    -- WWB: Check the Table
    EXECUTE SqlAzureRecursiveFind @Schema, 
        @Table, @Schema,
         @Table, @Fail OUTPUT
    IF (LEN(@Fail) > 0)
    BEGIN
        -- WWB: Failed, Output
        SET @Fail = @Schema + '.' + @Table + ' -> ' + @Fail
        PRINT @Fail
    END
            
   -- This is executed as long as the previous fetch succeeds.
    FETCH NEXT FROM list_cursor INTO @Schema, @Table;
END

-- WWB: Clean Up
CLOSE list_cursor;
DEALLOCATE list_cursor;    
                    
DROP TABLE #TableRelationships
DROP TABLE #Stack
DROP TABLE #TableList
DROP PROC SqlAzureRecursiveFind

Posted in Libraries, Web, Wndows Forms, WPF | Tagged , , | Leave a comment

Rails-Style Test Database Creation in ASP.NET MVC

One of the great things about Ruby on Rails is that it uses three databases: development (for dev), test (for unit and integration tests), and production. The test database is actually created prior to running any of the tests; it uses migrations to build the schema, and plain-text (YAML) files to populate test data as you specified.

Pretty cool.

This is actually possible in ASP.NET MVC (as of MVC3), with a bit of work. You will need:

  • Your ASP.NET MVC application (of course)
  • MigratorDotNet (or your migrations tool of choice)
  • Visual Studio Test Framework(or your testing tool of choice)
  • A bit of practice and ingenuity!

Here’s how it works. Given that you already have your development environment working, along with your set of migrations to create your schema tables (including the core ASP.NET tables if you’re using the built-in login module), you just need to create a once-per-test-run method that will recreate the database and run the migrations.

Sounds complicated? It’s not. Here’s how it would look (with the tool stack listed above):


[AssemblyInitialize] // Run once per test run
public static void RecreateDatabase(TestContext context)
{
  DataContext dataContext = new DataContext(connectionString);

  // Drop all the foreign keys; they can prevent tables from being dropped
  dataContext.ExecuteCommand(@"DECLARE @sqlForeignKeys VARCHAR(MAX)

  SELECT @sqlForeignKeys = ISNULL(@sqlForeignKeys,'') +
  'ALTER TABLE dbo.[' + OBJECT_NAME(FK.parent_object_id) + '] DROP CONSTRAINT [' + FK.name + '];' + CHAR(10)
  FROM SYS.FOREIGN_KEYS FK

  EXEC(@sqlForeignKeys)");

  
  // Drop all tables
  dataContext.ExecuteCommand("EXEC sp_MSforeachtable @command1 = \"DROP TABLE ?\"");

  // Run migrations to rebuilt schema
  Assembly migrationsAssembly = Assembly.Load("..."); // main application assembly
  Migrator.Migrator m = new Migrator.Migrator("SqlServer", connectionString, migrationsAssembly);
  m.MigrateToLastVersion();
}

The code is pretty straight forward: we drop all the foreign keys first, then the tables. We use sp_MSforeachtable, which is a stored procedure that iterates over all tables. (We drop foreign keys first, because you can’t drop a table that has a foreign key pointing to one of its columns.)

Then, we get a hold of our main assembly (the one containing the migrations), and we run those.

And everything just works! The AssemblyInitialize attribute ensures that this code is only run once, when the test assembly is loaded.

And just like that, you have your very own Rails-style database being recreated on-the-fly for running tests. (Depending on your flavour of ORM, you can even add your own seed data here for testing.)

Posted in Core .NET, Web | Tagged , , | Leave a comment

Testing Rendered HTML in ASP.NET MVC3

ASP.NET applications are still difficult to write automated tests against. Other languages (notably Ruby on Rails) have powerful mechanisms to perform not only unit-level testing, but also integration testing: fetching a set of webpages, performing postbacks, and verifying the HTML from the responses along the way.

MVC3 is partially testable: you can create controllers and request views, even pull items out of the ViewBag. That’s great, but for many applications, it’s not enough; you want to be able to actually read the underlying HTML and check for the presence or absense of certain HTML content.

Thankfully, there is an answer. It’s not simple, but it is relatively straight-forward: deploy your debug directory of your web application onto IIS, and use a .NET conversion of HtmlUnit (a GUI-less browser written in Java) to run on IKVM, a .NET implementation of the JRE.

Credit for this amazing solution goes to Steve Sanderson, who documented the process (and built the binaries) on his blog. Essentially, you need to:

  • Deploy your debug environment into IIS (giving you the benefit of seeing real IIS errors that don’t appear in Casini)
  • Download the HtmlUnit and IKVM binaries
  • Add all the appropriate references to your test project
  • Compile, execute, and rejoice

Steve’s page does a great job of xplaining all the steps; just note that he has a link to the IKVM and HtmlUnit binaries at the end of his post (so you don’t need to build them yourself).

Once you have your app deployed, testing can be as simple as:


  [TestMethod]
  public void RequestingSecureUrlRedirectsToLogOn() {
    WebClient webClient = new WebClient();
    HtmlPage page = (HtmlPage)webClient.getPage("http://localhost/some/secure/action");
    WebResponse response = page.getWebResponse();
    Assert.IsTrue(response.getRequestUrl().toString().EndsWith("/Account/LogOn"));
  }

Run your tests (Visual Studio test framework in my case), and, tada! More complicated tests are possible (filling out forms, clicking buttons, checking response HTML), all though the HtmlPage API. For example, we could have extended that test to include:


((HtmlInput)page.getElementById("UserName")).setValueAttribute("bob");
((HtmlInput)page.getElementById("Password")).setValueAttribute("invalid");
HtmlPage resultsPage = (HtmlPage)loginPage.getElementById("submit").click();

string content = resultPage.asXml();
Assert.IsTrue(content.Contains("Login was unsuccessful."));

In this case, we filled in the UserName and Password fields, clicked Submit, and checked the HTML of the resulting page — that it contained an error message.

Pretty slick stuff. I highly recommend it if unit testing is something you prioritize. The potential for integration testing is pretty awesome.

Posted in Libraries, Web | Tagged , , , , | Leave a comment

Integrating NUnit with CruiseControl.NET

There’s no clear, concise documentation on how to get NUnit working with CruiseControl.NET. So I figured I should write it, having gone through the pain of trying to figure everything out.

I assume you already:

  • Have a solution that builds in CC.NET
  • Have a project that builds the NUnit tests DLL

The recommended way of integration is not the nunit tag, but it’s via the exec tag. This supposedly will break less than using the nunit tag.

Here’s what you need to do:

Run NUnit in CruiseControl.NET

Add the following into your ccnet.config under tasks for your project:


<exec>
        <executable>nunit-console.exe</executable>
        <baseDirectory>C:\Program Files\NUnit 2.x.y.z\bin\net-2.0</baseDirectory>     
        <buildArgs>C:\blah\blah\your.nunit.dll /xml:C:\blah\blah\nunit-results.xml</buildArgs>
      </exec>

After executing the main build (MSbuild or whatever it is), this will invoke nunit-console and tell it to run the your.nunit.dll assembly’s tests, and to write the output to C:\blah\blah\nunit-results.xml.

The next step is to tell CruiseControl.NET to read this file and include it in the dashboard information. To do this, we need to add a publisher. As a point of extensibility, CruiseControl.NET allows you to merge any XML files into the build report; some, like NUnit, which it understands, it will display meaningfully.

To add a publisher, add the following after your <tasks /> tag:


<publishers>
  <merge>
    <files>
      <file>C:\blah\blah\nunit-results.xml</file>
    </files>
  </merge>
  <xmllogger />
  <statistics />
  <modificationHistory onlyLogWhenChangesFound="true" /> 
</publishers>

This tells CruiseControl.NET to merge the C:\blah\blah\nunit-results.xml content into the main build XML.

And that should be it! Force a build, and you should see CC.NET reporting success/failure test statistics in the web dashboard.

Posted in Silverlight, Tools, Web, Wndows Forms | Tagged , | Leave a comment

Fetching Connection Strings from App.Config in a Library via ConfigurationManager

Let’s imagine a common situation at work: you’re creating a library that must access a particular database and provide an interface for client applications to retrieve some data.

Easy, right? Simply create a DLL with App.Config, encrypt the connection string, and you’re good to go. Just call ConfigurationManager.ConnectionStrings[...].ConnectionString to get the connection string. If anything changes, you just change the connection string in one place, re-publish the DLL, and all the new consumers will automatically work.

Right?

Wrong! ConfigurationManager doesn’t (easily) allow you to read connection strings from an App.Config file inside a library. To do that, you need to use this workaround (error checking added):

Configuration config = null;
string exeConfigPath = this.GetType().Assembly.Location;

try
{
  string appConfigPath = exeConfigPath.Substring(0, exeConfigPath.LastIndexOf('\\') + 1) + "App.config";
  config = ConfigurationManager.OpenExeConfiguration(exeConfigPath);
}
catch (Exception e)
{
  throw new Exception("Can't read the config file with the connection string. Exception: " + e.Message);
}

if (config != null)
{
  if (!config.HasFile)
  {
    throw new Exception("Config file " + exeConfigPath + " doesn't exist.");
  }

  KeyValueConfigurationElement element = config.AppSettings.Settings["YourConnectionStringName"];
  if (element != null)
  {
    string value = element.Value;
    if (!string.IsNullOrEmpty(value))
    {
      // For some reason, slashes are quoted (eg. \ is converted to \\)
      // De-quote.
      return value.Replace(@"\\", @"\");
    }
  }
  throw new Exception("Found config file, but it doesn't have a value for YourConnectionStringName");
}
else
{
  throw new Exception("Got an empty config file");
}

The meat of this is really the OpenExeConfiguration line, which will open an App.Config file from a DLL (so long as you have the Copy to Output property on it set to Copy Always). You may also need to wrap everything into a <configuration /> tag.

You will also need a reference to System.Configuration in order to use System.Configuration, but I assume you know that already.

Posted in Core .NET, Web, Wndows Forms | Tagged , , | Leave a comment

Using NInject For Compile-Time AOP

I’ve blogged in the past about compile-time aspect oriented programming in C#. Please read that first, then come back, for this to make sense.

In summary: we want to be able to define aspects, write aspect-like code once, and have it automagically added to any class that uses that aspect.

After a lot of research, it seems like the best, easiest, and most flexible (albeit not-100%-automagical) way to do is is to implement aspects as an interface/implementation pair and inject them with Ninject.

Again, what does this mean?

  • Each aspect is defined by an interface. This gives us compile-time checking on which class implements which aspects. In our case, let’s imagine a (game-like) aspect like ILiving (for creating entities that have health and are alive or dead).
  • Each aspect is implemented in one interface-consuming class. This means the code for each aspect is in one place. In our case, we would have an LivingImpl class that implements ILiving.
  • Aspects are injected into every class automatically. No need to use a code weaver, post-build process, or anything else; just a simple (Ninject) kernel and a single Get method.
  • Classes implement interfaces, and redirect calls to *Impl instances. Our Player class would also implement ILiving, and redirect calls to an ILiving instance.
  • Aspects can be customized. Our LivingImpl class might define IsAlive by having Health > 0. Say we wanted to implement a zombie, which is living as long as it has health above -100. Since Zombie has an instance of ILiving, simply change the code to contain the new definition of IsAlive instead of returning _living.IsAlive.

Anyway, since this is practically possible, I plan to try this out in a future project. I’ll keep you posted on how it goes. It looks very exciting! My proof of concept using Ninject was very quick to be implemented, and worked like a dream.

One minor detail: Ninject uses constructors to pass in the implementations of interfaces. If you have a large number of aspects, and you don’t like using a huge constructor, you can always use Property Injection to inject via properties. But again, do you really want to expose a getter/setter for your property? Probably not; constructors are the way to go (and they signal dependency to the reader too).

And of course, you can always use dynamic classes and simply accumulate aspects that way; but I really prefer strong compile-time checking.

Posted in Core .NET, Silverlight, Web, Wndows Forms, WPF | Tagged , , | Leave a comment

Creating Background Applications in C#

.NET supports three types of executable applications out of the box: console, windows (forms), and service. (Actually, it also supports WPF, but that’s not the point.)

Console applications run with that old DOS-style window. They typically take input, and flood output on the console. They run, process, and execute in a finite lifetime.

Windows applications have some sort of windows form that they show. You can interact with them via buttons, lists, drop-downs, and more:

A windows service runs in the background. It starts when Windows starts, and stops when Windows shuts down. There’s no GUI; it just runs.

It’s pretty well-known how to create any of these application types in .NET. But what about a background process?

But first, what is a background process? It’s something like a mix between a console application and a Windows service; it runs in the background and executes code without any UI (like a service), but has a particular lifetime less than the lifetime of Windows (like a console application).

Why would you want to create a background process? Hopefully not to create a virus, malware, adware, or something else malicious (if that’s the case, please read about it elsewhere!).

It might be, as the case was for me, that you have an existing application which needs to perform some sort of task in the background: performing maintenance, checking for updates, or things like that.

The solution is pretty simple: just create a Windows Application project which doesn’t invoke any forms. You can do this by creating a new Windows Forms application and deleting the main form, or by creating a console application and changing the output type to Windows Application in the project properties:

That’s really all there is to it; your application will execute without any visible GUI or console window.

Posted in Core .NET, Wndows Forms | Tagged | Leave a comment

Sending Multiple Updates Through the Updater Block

In a previous post, we discussed the basics of Microsoft’s Updater block from their Enterprise Library: that clients connect to a server, pull XML files describing updates (files to update and an execution script/task to execute), grab those updates passively via BITS, and then download and execute updates.

As promised, this post will describe how to include multiple updates in a single manifest file.

The key here is really to understand that manifest files and refer to other manifest files. This means we have a master/index manifest file, which links all the update manifests.

Conceptually, you can have recursive manifests, nested manifests, or a tree/graph of manifests (with an unlimited amount of nesting, as far as I can tell). And in terms of performance, only new manifests are downloaded, so you don’t need to worry about a performance hit.

Our previous manifest looked like this:


<manifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" manifestId="{9DBCD243-0479-4dd2-883B-8DA46FC3FCA9}" mandatory="False" xmlns="urn:schemas-microsoft-com:PAG:updater-application-block:v2:manifest">
  <description>New software update</description>
  <application applicationId="{225E1AD7-8ABA-432f-A942-24BACA556850}">
  <!-- Path relative to <location /> of the app to launch for this update -->
    <entryPoint file="SimpleApplication\1.0.0.0\SimpleApplication.exe" parameters="" />
  <!-- Local path to store the downloadad file. Creates if necessary. -->
    <location>C:\Temp\Updater\</location>
  </application>
  <files base="http://localhost/MyAwesomeUpdateServer" hashComparison="No">
  <!-- Place on the remote server where we store the file -->
    <file source="SimpleApplication\1.0.0.0\SimpleApplication.exe" transient="No" />
  </files>
  <activation>
    <tasks>
      <task type="Microsoft.ApplicationBlocks.Updater.ActivationProcessors.ApplicationDeployProcessor, Microsoft.ApplicationBlocks.Updater.ActivationProcessors" name="ApplicationDeployProcessor" />
    </tasks>
  </activation>
</manifest>

Let’s rip out and stub out tasks and files, and instead, put them into a child manifest called update1.xml. This file will look like:


<manifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" manifestId="{9DBCD243-0479-4dd2-883B-8DA46FC3FCA9}" mandatory="False" xmlns="urn:schemas-microsoft-com:PAG:updater-application-block:v2:manifest">
  <description>New software update</description>
  <application applicationId="{225E1AD7-8ABA-432f-A942-24BACA556850}">
  <!-- Path relative to <location /> of the app to launch for this update -->
    <entryPoint file="SimpleApplication\1.0.0.0\SimpleApplication.exe" parameters="" />
  <!-- Local path to store the downloadad file. Creates if necessary. -->
    <location>C:\Temp\Updater\</location>
  </application>
  <files base="http://localhost/MyAwesomeUpdateServer" hashComparison="No">
  <!-- Place on the remote server where we store the file -->
    <file source="SimpleApplication\1.0.0.0\SimpleApplication.exe" transient="No" />
  </files>
  <activation>
    <tasks>
      <task type="Microsoft.ApplicationBlocks.Updater.ActivationProcessors.ApplicationDeployProcessor, Microsoft.ApplicationBlocks.Updater.ActivationProcessors" name="ApplicationDeployProcessor" />
    </tasks>
  </activation>
</manifest>

Now that we have encapsulated our update into its own manifest, let’s update the original manifest to reference this one:


<manifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" manifestId="{11BCD243-0379-4cd2-883A-8D946FC3FBA1}" mandatory="False" xmlns="urn:schemas-microsoft-com:PAG:updater-application-block:v2:manifest">
  <description>New software update</description>
  <application applicationId="{215E1AD7-9ABA-432f-A952-24BABA556850}">  
    <entryPoint file="" parameters="" />
    <location>C:\Temp\Updater\</location>
  </application>
  <files base="http://localhost/MyAwesomeUpdateServer" hashComparison="No" />
  <includedManifests>
    <manifest location="update1.xml" manifestId="{11BCD243-0379-4cd2-883A-8D946FC3FBA1}" />
  </includedManifests>
</manifest>

You’ll notice the <includedManifests> section, which references our update1.xml manifest. Great!

That’s it! If you wanted to add another update, simply create an update2.xml (or whatever you want to call it), and add another <manifest ... /> to your master/index manifest file to reference it.

One caveat: The Updater block uses manifest IDs to tell if a manifest has changed. The updater is smart enough to know if the original file has additional referenced files, even if the ID hasn’t changed. So you just need to add the new manifest, and you’re golden.

Simple as that!

Posted in Libraries, Silverlight, Web, Wndows Forms | Tagged , | Leave a comment

An Overview of the Updater Application Block

Part of Microsoft’s Enterprise Library is an Updater block. It’s not really clear from the MSDN introduction page what this is and how it works.

Essentially, it’s code that works like Windows Update. How does it work? At a high level:

  1. Your computer (client) connects to the Windows Update machine with the updates (server)
  2. The client asks: What new updates are there for me?
  3. The server sends: Here’s a list of updates.
  4. The client downloads each update (when bandwidth is available)
  5. The client activates each update

As you can see, it’s a server-client architecture. One of the immediate benefits is that it uses pull, not push — meaning if your client is behind corporate firewalls, you can still deliver updates. But like all pull technology, you can’t guarantee when (or even if) updates will happen.

Let’s drill into some details.

Under the Hood: How Updates Work

How exactly do we encapsulate this notion of an update? What exactly is an update?

In the Updater block, an update is essentially a file you want to deliver to the client, with a possible execution action.

  • A file can be any file — a ZIP file, an EXE file, a batch file, text file, doc file, or anything else.
  • An execution action is any action you can run. For example, you can invoke Internet Explorer, or 7-Zip; you can run your downloaded EXE or batch file; or open your downloaded text file in Notepad.

All of this information is collected into a “manifest” XML file on the server. Here’s a sample of an update that downloads SimpleApplication.exe into C:\Temp\Updater and then executes it:


<manifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" manifestId="{9DBCD243-0479-4dd2-883B-8DA46FC3FCA9}" mandatory="False" xmlns="urn:schemas-microsoft-com:PAG:updater-application-block:v2:manifest">
  <description>New software update</description>
  <application applicationId="{225E1AD7-8ABA-432f-A942-24BACA556850}">
  <!-- Path relative to <location /> of the app to launch for this update -->
    <entryPoint file="SimpleApplication\1.0.0.0\SimpleApplication.exe" parameters="" />
  <!-- Local path to store the downloadad file. Creates if necessary. -->
    <location>C:\Temp\Updater\</location>
  </application>
  <files base="http://localhost/MyAwesomeUpdateServer" hashComparison="No">
  <!-- Place on the remote server where we store the file -->
    <file source="SimpleApplication\1.0.0.0\SimpleApplication.exe" transient="No" />
  </files>
  <activation>
    <tasks>
      <task type="Microsoft.ApplicationBlocks.Updater.ActivationProcessors.ApplicationDeployProcessor, Microsoft.ApplicationBlocks.Updater.ActivationProcessors" name="ApplicationDeployProcessor" />
    </tasks>
  </activation>
</manifest>

You can see a couple of things from this file:

  • A description of what this update contains
  • An application that we’re providing as an update (SimpleApplication.exe)
  • The script to execute when the update completes (<entryPoint ... />)
  • The location to download the update to (C:\Temp\Updater)
  • The location on the server where we can grab the file from (http://localhost/MyAwesomeUpdateServer)
  • The exact path of the remote file to download (files base plus file source)

That’s really (surprisingly) all there is to it. When you run the updater, it will download this file; if it hasn’t run this update before (successfully), it will download and execute http://localhost/MyAwesomeUpdateServer/SimpleApplication/1.0.0.0/SimpleApplication.exe into E:\temp\Updater\SimpleApplication\1.0.0.0.

That’s really it. The update is queued and executed later. The next time you run the updater, it’ll check again for any new files in the manifest, and download any new updates.

Server-Side Stuff: IIS

On the server side, you need to actually host the manifest file somewhere where clients can access it. If you’re doing everything locally (and even if you’re not), the easiest way to do this is add a virtual directory to IIS to host the manifest file and the update files.

In our example, we’ll have the virtual directory MyAwesomeUpdateServer somewhere; it will have inside a manifest.xml file, along with the SimpleApplication.exe file under MyAwesomeUpdateServer\SimpleApplication\1.0.0.0.

I’m sure this can work with Apache or any other web-server, but I leave that as an exercise to you.

How Transferring Works: BITS

BITS, which evolved out of Windows Updater, is a smart downloader. If your maximum download speed is 100kb/s, and you’re currently downloading at 90kb/s, it will utilize only the remaining 10kb/s to download the updates. BITS also handles resuming downloads (even across client reboots), and some other stuff; you can read more about it here, at MSDN.

How do you add updates for multiple applications, and multiple updates per application? That’s beyond the scope of this article, so until next time! (Actually, that’s beyond the scope of my knowledge at this time, so when I figure it out, I’ll post another post about it.)

Posted in Libraries, Silverlight, Web, Wndows Forms | Tagged , | Leave a comment