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

Fixing ApplicationBlocks.Updater Exception in x64

I recently inherited a project that uses Microsoft Enterprise Library, albeit that it uses source code instead of binaries. Yuck. I spent a lot of time trying to fix compatibility issues with x86 vs. x64.

In the end, I did manage to get it working. The major issue I ran into was an exception in the Updater project:


Could not load type 'Microsoft.ApplicationBlocks.Updater.Downloaders.BG_BASIC_CREDENTIALS' from assembly 'Microsoft.ApplicationBlocks.Updater.Downloaders, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 4 that is incorrectly aligned or overlapped by a non-object field.

As it turns out, this is a unique x64 problem. Essentially, the struct in question uses a space of 4 bytes, which is correct for 32-bit machines. On 64-bit machines, it needs to be eight bytes.

We can easily update the relevant class, like so:


  /// </summary ... />
  [StructLayout(LayoutKind.Explicit, Size=8, Pack=4)]
  internal struct BG_BASIC_CREDENTIALS
  {
    /// <summary ... />
    [FieldOffset(0)]
    [MarshalAs(UnmanagedType.LPWStr)]
    public string UserName;

    /// <summary ... />
    [FieldOffset(4)] // Change this to 8
    [MarshalAs(UnmanagedType.LPWStr)]
    public string Password;
  }

Tada, instant success! The exception disappears, and everything proceeds on as expected.

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

Debugging Silverlight Apps in Firefox

Getting Firefox to break on your breakpoints can be a challenge. Even until today, many people still believe this is only possible by using Attach to Process ....

It’s not.

You don’t need a web-side project in your solution, either; Firefox is more than capable of handling this.

Simply:

  • Load Firefox
  • Type “about:config” into FF’s address bar
  • Accept the warning
  • Search for the entry “dom.ipc.plugins.enabled”
  • Change its value from “true” to “false” (double-click)
  • Restart the browser

You should be able to hit F5 in Visual Studio and immediately see your breakpoints being hit.

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

Dropping an Active Database in SQL Server

How do you drop a database in SQL Server? Easy, right?

DROP DATABASE SomeDatabase

This won’t work if you have active connections to your database. You might have an application connecting, or even Management Studio or some other tool holding an open connection.

But what if you really, really want to drop the database? Maybe you’re going to recreate it, or reseed it, and you need to kill all existing connections.

The answer is perplexingly simple:


ALTER DATABASE SomeDatabase
    SET SINGLE_USER 
    WITH ROLLBACK IMMEDIATE
DROP DATABASE SomeDatabase

This immediately disconnects all users, closes any open connections, rolls back any transactions in progress, and drops the database.

Dangerous? Yes. But if you’re trying to drop the database, you should already be aware of the dangers of doing so.

Posted in Tools | Tagged | Leave a comment

Enums, SQL Server, and Null

Enumerations are great, because they give you a human-readable, strongly typed, limited list of values to use (instead of, say, an integer with a symbolic value). But how do enumerations work with SQL Server, and in particular, with null?

The History of Enums: C++ and Integers

Historically (especially in C++), enumerations came about to give a strongly-typed, limited-size list of values to use instead of integers. Consider code that returns 0 for success, 1 for “File not found,” and 2 for “out of space.” Wouldn’t you much rather prefer values like, say, Success, FileNotFound, and OutOfSpace?

Worse still, what if you’re using 1 to represent some value, and you accidentally assign some other value, or call i++? There’s no safety net.

If you just learned C# (without the pain of running into this in C++), you might not realize that enums can be easily converted into integers. Not to mention that each value already has a (default, overridable) integer value assigned to it.

But that’s besides the point. What’s more relevant is that enums are usually stored as integers in SQL Server. I say usually because there are probably a dozen different ways to handle the implementation — but the simplest is just to use integers. This is especially true if you’re using some framework that maps the values to integers.

Dealing with Null and SQL Server

One drawback of enumerations is that you can’t easily specify “no value” or “nothing.” Sure, you could add a special Nothing value to your enum, but what would be the point of that?

As it turns out, there is a way to specify a nothing value. Any enumeration can easily be defined as a nullable type, by use of the ? symbol.

If you’re not familiar with the question-mark nullable operator, it means “and also possibly null. To illustrate:


int x = 13;
x = null; // compilation error
int? y = 7;
y = null; // works!

You can do the same thing with enumerations:


private enum DayOfWeek { Sunday, Monday, ... , Saturday };

DayOfWeek today = Sunday;
today = null; // won't compile
DayOfWeek? tomorrow = Saturday;
tomorrow = null; // compiles!

The MSDN documentation mentions that any value type can be nullable — ints, bools, floats, etc. and enumerations.

And as you would expect, this allows you to specify a null value in your column in SQL Server. No extra work needed!

Summary

In this brief post, we talked about enumerations: their purpose historically, their relationship to integers, SQL server, and how to make any enumeration null-worthy by using nullable types.

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

Searching the Entire SQL Server Database

Sometimes, like when you’re reverse-engineering a huge application, you need to do a free-form text search on the database. You know some value is stored in the database (albeit maybe as a partial string), you just don’t know where. It could be in any of thousands of tables and millions of records.

As it so happens, this Stack Overflow question answers exactly how to do this. You can create a stored procedure, and run it, like so:

SearchAllTables 'Linear Algebra'

I recommend you use the link, since it covers two variants on the script (the original, and a slower one that also searches integer fields). But in any case, here’s the full version. Enjoy!


CREATE PROC SearchAllTables
(
    @SearchStr nvarchar(100)
)
AS
BEGIN

