The AppLife Update Blog

  • Application Update Customization using Custom Data

    When publishing updates for applications, it is often helpful to implement rules that can be applied on an update-by-update basis. With AppLife Update, the custom data field provides this opportunity.

    clip_image001

    With each update, you can specify a custom data string to go with the update. This value is then available to your application after an update check has been performed. Your application can interrogate the value and control additional logic based on the information. As an example, when creating updates for AppLife Update, we use this field to know whether or not the update requires Visual Studio to be closed. If it does, we add a RequiresVSClosed property to the custom data field.

    Accessing the Custom Data in Your Application

    After an update check, the update controller has a CurrentUpdate property that holds an UpdateInformation object. This object has a CustomData property that holds, you guessed it, the Custom Data string that you specify when publishing the update.

     

    Code Snippet

    1.if(updateController1.CheckForUpdate()) {

    2.   string customData = updateController1.CurrentUpdate.CustomData;

    3.}

    Changing Custom Data after Publication

    Custom Data can be modified after an update has been published without having to re-build the update package itself. To modify custom data, you can Manage Published Updates…

    From the Manage Published Updates dialog the Custom Data string can be modified and then published.

    clip_image002

    A Class to Parse Name/Value Pairs

    A common approach to be able to provide multiple pieces of information through the custom data string is to use a name/value pair syntax, and then extract this information within your application code. To help with this, here is a class that will parse a custom data field using a name=value; syntax.

    AppUpdateCustomData.cs and AppUpdateCustomData.vb

    Using this class, you can easily extract and use multi-value custom data strings in your applications.

    clip_image003

    Using the AppUpdateCustomData class:

     

    Code Snippet

    1.  if(updateController1.CheckForUpdate()) {

    2.    Kjs.AppLife.Update.AppUpdateCustomData customData = new Kjs.AppLife.Update.AppUpdateCustomData(updateController1.CurrentUpdate.CustomData);

    3.   

    4.    string myValue1;

    5.    string myValue2;

    6.   

    7.    if(customData.DataTable.ContainsKey("MyName1")) {

    8.      myValue1 = customData.DataTable["MyName1"];

    9.    }

    10. 

    11.  if(customData.DataTable.ContainsKey("MyName2")) {

    12.    myValue2 = customData.DataTable["MyName2"];

    13.  }

    14.}

    In conclusion, the Custom Data field provides the means for update publishers to assign information to individual update packages that applications can use to control application update behavior.

    Posted at 18 September, 2012 | By :Brian Haas | Categories : AppLife Update | Software Updating |
  • Using a Pre-Build Script for File Automation

    When an application update is built with AppLife Update, you can define a pre-build and post-build batch script to run during the build process. This ability to easily interact with the build process provides, among other things, the means to move files around on the build system before the actions in the action list are built. This allows for accomplishing automation tasks that might otherwise require a custom action builder. Action builders are more powerful, but more technically complicated as well. Creating a pre-build script is easy. In this post, I will demonstrate the use of a pre-build script to remove the necessity of manually modifying an action configuration before building an update.

    Hub and Spoke Update Deployment Example

    The Hub and Spoke Update Deployment solution lab outlines how AppLife Update can be used to “update” multiple application update servers. This is a part of a process that allows a software publisher using AppLife Update to maintain many remote update servers for their applications. With remote update servers, client systems can check for and retrieve updates from servers that are on their local networks, instead of from a global update server over a wide area network.

    The update actions that maintain those remote application update servers simply add two files to the update. The first file is the Director.Xml document, and the second file is the newest update package built for the application. This file is named major.minor.build.revision.zip based on the current version number of the application. The issue here is that the version number always changes, and when a standard Add & Replace Files action is utilized, the action configuration must also change with each new update in order to address the proper update package.

    clip_image001

    With a little help from the pre-build batch script and using a different update file action, we can remove this requirement to manually modify the update configuration with each update, which makes creating the remote server update a one-step process using the AppLife Make Update tool. Configured this way, the remote server update build can also be easily incorporated into a larger automation process using the Command Line build utility.

    The Pre-Build Script

    The project pre-build script can be accessed from the project settings dialog, under the build tab. When creating a pre/post build script, there are replacement values that can be inserted into the script. Replacement values provide access to contextual information from the update project. We’ll be taking advantage of the $UpdateVersion$ and $ProjectDirectory$ replacements to accomplish the goal.

    The goal of the pre-build script is to empty a working folder, and then add the two files that will be included in the update to the working folder. The two files will be the Director.Xml file and the application update package that matches the designated update version. The script will copy these files from a local folder that represents the primary application update folder, and will be addressed in the script using a relative file path from the current AppLife Update project file location. After the pre-build script runs, there will be a working directory that contains two files. The Director.Xml file and the application update package (a.b.c.d.zip) file that matches the defined update version number. Then, we just need to use an update action to add these files to the update. Here is the script.

    Set WorkingPath=$ProjectDirectory$\Current Update

    Set AppUpdatePath=$ProjectDirectory$\..\Application Updates

    Del %WorkingPath%\*.*

    Copy "%AppUpdatePath%\Director.Xml" "%WorkingPath%"

    Copy "%AppUpdatePath%\$UpdateVersion$.Zip" "%WorkingPath%"

    Using replacements, we have access to the version number of the update currently being built, and we also have access to the path of the .aup AppLife Update project file. We use this information to copy the correct update package from the correct folder.

    The Update Actions

    With the pre-build script, the files that we want to add to the update is going to be sitting in a folder named Current Update that is a sibling to the AppLife Update .aup project file. Normally, we wouldn’t care which order the files are copied during the update, and the most obvious update action to use would be the Add Folder Content action. This action would simply add both of the files to the update as the update is built, and then write them to the designated client directory as the update engine executes the action on deployed clients. In this case though, we do care about order. We want the update package file copied first, and then the Director.Xml file. Because of this, we’ll use the Masked Add & Replace files action. With this action, we can apply a mask to the files that will be added to the update package. The first action will add the update package, and the second action the Director file. By applying a mask of (*.zip), the update package is added to the update.

    clip_image002

    To add the Director.Xml file to the update, we could have chosen the Add & Replace Files action, but for consistency we use another Masked Add & Replace action with a mask of *.Xml.

    With these two actions in place, the appropriate update package file and the corresponding Director.Xml file is added to the update package and will be placed in the application updates folder on remote update servers. To publish an update, no changes are necessary to the update project. We simply open AppLife Update and walk through the publish wizard. When the update version is defined in the wizard, the correct application update package is automatically included.

    Posted at 28 August, 2012 | By :Brian Haas | Categories : AppLife Update | Software Updating |
  • Enabling .Net 3.5 on Windows 8 During an Application Update

    In Windows 8, the .Net Framework 3.5 is not installed by default, however Windows 8 includes a Feature on Demand (FoD) option for the earlier frameworks.

    clip_image001

    We can enable this feature during an application update by using the Deployment Image Servicing and Management utility (dism). During an application update, we’ll execute the following command line:

    dism /online /enable-feature /featurename:NetFX3 /all /NoRestart /Quiet

    We can use a Run Command Line update action to perform the work. We just need to ensure that the update has elevated permissions. If you are already configured for update elevation, either by use of the AppLife Update Windows service or by the UAC, this is already taken care of. If however, your normal updates are not elevated, then you must explicitly set this update to elevate via the UAC when you publish the update.

    Configuring the Update

    To accomplish the goal, we’ll create an action list and name it Win 8 FX 3. In this action list, we’ll add:

    • Run Command Line action
    • Restart Operating System action
    • Prevent application restart action

    Run Command Line

    This action will run the dism command. This command requires an operating system restart, so we’ll explicitly command not to restart, and then let the update take care of this using a Restart Operating System action.

    clip_image002

    Note that this action takes some time to complete.

    Restart Operating System

    This command will prompt the user that a restart is required.

    clip_image003

    Prevent Application Restart

    If the host application will ordinarily restart after the update completes, we can suppress this knowing that the operating system must be restarted to complete the update. Depending on the host configuration, this action might or might not be necessary.

    clip_image004

    Conditionally Execute the Action List

    We only want to run this action list if the host operating system is Windows 8 and the .Net Framework 3.5 is not already installed. So from the primary action list, we’ll detect the OS version and .Net Framework 3.5 install state, and then run the Win 8 FX 3 action list only when necessary. To detect the OS version, we use a Read Registry Value action to read and assign the OS version to a Shared Property we’ll name WinVersion.

    image

    To detect the .Net Framework install state, we’ll inspect another registry key.  Note that the dism tool can retrieve information on Windows features using the Get command, however using that approach would require code to parse the command return information.Reading directly from the registry doesn’t require any parsing code.

    image

    These shared properties can then be used as a condition to run the Win 8 FX 3 action list.

    image

    That completes the configuration of the update. Now all we need to do is ensure that the update will run elevated, if your application isn’t already set up to ensure this. When publishing, we can set this update to use the UAC for permissions elevation.

    Ensure Elevation for this Update

    clip_image007

    The host for this update must be capable of running on the .Net 4.0 framework, as this will be available on Windows 8 out of the box. After running this update, executables that target the .Net 2.0 through 3.5 framework will be able to run on the deployed system.

    Posted at 3 August, 2012 | By :Brian Haas | Categories : AppLife Update | Software Updating |
  • Execute Windows Installer (MSI) Databases during Application Updates

    Has your product prerequisites ever changed between versions and therefore required you to deploy a new Windows Installer package before your new product version can function? Have you ever needed to deploy a companion application along with your previously installed and AppLife Update maintained application? With AppLife Update, these challenges can be overcome by executing a Windows Installer package as part of your application update.

    Packaging and Executing an MSI in an AppLife Update

    It’s very easy to include a Windows Installer package with your application update and then execute that Msi on all of your remote systems. To accomplish this, all that needs to be done is to include the Msi file with your update by using an Add & Replace files action, and then run the Msi using the Execute Msi action.

    clip_image001

    The Update Package Directory is the temporary directory that the update engine creates and removes for the currently executing update and is easily accessed by other actions. If you want your Msi file to remain on the remote system after the update completes you would choose a different folder, such as a subdirectory of your application directory.

    After this update action executes, the Windows Installer package will be present on the remote system. To execute the Msi we’ll add an Execute Msi action. The Execute Msi action lets your define a <path> variable and then use that variable within an msiexec.exe command line. When defining the path variable, you can choose any of the available local paths, including the Update Package Directory path that we placed the Msi file in with the previous update action. To complete the path to the Msi file, any subdirectories as well as the Msi file name can be added to the subdirectory property. With the <path> variable defined, the msiexec command line can be constructed. To install the Msi, the /i command line option can be used. A command line of /i “<path>” is equivalent to the default Msi file behavior.

    clip_image002

    When this action executes, the Msi is executed on the deployed client.

    Conditionally Update Based on Local Information

    In the case of prerequisites, it might be necessary to first verify that the prerequisites are not already present before executing the installer package. There are a number of methods that can be employed for this purpose. With the Windows Installer product code, we can look up information about the product. For example, if I wanted to first verify that AppLife Update was installed before taking action on the client, I could look up the AppLife Update product code in the uninstall registry key. Using a Read Registry Key action, we can look up the uninstall string and even use it to uninstall. If the string is not present, we can use the information to infer that the product is not installed.

    HKEY_LOCAL_MACHINE\SOFTWARE \Microsoft\Windows\CurrentVersion\Uninstall\{0c2b1285-5119-44f5-9b68-edc749f18967}

    Using a Read Registry Value action, we can set a Shared Property to the value of the uninstall string, and default the value if the string cannot be read.

    clip_image004

    If we wanted to make the execution of the Msi action conditional on AppLife Update being installed (or not installed) we can add a conditional statement to the update action.

    clip_image006

    Uninstalling First

    Windows Installers can be configured to first uninstall the application, but this is not usually the default behavior when using Windows Installer creation tools. If you would like your update to first uninstall, we can use the uninstall string we just read from the registry using a Command Line Action. Alternatively, we can also use the Msi Action directly.

    clip_image008

    Silent Updating when Using the Elevated Permissions Service

    When your application is using the AppLife Update Windows Service for permissions elevation, it’s important to recognize that the Windows Installer will be executing under the Local System account user, and won’t be able to interact directly with the logged on user. For some installers, this could impact the way they operate. Running under the service, the installer must be able to run silently (using /q). In the event that the installer must interact with a user, the elevation service cannot be used for that update. When publishing the update, select the option to override the controller elevation settings and use the UAC elevation option instead. This will require an administrator to apply the update, but will allow the Msi to interact with them as they do so.

    Disabling the Elevation Service

    clip_image009

    Troubleshooting Updates that Deploy an Msi

    The AppLife Update engine logs activity to an event log as the update executes. However, when an Execute Msi action is executed, the log will only include information indicating the exact command line used and the msiexec return value. In order to investigate what actions the Msi performs, it is necessary to use the msiexec command line option to log the Msi operation. This option can take an explicit path. To write a log file to the install directory, you can use a Set Shared Property action to define a Share Property with the application directory path.

    clip_image011

    And use it to define where to write the log file to.

    clip_image013

    Conclusion

    In the course of maintaining an application, it is sometimes necessary to install new prerequisites or companion installers. Using AppLife Update, automating these actions and ensuring an effortless transition for your end-users is very easy. The update actions available within AppLife Update lets you package and deploy new Windows Installer packages, conditionally execute update actions, uninstall existing packages if necessary, and troubleshoot the update process before widespread distribution.

    Posted at 17 July, 2012 | By :Brian Haas | Categories : AppLife Update | Software Updating | Windows Installer |
  • Accessing Local Directories during an Application Update

    Most application files reside in the installation directory, referred to within AppLife Update as the Application Directory. The AppLife Update execution engine determines the Application Directory from the physical location of the executable that launches the update. When any of the file related update actions are added to an update action list, the default directory that is targeted is the Application Directory.

    clip_image001

    This is most often the location where files need to be added or replaced during an application update. Accessing paths relative to the Application Directory can be accomplished using the subdirectories property.

    clip_image002

    And navigating up the directory tree…

    clip_image003

    In addition to the Application Directory, you can target any of the well-known named folder locations as well, such as the current user’s profile directories.

    clip_image004

    Using an Explicit Path

    You’ll notice in the list of directories, there is an Explicit Path option. This option lets you specify the entire path to use for the file action. At first glance, this feature doesn’t look all that useful, but when combined with Shared Properties, it becomes a very nice feature.

    Expanding Shared Properties in Place

    Shared Properties can be used in many action properties. Most of the properties of built-in actions have the ability to expand a Shared Property in place. These properties are adorned with a blue icon indicating their support of this feature. A Shared Property is inserted using $$ delimiters, and during update execution, the value of the designated Shared Property is inserted in-place of the delimiter.

    clip_image005

    So for file actions, we can use a Shared Property to target an explicit folder, which opens up lots of possibilities because Shared Property values can be passed in from the host application, set by other update actions that can read from a database, the registry, xml config files, or custom actions running your own code.

    clip_image006

    An Example – Maintaining Office Templates

    Say your application installs templates for Microsoft Office and you need to maintain those templates during an application update. There is a default location for Office templates however this location is user configurable, so it could be different on every system. The default template location is located in the current user’s roaming application directory.

    CurrentUserRoamingAppDataFolder\Microsoft\Templates

    If the user has specified a custom template location, we can find this path in the registry.

    HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\Common\General - UserTemplates

    One caveat is that if the user has not specified a custom location, this registry key is not present. So in order to target the correct folder, we’ll need to read the user configured location from the registry, and then use that location with an Add & Replace files action. If the registry value is not present, we’ll also set the default value of this shared property to the correct default location by expanding another Shared Property.

    Action 1 – Add a Set Shared Property action and set a Shared Property to the current user’s local roaming AppData folder path. We’ll use this to set the default value in the next action.

    clip_image008

    Action 2 – Add a Read Registry Value action to get the User Configured template directory from the registry and assign the value to a new Shared Property. If the value doesn’t exist, we’ll set the default value with the path identified in action 1.

    clip_image010

    Action 3 – Add an Add & Replace Files action and use an explicit path to target the correct templates folder.

    clip_image012

    Using Shared Properties and explicit paths, we can easily access and maintain files and assemblies in any local directory that our application uses.

    Posted at 12 July, 2012 | By :Brian Haas | Categories : Application Deployment | AppLife Update | Software Updating |
  • Conditionally Perform Update Tasks using Shared Properties

    In order to maintain an installed software application on different hardware and operating environments, it is sometimes necessary to perform update actions based on the conditions at the local site or system. An example of this is when your application uses both 64 bit and 32 bit assemblies. Your installer places the appropriate assembly during initial installation, but in order to maintain that installation during updates we might need to take different action based on the local architecture. Another example might be maintaining different configurations, such as a Dev, QA, or Production installations. We might want to place debug symbols on a dev update, but not in production. Or we might set specific configuration settings differently, based on the environment. With AppLife Update, we can use information from the local installation to conditionally control the actions taken during the application update. We accomplish this by defining and setting Shared Properties based on the local system information and then using those Shared Properties to conditionally execute update actions.

    Shared Properties

    The AppLife Update engine execution context hosts a collection of name/value pairs, and this collection is named the Shared Properties collection. Shared Properties can be accessed by any Update Action in the update action list, hence the name Shared Properties.

    Shared Properties can be defined and set in a many different ways. The initial collection of shared properties can be passed into the update context from the host application. The ApplyUpdate method of the Update Controller has an overload that takes an IDictionary object of string values. The contents of this object are used to populate the collection of Shared Properties.

    Dictionary<string, string> sharedProperties = new Dictionary<string, string>();
    sharedProperties.Add("MyData1", mMyData1);
    			
    this.updateController1.ApplyUpdate(ApplyUpdateOptions.None, sharedProperties);

    If you are using the built-in user experience controls, your code doesn’t call the ApplyUpdate method directly. All of the user experience controls have a property called InitialSharedProperties that can be used to add values to prior to applying an update.

    updateDisplay1.InitialSharedProperties.Add("MyData1", mMyData1);
    

    Many of the built-in update actions that read information can set shared properties. The Database actions can read query results into a shared property. The Read Registry Value action, Read Xml Node action, and the Set Shared Property action can all set shared property values. Custom actions, most easily created using the C#/VB.Net dynamic code action, can access the Shared Properties collection directly through the context parameter.

    clip_image001

    It’s worth noting that while most of the actions read and write string values to the Shared Properties collection, custom actions can set and access any object data.

    Conditional Updating Based on Shared Properties

    Say we want to replace 64 bit or 32 bit assemblies, depending on the architecture of the system being updated. To accomplish this, we’ll add two Add & Replace files actions to our update action list, and then conditionally execute each action based on the value of a Shared Property. We can define the Shared Property with a Set Shared Property action. Processor type is one of the values that are available to set using this action. We’ll name the Shared Property ProcessorType.

    clip_image002

    After the action executes, the Shared Property named ProcessorType will contain a value of either 32 or 64, based on the current processor architecture. We can now use this value in the Conditional Statement of the two file actions.

    clip_image003

    This action will only be executed if the value of the ProcessorType Shared Property is “64”. The conditional for the 32 bit assemblies is obviously “32”. By using a Shared Property and conditional statements, we can use local system information to control the execution of the update.

    Posted at 11 July, 2012 | By :Brian Haas | Categories : AppLife Update | Software Updating |
  • Updating Software Operating on Erratic and Unreliable Networks

     

    Download:
    Example Project Source Code

    When your software operates in an unreliable networking environment, it can be very challenging to automatically maintain your software installation. These environments are quite common. Police cruisers and ambulances use laptops to run software in the field, relying on cellular technology to distribute updates. Traveling salesmen use proprietary laptop business software and are constantly going in and out of network coverage. Medical staff use their mobile pc’s in large medical facilities, where dropping connections in elevators and dead Wi-Fi spots is common place. In scenarios like these, professionals are using software that must be maintained. In today’s professional environments, software maintenance is expected to “just happen”, without interrupting the work of the professionals using the software. Software publishers who create software that operate in environments like these all face the same challenge of maintaining their software without requiring support staff to take possession of the hardware. The AppLife Update Solution provides the answer for many software publishers whose applications operate in environments like this.

    With the AppLife Update solution, software publishers create and publish self-contained update packages that migrate an installation from one version to another. These update packages are retrieved by the client software when network connectivity is present. Once the update package is retrieved, network connectivity is no longer required and the update can be applied, performing the work necessary to maintain the deployed installation. As the update package is downloaded, the partial download is cached locally so that any interruption in network connectivity will not require restarting from the beginning.

    The flexibility of the AppLife Update solution provides the ability to change the behavior based on known circumstances. When it is known that the software being maintained is going to operate in an unreliable networking environment, it is possible to handle network connectivity errors differently than normal. Normally a network connectivity error would be unexpected and the user would be notified of the situation. Instead, the application can postpone the update retrieval operation for a short period of time and try again. And try again. And try again, until the update retrieval succeeds and can be applied.

     

    Example Implementation

    In the example project accompanying this post, the updating functionality is completely automated. The implemented updating process can be described as:

    When the application launches, a background update check is performed. If an update(s) is available, the update packages are retrieved in the background and without user interaction. If network connectivity is lost, the retrieval is postponed and continually retried in the background without user interaction until the update is successfully retrieved. Once retrieved the user is prompted to either apply the update now, or when the application is closed. If the user elects to apply the update, the update is applied and the application restarted. If the update is deferred until the application exits, the update is applied as the application exits and the application is not restarted.

    The example project contains an Updater class that controls the update check and retrieval process. Inspecting the Updater class, you’ll see that the class maintains an AppLife Update Controller and uses the API methods and events of the update controller to pause and retry as network errors occur. When an update package is successfully downloaded, an event is raised, alerting the primary application that an update is ready to be applied. The implementation code in the primary application is very simple. An Updater class is instantiated and the Update Controller properties are configured. Once configured, the GetUpdateCompleted and GetUpdateProgressChanged events are hooked before calling the GetUpdateAsync method. That’s it. Any updates will be retrieved as the network allows. When the completed event fires, the Updater status is checked and the user is prompted to apply the update now or when the application exits.

    Implementation Details

    The Updater class is the heart of the implementation. It has a very simple interface:

    clip_image001

    The Updater class wraps an AppLife Update Controller and exposes a single method that implementing code will call to perform the entire update process.

    We want to take a look at the GetUpdateAsync method. This method calls the Update Controller’s CheckForUpdateAsync method and then returns. The update process continues in the CheckForUpdateAsyncCompleted event handler. If an update is present, the DownloadUpdateAsync method is called. When the download completes, the GetUpdateCompleted event is raised. When these asynchronous methods are called, any network errors will cause the completed event to fire, and the event argument’s Error property will indicate the cause of the error. Based on the error information, we can take appropriate action. In this example, we are considering any WebException or IOException to indicate a network error. Your implementation can improve on this, based on environment specifics. At any rate, when a network error is detected, the updater class goes into a wait mode and try’s the check/download again after a period of time. Eventually, the update download is completed, and the GetUpdateCompleted event is raised, triggering the client application to prompt the user.

    Of course, the user experience behavior is completely customizable with just basic coding. The AppLife Update Controller performs the heart of the technical challenges involved in this implementation, and the Update Engine is what lets you package up any work that is necessary to maintain and migrate your deployed installations. So I invite you to take a look at the example and evaluate it for suitability in your own environment. Feel free to contact our technical support team with any questions.

    Posted at 3 July, 2012 | By :Brian Haas | Categories : Application Deployment | AppLife Update | Software Updating |
  • Easily Modify .Config Files During an Application Update

    The beauty of .Net configuration files (.config) is that they let you easily change the behavior of your application for individual installations. This allows for a great deal of flexibility, especially with service related settings. With this flexibility though, also comes a maintenance challenge. Unlike all of your other application files, configuration files usually can’t be simply replaced during a maintenance update. Doing so would lose any customizations made to support the specific application installation. As your application evolves, it is inevitable that your configuration files will require modification. With AppLife Update, you can easily maintain .Net configuration files without replacing them by modifying the existing files. I’ll cover three different methods that you can use, based on the type and scope of the config file modification that is necessary.

    • Modify the existing config file directly using Xml Update Actions
    • Migrate specific settings from an existing config file to a new config file using Shared Properties and Xml Update Actions
    • Utilize custom .Net code to manipulate the config file during an update

    Modify the Existing Config File

    Using Xml Update Actions is great for adding elements and updating attributes. As an example, let’s say that we use appSettings in our application and we need to add a new appSettings value in support of a new feature. We can use an Add Xml Element update action to insert a new appSettings value into the existing config file.

    This is what the v1 application configuration file might look like:

    clip_image001

    But for v2, the configuration file might need to look like this:

    clip_image002

    To migrate version 1 installations to version 2, in addition to replacing the application assemblies we must add a new entry to the appSettings collection. To do this, we’ll use an Add Element update action.

    clip_image003

    When configuring Xml update actions, XPath expressions are used to reference the specific Xml elements that you are interested in reading and writing. To accomplish our goal, we will use an XPath expression to access the appSettings node, and then add a new element to that node. The config file is located in the Application Directory and is named Simple.exe.config.

    The XPath expression is /configuration/appSettings. The element that we are adding is:

    <add key=”key2” value=”value2” />

    The name of the element is add, and the new element has two attributes, key and value. Add a new Add Element update action to your update project and configure it as below.

    clip_image004

    With this action in place, the new element will be added to the configuration file when the update is executed.

    Another scenario where Xml actions are great is when we need to update a specific attribute. Using a Change Node action, the value of an existing appSettings entry is easily accomplished. For instance, consider the situation where in v3 of our application, we needed the key2 value to be modified to value3. This can be accomplished in a very similar process. Instead of adding an Xml Element, we can use the Change Node update action to modify an existing value. To accomplish this, we need to know the XPath that references the specific value that needs to be changed. In this case, the XPath expression is /configuration/appSettings/add[@key=”key2”]/@value.

    clip_image005

    Adding a Change Node action configured like this will modify the attribute value to “value3”.

    Migrate Existing Values to a new Config File

    In some circumstances where there are wholesale changes to a config file that would require extensive modifications to the existing file, it could require less effort to extract specific values that are unique to the installation and migrate them to a new config file. In this scenario we use Xml Actions to read specific information from the existing config file and store that information in Shared Properties. We can then replace the config file with an Add & Replace Files update action, and finally use Xml actions to write the information that we stored into the new config file.

    Revisiting the previous example, we’ll take this approach for the necessary modifications. We’ll read and store the value of the key1 appSetting, then replace the config file and modify that value in the newly replaced configuration file.

    Reading the existing value, we’ll add and configure a Read Xml Node Action. Using this action, we set the config file name and XPath just as before. We’ll also designate a Shared Property to store the attribute value. Shared Properties are essentially variables that are scoped across the context of the executing updates. They allow for information to be shared between update actions. The Read Xml Node action will assign the string value of the designated attribute to the designated Shared Property.

    clip_image006

    With the value of the existing attribute stored, we can replace the application configuration file using an Add & Replace Files action.

    clip_image007

    After this action executes, the application configuration file will be replaced with a new updated version. However, the value of the attribute we are interested in will also have been reset to its default, non-customized value. To complete the update process we need to use the value that we previously stored to change the new configuration file. A Change Xml Node update action will update the attribute value. When using string value Shared Properties, the value of the Shared Property can be expanded using $SharedProperty$ syntax.

    clip_image008

    The Change Xml Node action restores the value originally set on the specific client and completes the update process.

    Utilize .Net Code to Modify an Existing Config File

    When using Xml Actions and Shared Properties, we read and write string values to the config file. In some circumstances, it can be beneficial to approach the Xml maintenance process within code, where the Xml can be manipulated in fragments. This too can be easily accomplished during an update using the Dynamic Code Action. A Dynamic Code action allows you to easily create a custom update action, which extends the UpdateAction class and overrides, at a minimum, the Execute and RollbackExecute methods.

    clip_image009

    With a Dynamic Code action you can use C# or VB.Net code to manipulate the deployed client. Here we use the context parameter to access the information we need to accomplish our goal in code. You can access local directory information as well as the Shared Properties collection. With this information, we load an XmlDocument and manipulate the file within our custom code.

    clip_image011

    Summary

    During software maintenance updates, application configuration files that are uniquely modified for each installation cannot be simply replaced as changes are made to support new versions. These config files must be modified in-place during the maintenance process. Using AppLife Update, application configuration files can be easily maintained throughout the life of the application and we present three different approaches to accomplishing the goal.

    Posted at 31 May, 2012 | By :Brian Haas | Categories : Application Deployment | AppLife Update | Software Updating |
  • Updating a Windows Service

    For applications that deploy a Windows Service, updating the installed service can present a maintenance challenge. This is a scenario where integrating AppLife Update makes a difficult task extremely easy to accomplish. Using AppLife Update actions, a Windows Service can be updated in three easy steps.

    1. Stop the Service using a Stop Service update action.
    2. Replace the Service assemblies using one of the available file replacement actions.
    3. Restart the Service using a Start Service update action.

    Tada! Big maintenance challenge accomplished.

    An Example

    The release of AppLife Update 4.5 included a few very small changes to our AppLife Update Windows Service. Specifically, in previous versions, if the Windows Application Event Log was full and not configured to replace old events, our service would not apply an update. This issue affects a very small number of systems as since Windows Vista, the default logging behavior is to replace old log events when the event log is full, and the event log has to actually be full to cause an issue. For customers who use our AppLife Update Windows Service, if you choose, you can update the AppLife Update Windows Service on your deployed clients during your next application update. This is optional because if the logging issue isn’t a concern, you can leave the previous version alone. Any past version of the elevation service will operate properly with the latest AppLife Update controller. If you do so choose, here is how you can update the AppLife Update Windows Service (or any other Windows Service for that matter).

    Stop the Service

    To stop the service, we need to know the service name. If you don’t already know the name of the service you are updating, it can be found in the Services manager.

    image

    Open your application update project file (.aup). Add a Stop Service action to your update. Set the Service to Stop property to the name of your service. In this case, the service name is KjsUpdateService2.

    image

    Replace the Service Assemblies

    We use an Add & Replace files on restart action to update the assemblies. The AppLife Update Windows service is initially deployed using an MSI merge module, and is always installed to the Common Files Folder\AppLifeUpdateService2 folder. To update the service, we’ll select the Common Program Files (x86) client folder and set the appropriate sub-directory, and then add the two assemblies that constitute the service. Choosing the x86 variant of the Common Program Files folder will ensure we target the x86 common files folder on x64 operating systems. Using the non x86 Common Program Files directory targets the x64 folder on 64-bit operating systems. On x86 operating systems, there is only one common program files directory, and either variant will target the correct folder.

    image 

    Note: When updating most Windows Services, even when a service updates itself, the service assemblies can be replaced immediately, without deferring to a restart. The AppLife Update service core assembly houses a class used to marshal information between the User Interface process and the service started worker process. For this reason, even though the service is successfully stopped, a lock is still being maintained on the core service assembly while the update is executed. Because this lock is not released until the update completes, the file replacement is deferred until restart. We do not need to force an operating system restart, as the previous update service can be restarted and function properly until the system is restarted. If a restart were necessary, we could include a Restart Operating System action to accomplish this.

    The service assemblies ship with AppLife Update already embedded into the AppLifeUpdateService.msm merge module. After an installation, the assemblies will be in the common program files folder and can be extracted from there. After this action executes, the Windows Service will be updated. Now we just need to restart the service.

    Restarting the Service

    The service is restarted by adding a Start Service update action. The action is configured by defining the name of the service to restart. In this case it is again, KjsUpdatService2.

    image

    That’s it! Windows Service update completed.

    But My Service is My Application?

    This example assumes an existing update process exists and can be utilized to update the Windows Service. This is usually an installed application that utilizes the Windows Service, and can take responsibility for updating it. A stand-alone Windows Service can become “Self Updating” just as easily by integrating an update process using an AppLife Update controller. There is one point to make in this scenario. When applying an update, you want to use the option to instruct the update controller not to shut down the host application (the service). The Stop Service update action performs a proper service shutdown through the use of the Windows Service Control Manager, and is the recommended method to use when stopping a service for an update.

    Posted at 9 May, 2012 | By :Brian Haas | Categories : Application Deployment | AppLife Update | Software Updating |
  • Using Callable Action Lists Part II

    In my previous post I used a callable action list along with Xml Update Actions to read all of the database connection strings identified in an app.config file, then iterate and update each one of the databases during an application update. The approach I took to accomplish the goal only used built-in Update Actions that are available to me in the Actions Palette. I purposefully chose not to use dynamic code actions (custom update actions) to make a point of what we can accomplish without resorting to writing our own code. However, what can be accomplished with a little custom code is extremely powerful, so now I’m going to revisit the objective, removing the intent of relying only on built-in actions.

    Identifying the Databases to Update

    In this scenario, the local databases that need to be updated during our application update are listed in the application configuration file. This is very convenient, especially when I want to use built-in actions to find the information. But what if the databases were not so conveniently discoverable? What if you first had to connect to a database server and search through all of the databases on the server for a specific naming convention? What if the databases were passed into the update process from the host application? Using a dynamic code action, scenarios like this can be easily handled.

    Custom Update Actions and Shared Properties

    The feature duo that makes what might initially sound difficult to accomplish during an application update magically easy using AppLife Update are Custom Actions and Shared Properties. Custom Actions are simply classes that inherit from an UpdateAction base class and implements at a minimum, an Execute method and a Rollback method. Shared Properties are a collection of objects that are scoped to the context of the update and can be accessed from any update action.

    For our purposes, we want a custom update action that will read the list of databases from an application configuration file. The C#/VB.NET Code action lets me write this custom action directly within the update creation software.

    Note:  Custom Actions can also be created in Visual Studio and compiled to an assembly.  Custom Action assemblies can be added to an update project through the Project..Settings dialog, or added the Custom Actions folder located within the AppLife Update install directory.

    clip_image001

    Here is the code:

    Code Snippet
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Text;
    4. using Kjs.AppLife.Update.Engine.Core;
    5. using System.Xml;
    6. using System.IO;
    7.  
    8. namespace DynamicCodeActions {
    9.     public class DynamicAction1 : UpdateAction {
    10.  
    11.         public override void Execute(UpdateContext context) {
    12.             //Read connection strings from app.config
    13.             XmlDocument configDoc = new XmlDocument();
    14.             configDoc.Load(Path.Combine(context.ApplicationDirectory, "CallActionListExample.exe.config"));
    15.  
    16.             XmlNodeList connStrings = configDoc.SelectNodes("/configuration/connectionStrings/*");
    17.             List<string> connectionStrings = new List<string>();
    18.             foreach(XmlNode node in connStrings) {
    19.                 connectionStrings.Add(node.Attributes["connectionString"].Value);
    20.                 context.Log.WriteLine(string.Format("Added connStr: {0}", node.Attributes["connectionString"].Value));
    21.             }
    22.             if(connectionStrings.Count > 0) {
    23.                 context.SharedProperties.Add("ConnectionStrings", connectionStrings);
    24.                 context.SharedProperties.Add("ExecuteDBUpdate", true);
    25.                 context.SharedProperties.Add("CurrentConnectionString", "");
    26.             } else {
    27.                 context.SharedProperties.Add("ExecuteDBUpdate", false);
    28.             }
    29.         }
    30.  
    31.         public override void RollbackExecute(UpdateContext context) {
    32.             //Add code here to undo work that was performed in the Execute
    33.             //method.  The method is not performed if the Execute method
    34.             //is not completed.
    35.  
    36.             context.SharedProperties.Remove("ConnectionStrings");
    37.             context.SharedProperties.Remove("ExecuteDBUpdate");
    38.  
    39.  
    40.         }
    41.     }
    42. }

    Notice that through the context parameter, the code can access the Shared Properties collection as well as other properties, such as the physical path to the host application. This code simply opens the application configuration file and reads the database connection strings. These strings are then added to a generic List of strings, and that List is added to the Shared Properties collection. If the list is not empty, another Shared Property is added that will be used in a conditional statement.

    Manipulating the List from other Actions

    With the list of database connection strings in the Shared Properties collection, we can call the recursive callable update action list to update the databases. This in-memory list takes the place of the copied app.config file used in the original post. From within the Update Databases action list, we can read and manipulate the Shared Properties collection with other custom update actions.

    Read the Next Connection String

    clip_image002

    Remove the Item after the Database is Updated

    clip_image003

    Conclusion

    Using Update Actions and Shared Properties during an application update allows you to very easily accomplish complicated processing on deployed clients. The C# / VB.NET update action lets you add your own code logic to your update, and using Shared Properties, your code can easily interact with built-in actions as well as other custom actions.

    Download Example AppLife Update Project

    Posted at 1 May, 2012 | By :Brian Haas | Categories : AppLife Update | Software Updating |
  • Using Callable Action Lists to Update Multiple Databases During a Client Update

    The recently released AppLife Update 4.5 includes many new features, one of which is the ability to create independent, callable action lists. By combining callable action lists with Shared Properties and applying conditional statements to update actions we can more easily accomplish advanced updating activity. One scenario which we can use to demonstrate this functionality is when an application uses multiple local databases. In order to update the installed application, all of the databases that are present must be updated. In this scenario an update will need to be able to:

    1. Identify all of the databases that are present.

    2. Iterate each of the local databases, applying the necessary change script to each one.

    3. Update the application assemblies.

    For this example, the list of databases will be discovered by inspecting the application configuration file. Each database connection string is listed in the connectionStrings segment of the configuration file. For each of the listed databases, we’ll connect to the database, start a transaction, run a SQL script, commit the transaction and close the connection.

    Note that all of the update actions and logic is packaged into a single, stand-alone update package. The update process embedded into the application discovers the new update, downloads it, and then initiates it. Once initiated, the Update Engine executes the update actions that perform the work. This example focuses completely on the update actions. No mention is made of the update process integrated into the application.

    Identify and Manage the Local Database List

    To read the databases that are present and manage the list as the databases are updated, I am going to read an item from the connectionStrings configuration element, update the database identified within it, and then remove the element from the configuration file. Using this method, I can accomplish all of the work using built-in update actions. This is not the only option available. Using Dynamic Code Actions offers more flexibility and an alternative approach. I’ll perform the same work using Dynamic Code actions in my next blog post.

    Now, I mentioned that as we update the databases I am going to remove the element from the config file. We don’t want to modify the actual application configuration file so the first thing that I am going to do is copy the config file to the working update directory. This is a directory created by the update engine and it is deleted when the update ends. I’ll accomplish this by using a Run command line update action. This action includes a helper feature that allows us to use common directories to define two path variables. The Application Directory is the physical path of the application that launched the update. This is where the application configuration file resides. The Update Package Directory is the physical path to the temporary working directory that is created for this update by the update engine. I define <path1> to be the path to the application configuration file, and I define <path2> to be the path of my copy of the config file. I’ll call it config.xml. With the two paths specified, I’ll use them in the actual command line that copies the config file:

    copy “<path1>” “<path2>”

    clip_image001

    To read the entries in the config file, I’ll use a Read Xml Node action. To use this action we specify an Xml file to read, define an XPath expression to identify the node value we are interested in, and then provide a name of a Shared Property to hold the string value of the Xml Node. The Shared Property can then be accessed and used by other actions as well as in conditional statements. I’ll be doing both with this Shared Property.

    clip_image002

    Here is what the config file section looks like:

    <configuration>

    <connectionStrings>

    <add name="Db1" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=TestDb1;Integrated Security=True"/>

    <add name="Db2" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=TestDb2;Integrated Security=True"/>

    </connectionStrings>

    </configuration>

    I am interested in the connectionString, so my XPath expression is /configuration/connectionStrings/add/@connectionString

    If multiple nodes are found, the action is configured to read the first node, and if no node is present a default value of None is assigned. We’ll use this in a conditional statement. If a node is present, a Shared Property with a key of ConnStr will be populated with a local database connection string. Next we’ll use a callable action list to update this database using SQL Server update actions, remove the connection string from our working config file, and recursively call itself until all of the databases represented in the config file are updated. If the ConnStr Shared Property does not equal the value “None”, we call the action list.

    clip_image003

    Update the Database

    The databases I am updating are SQL Server databases. Therefore I am using the SQL Server Update Actions that are also new to AppLife Update 4.5. Note that there are separate provider-Independent database actions available that can be used for updating any type of database. Using the SQL Server Actions, for each database we are going to:

    1. Open a Database Connection. I’ll configure the action to place the database in single-user mode.

    2. Begin a SQL Server Transaction.

    3. Execute a database query.

    4. Commit the SQL Server transaction

    5. Close the SQL Connection

    To open the connection, I set the connection string directly, and then use the ConnStr Shared Property we already defined. For many built-in actions, you can use Shared Properties that are strings by using a $SharedPropertyKey$ syntax. Wherever this is used, the Shared Property string value is expanded in-line during update execution. Notice that the connection itself is added to the Shared Properties collection using the defined key. Here the key is named SqlConection. We’ll use this Shared Property in the other database actions.

    clip_image004

    With a SQL Connection open, I’ll start a transaction using the Begin SQL Server Transaction action. To use this action we specify the connection to use and provide a Shared Property key name for the transaction. The transaction Isolation Level can also be specified. If the update fails, this transaction will be rolled back automatically unless the transaction is committed by a Commit SQL Server transaction action.

    clip_image005

    With the transaction started, it can be used by one or more Run SQL Server query actions. In this example, I’ll just add a table.

    clip_image006

    Next, I’ll commit the SQL transaction and close the database connection. Taking this approach means that should any of the database updates fail, the database changes made in all previously updated databases would not be rolled back because they have already been committed. I chose this approach for simplicity, however the update could be refactored to maintain all transactions open until all of the databases have been updated, then iterate the transactions and commit each one. Using this alternate approach, should any SQL query fail, all databases would roll back their changes.

    clip_image007

    Closing the connection by specifying the Shared Property key…

    clip_image008

    Remove the Database from the Working Xml File

    With the designated database updated, I am going to remove the connection string from the working Xml file using a Delete Xml Node action. To use this action, I specify the Xml file and as XPath expression identifying the node of interest, just like we did when defining the connection string. The node we are interested in is the connection string entry with the attribute value that matches the connection string of the database that we just updated.

    clip_image009

    With the node removed from the working file, we’ll again use a Read Xml Node action to read the next connection string in the file. If there is another connection string available, we’ll assign it to the ConnStr Shared Property. Otherwise, just like before, if no connection strings are left the value of the Shared Property will be set to “None”.

    clip_image010

    And now as long as the value of the ConnStr Shared property is not “None” we’ll call this same action list again, updating the next database in the list.

    clip_image011

    This process is repeated for all of the databases identified in the connectionStrings configuration element.

    Replace the Application Assemblies

    To complete this update, I’ll use an Add & Replace Files action to replace the main application executable.

    clip_image012

    Summary

    By using the new callable action list feature and the Shared Properties collection, we are able to read the list of local databases from the application configuration file and iteratively update each one. The new features of AppLife Update 4.5 provide more power and flexibility while maintaining the robust, transactable operation of the AppLife updating engine. In a follow-up blog post, I’ll use Dynamic Code actions and custom C# code instead of Xml Actions to read the connection strings and use a collection object instead of a temporary file to manage the databases.

    Download Example Project

    View Execution Log

    Posted at 20 April, 2012 | By :Brian Haas | Categories : AppLife Update | Software Updating |
  • Terminal Services Application Updating

    The AppLife Update solution is a perfect fit for maintaining applications that operate in multi-user terminal services environments. In a terminal services installation, there are likely many users simultaneously running your application. Application maintenance solutions must account for the fact that there can be multiple instances of an application running at one time as any running instance will maintain a lock on files and assemblies that must be replaced during an update process. The AppLife Update Solution ensures that all running instances of an application are shutdown prior to starting an update, and this is accomplished through a built-in Inter-process communications (IPC) feature. The IPC employed within AppLife Update communicates across all users and will shut down all instances of an application running in a terminal services environment, making the solution a perfect fit for maintaining terminal services hosted applications.

    Out of the box, AppLife Update will shut down all instances of an application and allow you to update a terminal services application. There is however some customizations that can be applied to an application that is known to be targeting terminal services that will improve the users application updating experience.

    Terminal Services Application Updating with AppLife Update

    User Experience Customizations

    The AppLife Update API provides an opportunity for the integrating developer to interact with the IPC process and update initiation (starting) procedure. We can use this opportunity to improve the user experience. For the instance that initiated the update, we’ll display an indeterminate progress dialog as all instances are being shut down, and for the non-initiating instances, we’ll display an informative dialog for a short period of time indicating that the application is about to be closed for maintenance. Further enhancements could allow terminal services users to cancel the update process, or perform additional work before the shutdown.

    Code Snippet
    1. private void checkForUpdatesToolStripMenuItem_Click_1(object sender,
    2.             EventArgs e) {
    3.         if(updateController1.ShowCheckForUpdateDialog(this,
    4.             ErrorDisplayLevel.ShowExceptionMessage) == DialogResult.OK) {
    5.             if(updateController1.ShowDownloadUpdateDialog(this,
    6.                 ErrorDisplayLevel.ShowExceptionMessage) == DialogResult.OK) {
    7.                 //Launch the update from another thread
    8.                 //To better accomodate terminal services
    9.                 //installations, the UI will remain
    10.                 //responsive as all of the other
    11.                 //instances of the application are closed.
    12.  
    13.                 BackgroundWorker worker = new BackgroundWorker();
    14.                 worker.DoWork += new DoWorkEventHandler(worker_DoWork);
    15.                 worker.RunWorkerAsync(updateController1);
    16.                 ApplicationUpdateInitiatedDialog dlg =
    17.                 new ApplicationUpdateInitiatedDialog(true);
    18.                 dlg.ShowDialog(this);
    19.             }
    20.         }
    21.     }
    22.  
    23.     private void worker_DoWork(object sender, DoWorkEventArgs e) {
    24.         //Since the ApplyUpdate method call is a
    25.         //blocking call, and we want the UI to remain
    26.         //response as the user waits for all instances
    27.         //to close, we'll initiate the update on a
    28.         //background thread.
    29.  
    30.         UpdateController controller = e.Argument as UpdateController;
    31.         if(controller != null) {
    32.             controller.ApplyUpdate(ApplyUpdateOptions.AutoClose);
    33.         }
    34.     }
    35.  
    36.     private void updateController1_UpdateStarting(object sender,
    37.             UpdateStartingEventArgs e) {
    38.         //An update has been an initated and this
    39.         //application will shutdown. This dialog will
    40.         //inform any other users that the application
    41.         //is about to shutdown on them. Showing this
    42.         //dialog is import for Terminal Services
    43.         //installations. Note: It is possible to
    44.         //allow other users to cancel the ongoing
    45.         //update process
    46.  
    47.         //This dialog is shown for 5 seconds
    48.         //before it is closed automatically
    49.         if(!e.IsInitiatingController) {
    50.             ApplicationUpdateInitiatedDialog dlg =
    51.         new ApplicationUpdateInitiatedDialog(false);
    52.             dlg.ShowDialog(this);
    53.         }
    54.     }
    55. }

    Prevent Users from Restarting During the Update

    During the actual update, the application files must be unlocked, and remain unlocked throughout the process. If a terminal services users attempts to start the application using their application shortcuts, the application assemblies could become locked and prevent the update form succeeding. To prevent this, we’ll make the first action taken during the update be to rename/remove the launching executable. If the launching executable is to be replaced during the update process, we’ll perform this action as the last step of the update. By taking this action, terminal services users will not be able to launch the application during the update process from existing shortcuts.

    clip_image001

    Download Terminal Services Example Project

    Posted at 21 March, 2012 | By :Brian Haas | Categories : Application Deployment | AppLife Update | Software Updating |
  • No IT Needed

    When deploying custom software applications at the enterprise level it is almost always necessary to coordinate the release of maintenance updates with each customer’s IT department. This is sometimes required for QA and software validation, but most often it’s because the IT department holds the responsibility of pushing software updates out to the individual PCs.

    No IT Needed

    For you, the software vendor, you need maintenance patches to be installed quickly, sometimes very quickly, to ensure optimal user experience. For them, the IT dept, your software maintenance patch is just another of many tasks in the work queue. It won’t help to plead with them how important your release is. They support all departments, and every department thinks their needs are greater than the other guys, so they’ve heard it all before. This leaves you, the software vendor, potentially way down on the IT task queue. Fortunately for you, AppLife Update provides the tools to keep your deployed applications maintained without relying on the IT guy.

    What are those tools, you ask? Why it’s the AppLife Update solution, consisting of:

    • Update Controller
      This .Net control integrates into your application to manage discovery, download, and initiation of your maintenance updates.
    • Update Permissions Elevation Windows Service
      This Windows Service deploys with your application and securely applies your updates under the privileges of the local system account. Using the service your application, running under a limited rights user, can still maintain your installation without administrative support.
      **Initial deployment requires administrative privileges.
    • Update Engine
      The update engine is downloaded by the Update Controller and performs the update on the deployed client. The update engine can execute the Windows Installer packages that you are already creating to update your software. In addition, it can do so much more. There are many built-in update actions to help you maintain your deployed software, and you can even write your own update actions in C# or Vb.Net

    With these tools, and a day’s time, you can cast away those IT guy ties and take control of your application maintenance requirements, saving you and your customer time and money.

    Posted at 6 September, 2011 | By :Brian Haas | Categories : Application Deployment | AppLife Update | Software Updating |
  • Implementing a Silent Updating Process

    For many applications, it is not desirable to leave the decision of whether or not to update an application to the end-user. In fact, it is sometimes desirable to craft an updating process that operates silently, with no user interaction at all. AppLife Update makes it very easy to implement such an update process. In this blog post, I’ll walk through implementing a silent updating process.

    The Process

    When our demo application starts up, we’ll check for updates asynchronously in the background. If an update is available, we’ll asynchronously download the update in the background. To make the process the least intrusive to the user, our process won’t take any action when the download completes. Since the downloaded update package is cached locally as it downloads, it will be available the next time the application is restarted. Upon application startup, we’ll check to see if an update is fully downloaded and if so, go ahead and apply the update. If the update is not yet fully downloaded, the download will pick up where it left off.

    Handling Unexpected Errors

    Many things can go wrong as we check for and download updates over a network, and since our process is being performed silently, we’ll need to handle any errors that occur and decide what to do about it.

    We’ll also need to be able to identify errors during the silent update execution. When an update is applied, our application is shutdown so that the application assemblies can be replaced. When the update process finishes, the application is restarted automatically. During startup, we’ll look at the results of the last update to see if any errors occurred. If any errors occurred, we can inform the user or send an administrative notice to support.

    Now that we have a plan, we can go forward with implementation.

    Implementation

    With the desired behavior identified, we’ll implement this updating process using AppLife Update. To start, we’ll create a new Windows Forms application and add an Update Controller to the main form from the AppLife Update toolbox palette.

    image

    The Update Controller application programming interface (API) will provide all of the functionality we need to accomplish our identified update process. Once the update controller is added to your form, go ahead and set up a new project using the control smart tag. This will create an AppLife Update project that you’ll use to create and publish updates for your application.

    Note: The Update Controller does not need to reside on a form. You can create an Update Controller and configure it programmatically in any .Net application.

    image

    Now that we have an Update Controller in the application and a project setup, we’ll implement our desired update process.

    Checking For Updates

    To check for updates, we’ll use the CheckForUpdateAsync method on the Update Controller. This check is performed asynchronously, and when the check completes, the CheckForUpdateCompleted event is raised.

       1:  using Kjs.AppLife.Update.Controller;
       2:   
       3:   
       4:  public Form1() {
       5:      InitializeComponent();
       6:   
       7:      //check for updates
       8:      updateController1.CheckForUpdateCompleted += 
       9:        new CheckForUpdateCompletedEventHandler(
      10:            updateController1_CheckForUpdateCompleted);
      11:      updateController1.CheckForUpdateAsync();
      12:  }
      13:   
      14:  void updateController1_CheckForUpdateCompleted(object sender,
      15:      CheckForUpdateCompletedEventArgs e) {
      16:      if(e.Result == true) { 
      17:          //An update is availabe
      18:   
      19:      }
      20:  }

    After the check completes, we can check to see if the update is already downloaded by inspecting the IsDownloaded property of the update. If the update is downloaded, we can go ahead and apply the update. If it is not, we’ll initiate the download. The download will pick up from where any previous instance left off. When the download process completes, the DownloadUpdateCompleted event will be raised. We won’t take any action when the download completes, but we will use this event for error handling later. We are not showing download progress in this implementation, but there is also a DownloadUpdateProgressChanged event to monitor download progress.

       1:  public Form1() {
       2:      InitializeComponent();
       3:   
       4:      //check for updates
       5:      updateController1.CheckForUpdateCompleted += 
       6:        new CheckForUpdateCompletedEventHandler(
       7:          updateController1_CheckForUpdateCompleted);
       8:      updateController1.DownloadUpdateCompleted +=
       9:         new AsyncCompletedEventHandler(
      10:          updateController1_DownloadUpdateCompleted);
      11:      updateController1.CheckForUpdateAsync();
      12:  }
      13:   
      14:  void updateController1_DownloadUpdateCompleted(object sender,
      15:        AsyncCompletedEventArgs e) {
      16:      //Download completed. Ready to apply on next startup.
      17:  }
      18:   
      19:  void updateController1_CheckForUpdateCompleted(object sender,
      20:        CheckForUpdateCompletedEventArgs e) {
      21:      if(e.Result == true) { 
      22:          //An update is available
      23:          if(updateController1.CurrentUpdate.IsDownloaded == true) {
      24:              //the update is already downloaded, go ahead and apply it.
      25:          } else { 
      26:              //start the download
      27:              updateController1.DownloadUpdateAsync();
      28:          }
      29:      }
      30:  }

    Applying the Update

    With the update downloaded, we can apply the update. We want to apply the update silently, so we’ll pass in a parameter that prevents the update window from being displayed. This method call will close the application, launch the update process, and restart after the update completes.

       1:  void updateController1_CheckForUpdateCompleted(object sender, 
       2:        CheckForUpdateCompletedEventArgs e) {
       3:      if(e.Result == true) { 
       4:          //An update is availabe
       5:          if(updateController1.CurrentUpdate.IsDownloaded == true) {
       6:              //the update is already downloaded, go ahead and apply it.
       7:              updateController1.ApplyUpdate(ApplyUpdateOptions.NoUpdateWindow);
       8:          } else { 
       9:              //start the download
      10:              updateController1.DownloadUpdateAsync();
      11:          }
      12:      }

    That’s it! We have implemented a silent update process, and in a perfect world we’d be done. But we don’t live in a perfect world, and unexpected events occur. Since this process is completely silent to the user, we’ll need to prepare for error conditions programmatically and take appropriate actions.

    Error Handling

    Handling errors that occur during the update check and download process is straightforward. The asynchronous event handlers can check for errors that occurred and look at the specifics of the error to aid in determining how to handle the error. If you are using the http protocol for updating, the inner exception is probably a WebException class, which provides additional error information. For instance, this information could be used to ignore connectivity errors. For this demonstration, we’ll display a message box if any errors occur during the update check or download process.

     

       1:  void updateController1_DownloadUpdateCompleted(object sender,
       2:        AsyncCompletedEventArgs e) {
       3:      //Download completed. Ready to apply on next startup.
       4:      if(e.Error != null) {
       5:          //An error occurred.
       6:          if(e.Error is DownloadException) {
       7:              //A download exception is thrown when something unexpected happens.
       8:              //The InnerException property will hold the exception that occurred.
       9:              string errorMsg = "";
      10:              if(e.Error.InnerException != null) {
      11:                  errorMsg = e.Error.InnerException.Message;
      12:              } else {
      13:                  errorMsg = e.Error.Message;
      14:              }
      15:              MessageBox.Show(
      16:               string.Format("An error occurred downloading an update: {0}",
      17:                 errorMsg));
      18:          }
      19:      }
      20:  }
      21:   
      22:  void updateController1_CheckForUpdateCompleted(object sender,
      23:        CheckForUpdateCompletedEventArgs e) {
      24:      if(e.Error != null) {
      25:          //An error occurred.
      26:          if(e.Error is DownloadException) { 
      27:              //A download exception is thrown when something unexpected happens.
      28:              //The InnerException property will hold the exception that occurred.
      29:              string errorMsg = "";
      30:              if(e.Error.InnerException != null){
      31:                  errorMsg = e.Error.InnerException.Message;
      32:              }else{
      33:                  errorMsg = e.Error.Message;
      34:              }
      35:              MessageBox.Show(
      36:            string.Format("An error occurred checking for updates: {0}",
      37:                errorMsg)); 
      38:          }
      39:      }
      40:  
      41:   

    Detecting a Failed Update Execution

    As an update is executed, the application being updated is shutdown. When an update is executed with a user interface, any errors that occur would be presented to the user through the visual updating interface. Since we are applying this update silently, we will need to inform the user of any errors that occur another way. After the update completes, the application is restarted. We can use methods of the Update Controller to easily investigate the results of the last update that was applied. We’ll use this method to look up what happened, and inform the user of any errors that occurred.

       1:  InitializeComponent();
       2:   
       3:      //check for updates
       4:      updateController1.CheckForUpdateCompleted += 
       5:        new CheckForUpdateCompletedEventHandler(
       6:          updateController1_CheckForUpdateCompleted);
       7:      updateController1.DownloadUpdateCompleted += 
       8:        new AsyncCompletedEventHandler(
       9:          updateController1_DownloadUpdateCompleted);
      10:      
      11:      //Read last update results
      12:      LastUpdate lastUpdate = updateController1.ReadLastUpdateInformation();
      13:      if(lastUpdate != null &&
      14:        lastUpdate.Result == UpdateResult.Failure && 
      15:        lastUpdate.StartingVersion == updateController1.Version) {
      16:          //An update failed. Prompt the user.
      17:          if(MessageBox.Show(string.Format(
      18:        "An unexpected error occurred while silently applying an update:
      19:      {0}\n\nWould you like to retry the update?",
      20:         lastUpdate.ErrorText), "Update Error", MessageBoxButtons.YesNo) == 
      21:          DialogResult.Yes) { 
      22:              //launch an interactive update
      23:              updateController1.UpdateInteractive(this);
      24:          }
      25:      } else { 
      26:          updateController1.CheckForUpdateAsync();
      27:      }

    Conclusion

    Using the AppLife Update API, you can quickly and easily implement a non-interactive silent updating process that can be used in any .Net application. The application checks for, and downloads updates asynchronously. When the application launches and an update has been fully downloaded in a previous session, the update is applied silently. If any errors occur, the user is notified. The example can be easily extended and improved as necessary to fit specific updating requirements.

    Posted at 23 February, 2011 | By :Brian Haas | Categories : AppLife Update | Software Updating |
  • How to Hide the Error When Out of Network Range

    All of the visual updating controls that ship with AppLife Update show an error icon and message whenever an update check fails.  Sometimes though this isn't the most desirable behavior.  For instance, if your application runs on a laptop that is frequently moving in and out of network coverage.  In a situation like this, an update check failure is expected and you probably don’t want to display a concerning error icon to your end user.

     

    image

     

    To address this, we can look at the results of an update check and check to see why the error occurred.  If the issue is a network connection error, and we expect spotty network connectivity, we can choose to hide the control, instead of displaying an error to the user.

    By listening for the CheckForUpdateCompleted event of the Update Controller, information about the error can be inspected and we can hide the control if a connectivity issue is discovered.

       1:  private void updateController1_CheckForUpdateCompleted(object sender,
       2:       Kjs.AppLife.Update.Controller.CheckForUpdateCompletedEventArgs e) {
       3:      if(e.Error != null &&
       4:          e.Error.InnerException != null &&
       5:          e.Error.InnerException is WebException) {
       6:          WebException ex = e.Error.InnerException as WebException;
       7:          if(ex.Status == WebExceptionStatus.NameResolutionFailure ||
       8:             ex.Status == WebExceptionStatus.ConnectFailure) {
       9:          //There is connectivity issue. 
      10:          //Hide the update control, instead of showing an error.
      11:              this.updateDisplay1.Visible = false;
      12:          }
      13:      }
      14:  }

    Another Alternative

    It might be more preferable to display the control but show that no updates are available. We can accomplish this as well by including with the application a Director.Xml file that contains no updates.  Just copy the Director.Xml file from your publish location and remove all Version nodes. With this file present, instead of hiding the control, we can change the update location to the local application path and initiate another update check.  This time no updates will be found and the control will indicate this.

       1:  Kjs.AppLife.Update.Controller.CheckForUpdateCompletedEventArgs e) {
       2:  if(e.Error != null &&
       3:      e.Error.InnerException != null &&
       4:      e.Error.InnerException is WebException) {
       5:      WebException ex = e.Error.InnerException as WebException;
       6:      if(ex.Status == WebExceptionStatus.NameResolutionFailure ||
       7:          ex.Status == WebExceptionStatus.ConnectFailure) {
       8:          //There is connectivity issue. 
       9:          //Start an update check that will not find an update.
      10:          string appDir = Path.GetDirectoryName(Application.ExecutablePath);
      11:          this.updateController1.UpdateLocation = appDir;
      12:          this.updateController1.CheckForUpdateAsync();
      13:      }
      14:  }

    With no network connectivity, this is what is displayed to the user.

    image 

    These techniques can be used with any of the visual updating controls and provides a method to customize the user experience when network connectivity is expectedly unreliable.

    Posted at 13 January, 2011 | By :Brian Haas | Categories : AppLife Update | Software Updating |
  • Customizing the Application Updating User Interface

    For many software teams who integrate a commercial application updating solution, the user experience that comes out of the box is perfectly acceptable. But for others, it’s one of the major barriers preventing solution adoption. The ability to customize the user experience is a differentiator for AppLife Update over competing options. We provide turn-key visual controls and user interfaces for an application updating process right out of the box, just like the others. Where we are different, is that we also provide the ability for you, the integrator, to completely customize the end-user updating experience. We’re not talking about changing the background color, or adding an image. We’re talking complete customization. In this post, I’ll walk through implementing a facelift customization of the AppLife update engine user interface.

    The Built-In User Interface

    image

    As an update is executing on a deployed client, the image above is what the end-user sees. The window title and the image displayed are easily customizable through simple project property settings. It’s also just as trivial to silently update and not show any interface at all through update implementation code:

    this.mUpdateController.ApplyUpdate(ApplyUpdateOptions.NoUpdateWindow);

    image

    Replacing the Built-In User Experience

    Notice on the project settings tab above, the option to use a Customized Replacement Window. This is what lets us give this user experience a real face lift. As an update is being executed and the AppLife Update engine is executing, there is a defined contract, or interface, that the visual window adheres to. Let’s introduce this interface.

    Meet the IUpdateUI interface.

    Any class that implements the IUpdateUI interface located in the Kjs.AppLife.Update.Engine.Core.dll assembly can replace the built-in window. This interface is quite simple. It has five methods and four events.

    Methods – These methods are called by the update engine as the update is executed.

    • Open
      Displays, or initializes, the user interface.
    • Close
      Closes the user interface. This method will not always be called by the update engine. The update engine will call this method after the Finish method, only if the host application code initiated the update with the AutoClose option. Close is also called immediately after the Finish method if an error occurs during the update. Otherwise it is expected that the user interface remain open until the user closes it.
    • Finish
      Called by the update engine to notify the update user interface that the update has finished and is allowed to be closed. The user interface should not be allowed to be closed before this method is called.
    • Update
      This method is called repeatedly as progress is made during the update process. The method is called in order to refresh the user interface. Method parameters provide information about the current state of the update process.
    • ShowYesNoPrompt
      Display the designated message and prompt the user for a yes or no answer. This method is used by built-in action, such as the Restart Operating System action.

    Events – These events are raised by the customized update interface to communicate with the update engine.

    • Closed
      Raise this event when the UI has been closed. This event must be raised for the Update Engine to complete the update and shutdown.
    • RequestCancel
      Raise this event when the user desires to cancel an executing update. The cancel request is confirmed by the update engine through a Finish method call. The result parameter will be set to Cancelled.
    • RequestPause
      Raise this event when the user desires to pause the executing update. The pause request is confirmed by the update engine through an update method call. The uiState parameter will be set to Paused.
    • RequestResume
      Raise this event when a paused update should be resumed. The resume request is confirmed by the update engine through an update method call. The uiState parameter will be set to Updating.

    That’s the interface that we must implement in order to replace the built-in updating window. You can use Windows Form, a WPF Window, or you can even use a communications proxy class that knows how to marshal the updating process information to a supervisory application, such as an update manager. For this walk through we’ll create a Windows Form replacement.

    1. Create a new Windows Forms project. Make sure to target the same .Net Framework version as your host application. Name the project MyCustomUpdatingForm.
    2. Add a reference to the assembly Kjs.AppLife.Update.Engine.Core.dll. If AppLife Update is installed on your development computer, this assembly will be in the .NET list.

      image
    3. View the code on Form1 and extend this form to implement the Kjs.AppLife.Update.Engine.Core.IUpdateUI interface.

    4.    1:  public partial class Form1 : Form, IUpdateUI {
         2:  ...
         3:  }

    5. Design and layout your update user experience. As the update progresses, there are text messages and percent completion updates that you can use in the design. You can design anything you like. This is your form. For simplicity, this walkthrough will use a label and a progress bar in a much smaller form factor than the built-in updating window.

      Add a label near the top of the form and name it lblMessage. Then set AutoSize to false, AutoEllipse to true, and anchor to Top, Left, Right.

      Next add a progress bar below the label. Size it to fill the width of the window and set its Anchor property to Top, Left, Right.

      Finally, add a cancel button below the progress bar and name it btnCancel.

      image
    6. Implement Interface Methods

    Open. In this method, we’ll simply show the form.

       1:  public void Open(Kjs.AppLife.Update.Engine.Core.UpdateUIContext context) {
       2:      this.Show();
       3:  }

    Close. The Form base class already implements a Close method that will close the form. We do want to interact with the form close logic to prevent the form from closing before the update engine calls the Finish method. To accomplish this, we’ll override the OnClosing method and check a member variable that we’ll add. This member variable will be used to signal that the Finished method has been called. We’ll also keep the update interface open in the event of an error to show the user information about the error.

       1:  private bool mCanClose;
       2:  private bool mError;
       3:   
       4:  protected override void OnClosing(CancelEventArgs e) {
       5:      base.OnClosing(e);
       6:   
       7:      if(!mCanClose) {
       8:          e.Cancel = true;
       9:          if(mError == true) {
      10:              mCanClose = true;
      11:          }
      12:      }
      13:  }

    Finish. After the Finish method is called, the user interface can be closed. This is signaled by setting the mCanClose member variable to true. Then, if the update did not fail, the form is closed. If the update did fail, the exception message is shown on the form.

       1:  public void Finish(Kjs.AppLife.Update.Engine.Core.UpdateResult result, 
       2:     string description, Exception updateError) {
       3:   
       4:      if(updateError == null) {
       5:          mCanClose = true;
       6:          Close();
       7:      } else {
       8:          lblMessage.Text = result.ToString();
       9:          progressBar1.Visible = false;
      10:          btnCancel.Enabled = false;
      11:          lblMessage.AutoSize = true;
      12:          lblMessage.Text = "Error: " + updateError.Message;
      13:          mError = true;
      14:      }
      15:  }

    Update. Update the progress bar and message label.

       1:  public void Update(Kjs.AppLife.Update.Engine.Core.UpdateUIState uiState,
       2:   Kjs.AppLife.Update.Engine.Core.UpdateState updateState, 
       3:   string description, int progressValue, int progressMaximum) {
       4:   
       5:      progressBar1.Maximum = progressMaximum;
       6:      progressBar1.Value = progressValue;
       7:   
       8:      lblMessage.Text = description;
       9:  }

    ShowYesNoPrompt. The simplest method is to show a message box.

       1:  public YesNoResponse ShowYesNoPrompt(string message) {
       2:      YesNoResponse result = YesNoResponse.No;
       3:      if(DialogResult.Yes == MessageBox.Show(this,
       4:                                message, "Update", 
       5:                                MessageBoxButtons.YesNo,
       6:                                MessageBoxIcon.Question)) {
       7:          result = YesNoResponse.Yes;
       8:      }
       9:   
      10:      return result;
      11:  }
     

    6.  Implement Cancel by raising the RequestCancel event when the Cancel button is clicked.

    private void btnCancel_Click(object sender, EventArgs e) {
        if(RequestCancel != null) {
            RequestCancel(this, EventArgs.Empty);
        }
    }

    7. Implement the Closed event. This event informs the update engine that the user interface has closed. A Windows Form class raises a Closed event when the form is closed, so we don’t need to implement the event in this example.

    Testing the New User Interface

    With the basics of the interface implemented, we can build the project and then test our form using Make Update. Open your AppLife Update project file and then navigate to the project settings dialog.

    image

    On the Update Window tab, we can import the assembly that includes our new replacement window. The imported assembly must have only one class that implements the IUpdateUI interface. The assembly is imported into the update project and will be included in any new update packages built by this update project. This dialog also provides a tester for replacement windows. Once imported, clicking the Test button will launch a test process.

    image

    In conclusion, by using the IUpdateUI interface you have complete control over the look and feel of your updating user experience. If your application demands strong product branding or a specific look and feel, you can easily fulfill your requirements with AppLife Update.

    Posted at 8 December, 2010 | By :Brian Haas | Categories : AppLife Update | Software Updating |
  • Application Updating by File Patching or Replacement

    File Update ActionsThere are many update actions available in AppLife Update to manipulate files on deployed systems during a software update. You’ll see in the list of update actions, that there are actions to replace files, and also actions that patch files and folders. When would you choose a patching action over a replacement action? What’s the difference anyways?

    Replacing Files

    Update actions that add & replace files will place the complete and intact file into the update package during the update build process, and then as the update package is executed on a deployed client, the intact file is extracted from the update package and replaces the existing previous version.

    Patching Files

    Actions that patch a file or folder do not place the entire file in an update. Instead, during the update build process a difference file is generated by comparing an earlier revision of a file with the current revision and this difference file is added to the update package. Difference files are often much smaller than a complete file, which results in a significantly smaller update package. As the update is executed on the deployed system, the difference file is combined with the earlier version to reproduce the current version file.

    Advantages & Disadvantages

    Replacing files makes an update far less dependent on the specific version of the application being updated on the deployed client. For many applications, using replacement file actions allows their update to successfully update any previous version. In this scenario, once a new version update is published, previous updates are no longer necessary and can be removed from the update server.

    The advantage of patching files is that update packages can be significantly smaller in physical size.

    The disadvantages of both types are converse to their advantages. Replacing files results in much larger update packages. The disadvantage of patching actions is very stringent versioning requirements.

    So when would you choose one over the other? Here are a few factors that can contribute to this decision.

    1. Are specific file versions reliably present?
    If the specific version of a target file cannot be guaranteed based on the installed version number of the application, patching cannot be used. The difference file must be combined with the exact base file used to create it. If that exact file is not present on the deployed system, the new file cannot be created during the update process and the action will fail.  This situation can occur when end users might manipulate the files and assemblies in the application installation directory.

    2. If the files to update are physically small, the number of clients to update is small, or network bandwidth is not a concern, consider using file replacement actions.
    In general, file replacement actions are more robust due to the lack of specific file versioning requirements. In addition, because updates can target many previous versions, clients that do not regularly update their software as updates are published will apply fewer updates. Update File Patching vs Replacing

    3. To minimize update package size, use patching actions
    Applications with many deployed clients, or physically large files should consider using patching actions. A Patch Folder action can operate recursively on an entire folder structure, making it easy to patch the entire application with a single update action. When using patching actions, it is necessary to build your updates to target specific previous versions.

    4. Consider combining both patching and replacing
    For some applications, certain files can be safely patched while others cannot. Both file action types can be used in a single update.

    Wrapping it up, with AppLife Update you have a choice to patch files or replace files during an update. Patching creates much smaller update packages, but requires strict adherence to versioning. Replacing files creates larger update packages but is far more forgiving and allows a single update to target multiple previous versions. So choose the right strategy or your application and start updating!

    Posted at 22 November, 2010 | By :Brian Haas | Categories : AppLife Update | Software Updating |
  • Build and Publish Software Updates from Visual Studio

    So you’ve got AppLife Update integrated into your application. That was easy enough. You’ve got your AppLife Update project set up to build and publish updates from Make Update as you release software versions. To make the process of building your updates even easier, I’ll show you how to integrate update building and publishing directly into your Visual Studio project build process.

    AppLife Update ships with an MSBuild task that we can use within a Visual Studio project file to build and publish updates as part of the Visual Studio build process. Using this, we’ll add a new Release with Update build configuration to a Visual Studio project. When this build configuration is chosen, an application update will be built and published as the Visual Studio project builds.

    Start by extracting the Simple C# Quick Start project. This will give us a common project to work from.

    Step 1 – Create a new build configuration.clip_image002

    From the Visual Studio build menu, select the Configuration Manager.

    Create a new build configuration and call it Release with Update. Select to copy settings from the existing Release configuration. We’ll modify the project to build and publish an update when this configuration is built.

    Step 2 – Modify the Visual Studio Project File

    From the Visual Studio project menu, select to Unload Project. With the project unloaded, you can edit it within Visual Studio by selecting the Simple project node from the Solution Explorer and from the context menu, select to Edit Simple.csproj. With the Visual Studio project file open in the editor, scroll to the bottom and you will see two commented out Target elements. Uncomment the AfterBuild target and add a UsingTask element that references the assembly that houses the BuildUpdate MSBuild task. This assembly is located in the AppLife Update install directory.

    Inside the AfterBuild target, add a BuildUpdate task. Set the Condition attribute to execute only when the newly created build configuration is used. Details on the attributes of this task are available in the MSBuildTask ReadMe.rtf file located in the same folder.

     <UsingTask AssemblyFile= "C:\Program Files\AppLife Update\Build Automation Utilities\MSBuild\Kjs.AppLife.Update.BuildUpdateTask.dll"
     	   TaskName= "Kjs.AppLife.Update.MSBuild.BuildUpdate" /> 
      
    <Target Name= "AfterBuild"> 
     	<BuildUpdate 
     		Condition= " '$(Configuration)|$(Platform)’ == 'Release with Update|AnyCPU' "
     		ProjectFile= "..\Simple.aup "
     		UpdateVersionSource= "$(OutputPath)\$(AssemblyName).exe"
     		TestOnly= "false"
     		PublishLocations= "Update Location" /> 
     </Target>
     

    Step 3 – Modify the aup project file to use the Release with Update output folder

    The Add & Replace files action should look at the Release folder for its files. Add a path relative to the aup project file.

    Simple\bin\Release\Simple.exe

    image

    That’s it!

    Now, whenever you want to publish an update, you can select the Release with Update build configuration and build the project.

    clip_image002[10]

    Visual Studio Build Output

    Parting Thoughts

    Build a test update out of Visual Studio, or build to a test update location. Both options are just as easy. This prevents an inadvertent build from being available to end users, and provides a built in updating testing mechanism.

    To build a test update, set the TestOnly attribute to true. For clients to see test updates, they must have a specific application setting in their app.config file.

    To publish to a specific test update location, you can name the publish location in Make Update project settings, then change the PublishLocations attribute value to match this update location.

    Posted at 12 November, 2010 | By :Brian Haas | Categories : AppLife Update | Software Updating |
  • To be Automatic, or be Automated… There is a Difference

    A developer doesn't have to look very hard to find an application that employs automatic updating.  In fact, there’s a good chance that an icon down in the system tray right now is informing you of an update’s availability. Some applications tell you ahead of time that updates are available, and some tell you after the fact that an update has been applied. Some are painstakingly obnoxious to the user, and some completely transparent. For most desktop applications, employing a system of automatic updating makes perfect sense.  But for many applications, especially applications consisting of services, server components and databases, automatic updating isn't very desirable.  But almost always, an automated update process does make sense, and should be employed.Automate Software Updating

    If your application is deployed to more than one location and development is ongoing, then the application should include an automated means to find updates and apply them.  Not always automatic, but always automated. There is a difference. An automated update process won’t just happen on its own, and it often doesn't even inform the user when an update is available.  It’s there to provide a simple, consistent, single step process to update the installed software. Customers will thank you, and it cuts your support costs.  

    If your responsible for back office software, you’ve no doubt had the unpleasant experienced of reviewing a software update procedure.  Software you installed a year ago, and haven't thought of since.  You first have to re-familiarize yourself with software terminology and configuration before you can even make sense of the upgrade procedure. Time consuming.

    And if your a developer, you’ve no doubt written an upgrade procedure, supported customers as they perform the upgrade, then tweaked the procedure for better understanding.  Time consuming.

    AppLife Update provides the means to automate your application maintenance plan, and could make a significant impact on support costs, especially if your application upgrades involve a multi-step manual upgrade process. Even if your application is complicated, don’t assume that implementing an automated update process would be cost prohibitive.  If you were to start from scratch, it probably would be, but with the built-in actions in AppLife Update, along with the Dynamic Code Action providing the means to write and package up application-specific upgrading functionality, you’ll be automated in no time.

    Posted at 22 June, 2010 | By :Brian Haas | Categories : AppLife Update | Software Updating |
  • Pros and Cons of File Patching, Update Chaining, vs. Broader Multi-Version Application Updates

    Say you have a .Net application.  From a deployment perspective, your application is a relatively normal application.  A primary executable, probably Windows Forms or WPF based, a class library or two, and a few third party controls.  The application has reached a shipping point and now it's time to distribute it to more than a few workstations.  You've chosen to distribute your application using the Windows Installer.  You're now faced with determining the strategy for maintaining the workstations that have installed your application.  Whatever strategy you choose to pursue, you will be confronted with this question:

    When I update my application, do I replace all of my assemblies, making updating simple, or do I replace only what I just changed, making updates smaller, but more complicated?

    This question is going to arise whether you create Windows Installer upgrades and patches, use a third party updating solution, or even consider rolling your own updater.  Regardless of the tool you use, at some point you will find yourself pondering the topic.  The physically small update is the apparent no-brainer.  The uninitiated may say, "of course we want our updates small.  Nobody wants to wait on updates, and we don't want to waste bandwidth.  Net neutrality isn't here yet!"   This is all true, and can be a compelling argument. So you march forward on the task... until the details emerge.  To keep updates small, versioning rears its ugly head.  An incremental update can only target specific previous versions.  For manually distributed software updates, as is often the case with Windows Installer deployments, knowing what version you have, and which patch, or patches, you need to apply becomes as big a deterrent to end-user updating as a larger update.

    After considering the challenges of implementation, the simplicity of larger, but version agnostic updates will cause you to reconsider your seemingly obvious initial plan. This is a big reason why so many organizations start out attempting to distribute patches and incremental upgrades, but then revert to the far more common version agnostic approach of uninstall/re-install. (There are plenty of technical challenges involved in actually producing working Windows Installer upgrades and patches, which also plays a role here as well).

    So which path do you choose?  Consider the following.

    • Frequency of updates
      If you are creating updates frequently, you want the update process creation to be as automated as possible. Decreasing the manual involvement increases efficiency as well as lowers the opportunity for mistakes. If you have the infrastructure to automate the creation of small, incremental updates then you should do so. If not, your update process will be simpler and less prone to error if you build larger, version agnostic updates. Even if you are doing this frequently.
    • Frequency of application use
      For applications that are launched and updated infrequently, accumulating incremental updates can create an undesirable user experience. Try to avoid forcing your users to regularly discover and apply multiple updates, one right after another. You should build larger updates that apply to more versions, or ensure your update process can apply multiple individual updates in a single update session.
    • Physical size of the application files
      Physically large application assemblies make for large updates. File patching can significantly reduce this size of an update, but requires strict control of which previous versions can apply the update.
    • Number of deployed clients
      For applications with many thousands of deployed clients, the network burden of larger updates is much more significant than applications with tens or hundreds of deployed clients. As your installed user base grows, minimizing the physical size of each update becomes far more important in order to manage your server bandwidth utilization without resorting to throttled update deployment.
    • Network Environment
      The network speed between the update server and deployed clients can dictate your decisions, especially when slow links are known to exist. When your application lives within slow networks, smaller updates are more desirable.
    • Background Download to Reduce the Burden
      Downloading updates in the background and informing the user when an update is ready to apply removes much of the burden the user experiences with larger updates.  It doesn't remove the burden from the network though.
    • Infrequent Exceptions to the Norm
      Targeting multiple versions, and making exceptions when you need to update infrequently modified files, such as third-party tools and help documentation keeps the initial update implementation effort low, ongoing update creation simple, and minimizes the burden that updating places on the end-user.

    A commonly pursued solution to this updating dilemma is not to consider application updating as an in incremental progression, but rather a "synchronization" process.  A process where deployed workstation application files are kept in-sync with a master version located on a server.  This approach works well if the updating process only updates files. It doesn't work so well when application maintenance also requires performing other updating activities, such as registry and data store maintenance.  Security and licensing concerns also make the "sync" approach more challenging and less desirable than version migration approaches.

    Our updating solution, AppLife Update, is an incremental updating solution.  Each update is self-contained, and includes all of the updating logic and new files/assemblies needed to migrate a deployed application from a previous version to a new version.  When an update is created, you get to choose which previous versions can successfully apply the new update.  You can target all previous versions, a list of discrete versions, or all greater than a previous version.  How you've defined the update obviously determines which previous versions you can target.  When defining an update, you have a lot of latitude in your decisions.  You can package and deploy Windows Installer databases, you can replace whole files, you can individually patch existing files, you can use update actions that automate the determination of which files need to be updated.  With an update system like AppLife Update, there is little difference in the effort needed to create updates that target all previous versions, or just the most recent version, however the bandwidth and user experience factors still need to be considered.

    The flexibility is there to create the application updating strategy that best fits your application and your organization.  If the size of the update package necessary to replace all of the assemblies built in a standard upgrade of your application is acceptable, your update process will be far simpler to create and maintain if you target all previous versions with each update.  If the factors involved with your application dictate smaller updates, you can easily extend your updating process to seamlessly discover and download multiple updates, as well as display to the user a unified updating experience.

    Posted at 16 March, 2010 | By :Brian Haas | Categories : AppLife Update | Software Updating |
  • .Net Application Updating in 60 Seconds

    The video below demonstrates how to update enable a .Net application in 60 seconds using AppLife Update.  And once enabled, maintaining deployed .Net applications is very easy.  In the video, you see an update created that replaces files and reads a registry key. The update then places the value from that registry key into the app.config file (an appSettings value). And for versatility, an MSI is installed and the registry key previously read in an earlier action is shown to the update user through a progress notification event initiated from C# code!

    This update video demonstrates a few of the common activities that are needed to update and maintain deployed .Net software. It only scratches the surface of what can be done with AppLife Update.

    If you are responsible for developing and maintaining a .Net application, you need to check out AppLife Update. Maintaining deployed release applications, as well as beta and QA installations have never been this easy.

    http://www.kineticjump.com/update/

    Posted at 3 March, 2010 | By :Brian Haas | Categories : Application Deployment | AppLife Update | Software Updating |
  • I Think I'll Roll My Own Application Updater

    Auto-updating deployed software is easy right?  I mean come on, how hard can it be to download a file from the internet and replace the old with the new. Why wouldn't I roll my own? I'd knock this out in a day or two.  All I'd need to do is...

    Replace some files

    I'll need to download the new files and replace the old ones.  Well... since my application is running and the files I need to replace are locked I'll need to do something with that.  Let's see, I'll just shadow load the exe.  When the application starts, I'll just copy it to another location and run it from there.  That way when my updater wants to replace it with the new one, it'll work.  I might have problems when I want to add another assembly to my application. rollyourown I guess I'll have to copy all the assemblies when my app starts.  That could get messy, but it's quick and easy.  Moving on...

    I'll need to know when an update is available.  OK, I can just retrieve a little file that will tell me what the current update is.  If the current update is newer than what is on the client, I'll download it and replace the client file with the updated file.  What?  Hmmm.... your right.  This will have to be changed if I ever want to update just part of the install, but I'll sort that out later when I have more time and I actually need to do it.  On to downloading...

    Downloading an update

    Downloading should be easy. The .Net framework gives me the WebClient class, which will make it as easy as pie.  I'll probably want to give my users some feedback and let them cancel.  My updates won't be very big so I don't think I'll need to worry about resuming from a previously failed update.  Everyone has fast internet connections now anyways. What's that?  Proxy servers could be a problem?  Well that'll take some time to sort out, so I'll just auto-detect, and if that fails then those users will just have to download the installer again and update the old fashioned way.  You think I should worry about getting hacked?  Not likely.  After all, we're pretty small and don't have that many users.  If they did though, I better do something to prevent that. That'll take some time to sort out, so I'll worry about it when we get big. Maybe crypto-signing or something... later.  Let's move on to actually updating the client...

    Updating the client system

    This will be super easy.  I'll just launch a little exe that will download the new files and replace the old ones.  What? Permissions might be a problem?  Never mind all that.  My users are all administrators on their machines anyway. What? Vista and Windows 7 doesn't even let administrators replace files everywhere?  Well then my users will just have to install the application somewhere where they do have permissions to replace files, or get someone who does have permissions to update their software.  We'll make a better solution later when we have more time to sort it out...  We can always update the updater later.  What?  I know the updater is running!  I'll just have to shadow launch the updater too so that I can replace it during an update.

    And when the updater fails

    All I am doing is replacing a file or two.  Why would the updater fail?  The user can just tell me which files are replaced and which ones aren't.  Later... when we have more time we can back up the files before we try to replace them or maybe even totally change the way we update the files.  Someday maybe we'll even add some logging so that we can figure out what happened when things go wrong.

    Publishing updates

    We'll just copy the new files to our web server whenever we build a new version so that the updater can download them. That's easy enough.  Yeah your right. Maybe we should compress them or something.

    You know... this sounds like a lot more work than I thought.  It might take me weeks, not days to get this done.  I wonder if there is something I can buy that will do all this?  That would save me a lot of time.

    Posted at 25 February, 2010 | By :Brian Haas | Categories : Application Deployment | Software Updating |