-- Copyright © 2002 Narayana Vyas Kondreddi. All rights reserved.
-- Purpose: To search all columns of all tables for a given search string
-- Written by: Narayana Vyas Kondreddi
-- Site: http://vyaskn.tripod.com
-- Tested on: SQL Server 7.0 and SQL Server 2000
-- Date modified: 28th July 2002 22:50 GMT

DECLARE @Results TABLE(ColumnName nvarchar(370), ColumnValue nvarchar(3630))

SET NOCOUNT ON

DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110)
SET  @TableName = ''
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''')

WHILE @TableName IS NOT NULL
BEGIN
    SET @ColumnName = ''
    SET @TableName = 
    (
        SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
        FROM    INFORMATION_SCHEMA.TABLES
        WHERE       TABLE_TYPE = 'BASE TABLE'
            AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
            AND OBJECTPROPERTY(
                    OBJECT_ID(
                        QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
                         ), 'IsMSShipped'
                           ) = 0
    )

    WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL)
    BEGIN
        SET @ColumnName =
        (
            SELECT MIN(QUOTENAME(COLUMN_NAME))
            FROM    INFORMATION_SCHEMA.COLUMNS
            WHERE       TABLE_SCHEMA    = PARSENAME(@TableName, 2)
                AND TABLE_NAME  = PARSENAME(@TableName, 1)
                AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar')
                AND QUOTENAME(COLUMN_NAME) > @ColumnName
        )

        IF @ColumnName IS NOT NULL
        BEGIN
            INSERT INTO @Results
            EXEC
            (
                'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) 
                FROM ' + @TableName + ' (NOLOCK) ' +
                ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
            )
        END
    END 
END

SELECT ColumnName, ColumnValue FROM @Results
END

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

Selecting Encrypted Columns in SQL Server

SQL Server has a wonderful (and sometimes annoying) feature where you can encrypt entire columns. If you’re interested in a bigger picture and more details on SQL Server and encryption, check out this uber long post I wrote.

We won’t go into that much detail here. Let’s instead breeze through what you need to know:

  • SQL server has symmetric and asymmetric encryption keys.
  • Keys can themselves be encrypted by “security certificates.”
  • Security certificates can be password-encrypted if you choose to do so.
  • Columns can be encrypted with a key.

This means that to encrypt (or subsequently decrypt) columns, you will need a key and a certificate. Generating these are beyond the scope of this post; let’s just assume you have an AllPurposeKey which is encrypted with an AllPurposeCertificate.

For example, let’s say you had a User table that had an encrypted BirthDate column. If you tried to select all the birthdays, you would see something like:


0x002A5D0CDC10391F25DA73EA80F6AE3801000000E5177115DF0DC30BFFE9AE ...
0x002A5D0CDC10391F25DA73EA80F6AE3801000000A5EE2DED63FCF9F85688BA ...
0x002A5D0CDC10391F25DA73EA80F6AE3801000000B231814527B6C75A520721 ...
...

Clearly, this is unusable. To decrypt it, select it with your key and certificate, and convert it into a date, like so:


OPEN SYMMETRIC KEY AllPurposeKey DECRYPTION BY CERTIFICATE AllPurposeCertificate
SELECT CONVERT(DATE, DecryptByKey(u.BirthDate)) AS BirthDate

And instead, you will see (as expected), the unencrypted dates:


1961-09-07 00:00:00.000
1978-11-22 00:00:00.000
1953-03-31 00:00:00.000
...

Easy breezy! There are benefits to encrypting at a database level, as there are drawbacks, but I leave it to you to puzzle those out.

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

Aggregate Objects in DevExpress

DevExpress has an amazing feature called “aggregation,” which is not explained terribly well in their documentation.

What is aggregation, and how does it work?

Simply, aggregation is two things:

  1. Cascading Delete: Aggregated objects can’t live without their parents; deleting the parent deletes the (aggregated) child. This is essentially cascading delete in database parlance.
  2. Aggregated Views: More importantly, fields for an aggregate object show up embedded in the parent’s form instead of linked by a drop-down.

Let’s say we had a Person class with an Address instance (associated 1:1). Without aggregation, when you add the address field to the person, you get an association drop-down, like so:

When aggregated, you will instead see all of the address fields on the Person detail view:

Aggregating an Object: Step by Step

So how do you create an aggregate object?

  1. Create the parent (aggregation-holder) and child (to be aggregated) classes, inheriting from BaseObject.
  2. Create a field in the parent with the child’s type, as you would with any other field type (eg. String).
  3. Add the [Aggregated] attribute on the field you just created.
  4. In the AfterConstruction method (still in the parent class), instantiate the new object (eg. this.Address = new Address(this.Session)).

And you’re done!

Troubleshooting Aggregated Objects

Q: I can’t write to any of the fields in the aggregated object!
A:
In the model editor, make sure that you haven’t set AllowEdit to false for the field (under Items). The default is true. Additionally, make sure you're instantiating a new instance of the field in the AfterConstruction method, as described above.

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

Excel-Style Auto-Filtering List Views in DevExpress

DevExpress automatically generates ListView and DetailView views for you. List views are great: they provide paging and sorting out of the box. But what about filtering? How can we implement complex, multi-faceted, Excel-style filtering?

The answer is surprisingly easy: simply toggle the ShowAutoFilter property on the ListView.

To set this:

  1. Double-click on your .xafml file to load up the model editor
  2. Uncheck the Views node (see screenshot)
  3. Find the list view you want to filter on, and select it
  4. Under Behaviour, look for the ShowAutoFilterRow property and set it to true.
  5. Rebuild and deploy your application.

You should now see an unintuitively blank row below your list view headers. Go ahead and type anything in and you should see the filters take effect, as well as the filter criteria (which you can click on to modify via a GUI).

That’s quite a lot of framework and scaffolding DevExpress is providing. I’m surprised how easy it is to allow dynamic, smart filtering on any field.

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