<?xml version="1.0" encoding="utf-8"?>
<feed xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom">
  <title>The AppLife Blog</title>
  <link rel="alternate" type="text/html" href="http://blog.kineticjump.com/" />
  <link rel="self" href="http://blog.kineticjump.com/SyndicationService.asmx/GetAtom" />
  <icon>favicon.ico</icon>
  <updated>2012-05-09T10:54:36.9775-05:00</updated>
  <author>
    <name>Kinetic Jump Software, LLC</name>
  </author>
  <subtitle>Kinetic Jump Software, LLC</subtitle>
  <id>http://blog.kineticjump.com/</id>
  <generator uri="http://dasblog.info/" version="2.3.9074.18820">DasBlog</generator>
  <entry>
    <title>Updating a Windows Service</title>
    <link rel="alternate" type="text/html" href="http://blog.kineticjump.com/2012/05/09/UpdatingAWindowsService.aspx" />
    <id>http://blog.kineticjump.com/PermaLink,guid,6336ccef-8926-45c9-a2da-3fb52099ac95.aspx</id>
    <published>2012-05-09T15:41:00-05:00</published>
    <updated>2012-05-09T10:54:36.9775-05:00</updated>
    <category term="Application Deployment" label="Application Deployment" scheme="http://blog.kineticjump.com/CategoryView,category,ApplicationDeployment.aspx" />
    <category term="AppLife Update" label="AppLife Update" scheme="http://blog.kineticjump.com/CategoryView,category,AppLifeUpdate.aspx" />
    <category term="Software Updating" label="Software Updating" scheme="http://blog.kineticjump.com/CategoryView,category,SoftwareUpdating.aspx" />
    <author>
      <name>Brian Haas</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <ol>
          <li>
Stop the Service using a <strong>Stop Service</strong> update action.</li>
          <li>
Replace the Service assemblies using one of the available file replacement actions.</li>
          <li>
Restart the Service using a <strong>Start Service </strong>update action.</li>
        </ol>
        <p>
Tada! Big maintenance challenge accomplished.
</p>
        <h3>An Example
</h3>
        <p>
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, <i>and</i> 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).
</p>
        <p>
          <b>Stop the Service</b>
        </p>
        <p>
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.
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/Updating-a-Windows-Service_9143/image.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.kineticjump.com/images/blog/Updating-a-Windows-Service_9143/image_thumb.png" width="564" height="332" />
          </a>
        </p>
        <p>
Open your application update project file (.aup). Add a <b>Stop Service</b> action
to your update. Set the <i>Service to Stop</i> property to the name of your service.
In this case, the service name is KjsUpdateService2.
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/Updating-a-Windows-Service_9143/image_3.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.kineticjump.com/images/blog/Updating-a-Windows-Service_9143/image_thumb_3.png" width="564" height="547" />
          </a>
        </p>
        <p>
          <b>
          </b>
        </p>
        <p>
          <b>Replace the Service Assemblies</b>
        </p>
        <p>
We use an <i>Add &amp; Replace files on restart</i> action to update the assemblies.
The AppLife Update Windows service is initially deployed using an MSI merge module,
and is always installed to the <i>Common Files Folder\</i>AppLifeUpdateService2 folder.
To update the service, we’ll select the <i>Common Program Files (x86)</i> 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 <i>Common
Program Files</i> 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.
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/Updating-a-Windows-Service_9143/image_4.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.kineticjump.com/images/blog/Updating-a-Windows-Service_9143/image_thumb_4.png" width="564" height="517" />
          </a> 
</p>
        <p>
          <em>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</em> Restart Operating System <em>action to accomplish
this.</em></p>
        <p>
The service assemblies ship with AppLife Update already embedded into the <i>AppLifeUpdateService.msm</i> 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.
</p>
        <p>
          <b>Restarting the Service</b>
        </p>
        <p>
The service is restarted by adding a <b>Start Service</b> update action. The action
is configured by defining the name of the service to restart. In this case it is again,
KjsUpdatService2.
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/Updating-a-Windows-Service_9143/image_5.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.kineticjump.com/images/blog/Updating-a-Windows-Service_9143/image_thumb_5.png" width="564" height="517" />
          </a>
        </p>
        <p>
That’s it! Windows Service update completed.
</p>
        <p>
          <b>But My Service <i>is</i> My Application?</b>
        </p>
        <p>
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 <strong>Stop Service</strong> 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.
</p>
        <img width="0" height="0" src="http://blog.kineticjump.com/aggbug.ashx?id=6336ccef-8926-45c9-a2da-3fb52099ac95" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Using Callable Action Lists Part II</title>
    <link rel="alternate" type="text/html" href="http://blog.kineticjump.com/2012/05/01/UsingCallableActionListsPartII.aspx" />
    <id>http://blog.kineticjump.com/PermaLink,guid,ed1367ed-9e8b-4dcc-8400-3bf2ce9676e7.aspx</id>
    <published>2012-04-30T20:57:00-05:00</published>
    <updated>2012-04-30T17:05:30.747625-05:00</updated>
    <category term="AppLife Update" label="AppLife Update" scheme="http://blog.kineticjump.com/CategoryView,category,AppLifeUpdate.aspx" />
    <category term="Software Updating" label="Software Updating" scheme="http://blog.kineticjump.com/CategoryView,category,SoftwareUpdating.aspx" />
    <author>
      <name>Brian Haas</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
In my <a href="http://blog.kineticjump.com/2012/04/20/UsingCallableActionListsToUpdateMultipleDatabasesDuringAClientUpdate.aspx">previous
post</a> 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.
</p>
        <p>
          <b>Identifying the Databases to Update </b>
        </p>
        <p>
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.
</p>
        <p>
          <b>Custom Update Actions and Shared Properties</b>
        </p>
        <p>
The feature duo that makes what might initially sound difficult to accomplish during
an application update magically easy using AppLife Update are <b>Custom Actions</b> and <b>Shared
Properties</b>. Custom Actions are simply classes that inherit from an <i>UpdateAction</i> base
class and implements at a minimum, an <i>Execute</i> method and a <i>Rollback</i> method.
Shared Properties are a collection of <b>objects</b> that are scoped to the context
of the update and can be accessed from any update action.
</p>
        <p>
For our purposes, we want a custom update action that will read the list of databases
from an application configuration file. The <b>C#/VB.NET Code</b> action lets me write
this custom action directly within the update creation software.
</p>
        <p>
          <em>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.</em>
        </p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-Part-II_E9A1/clip_image001.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image001" border="0" alt="clip_image001" src="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-Part-II_E9A1/clip_image001_thumb.png" width="558" height="395" />
          </a>
        </p>
        <p>
Here is the code:
</p>
        <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: ; color: ; border-top: #000080 1px solid; border-right: #000080 1px solid">
          <div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: ; background: #000080; color: ; padding-top: 2px">
            <font face="Verdana">
              <font style="font-size: 10pt" color="#ffffff">
                <strong>Code
Snippet</strong>
              </font>
            </font>
          </div>
          <div style="background: #ddd; max-height: 300px; overflow: auto">
            <ol style="padding-bottom: 0px; margin: 0px 0px 0px 33px; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px">
              <li>
                <font face="Courier New">
                  <span style="color: ">
                    <font color="#0000ff">
                      <font style="font-size: 10pt">using</font>
                    </font>
                  </span>
                  <font style="font-size: 10pt" color="#000000"> System;</font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <span style="color: ">
                    <font color="#0000ff">
                      <font style="font-size: 10pt">using</font>
                    </font>
                  </span>
                  <font style="font-size: 10pt">
                    <font color="#000000"> System</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Collections</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Generic;</font>
                  </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <span style="color: ">
                    <font color="#0000ff">
                      <font style="font-size: 10pt">using</font>
                    </font>
                  </span>
                  <font style="font-size: 10pt">
                    <font color="#000000"> System</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Text;</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <span style="color: ">
                    <font color="#0000ff">
                      <font style="font-size: 10pt">using</font>
                    </font>
                  </span>
                  <font style="font-size: 10pt">
                    <font color="#000000"> Kjs</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">AppLife</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Update</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Engine</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Core;</font>
                  </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <span style="color: ">
                    <font color="#0000ff">
                      <font style="font-size: 10pt">using</font>
                    </font>
                  </span>
                  <font style="font-size: 10pt">
                    <font color="#000000"> System</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Xml;</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <span style="color: ">
                    <font color="#0000ff">
                      <font style="font-size: 10pt">using</font>
                    </font>
                  </span>
                  <font style="font-size: 10pt">
                    <font color="#000000"> System</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">IO;</font>
                  </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000"> </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <span style="color: ">
                    <font color="#0000ff">
                      <font style="font-size: 10pt">namespace</font>
                    </font>
                  </span>
                  <font style="font-size: 10pt" color="#000000"> DynamicCodeActions
{</font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">    </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#0000ff">public</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="color: ">
                      <font color="#0000ff">class</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="color: ">
                      <font color="#2b91af">DynamicAction1</font>
                    </span>
                    <font color="#000000"> : </font>
                    <span style="color: ">
                      <font color="#2b91af">UpdateAction</font>
                    </span>
                    <font color="#000000"> {</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000"> </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#0000ff">public</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="color: ">
                      <font color="#0000ff">override</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="color: ">
                      <font color="#0000ff">void</font>
                    </span>
                    <font color="#000000"> Execute(</font>
                    <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%; color: ">
                      <font style="background-color: #f2dfdf" color="#2b91af">UpdateContext</font>
                    </span>
                    <font color="#000000"> context)
{</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">            </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//Read
connection strings from app.config</font>
                  </span>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">            </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#2b91af">XmlDocument</font>
                    </span>
                    <font color="#000000"> configDoc </font>
                    <span style="color: ">
                      <font color="#cc0071">=</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="color: ">
                      <font color="#0000ff">new</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="color: ">
                      <font color="#2b91af">XmlDocument</font>
                    </span>
                    <font color="#000000">();</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">           
configDoc</font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Load(</font>
                    <span style="color: ">
                      <font color="#2b91af">Path</font>
                    </span>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Combine(context</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">ApplicationDirectory, </font>
                    <span style="color: ">
                      <font color="#a31515">"CallActionListExample.exe.config"</font>
                    </span>
                    <font color="#000000">));</font>
                  </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000"> </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">            </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#2b91af">XmlNodeList</font>
                    </span>
                    <font color="#000000"> connStrings </font>
                    <span style="color: ">
                      <font color="#cc0071">=</font>
                    </span>
                    <font color="#000000"> configDoc</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">SelectNodes(</font>
                    <span style="color: ">
                      <font color="#a31515">"/configuration/connectionStrings/*"</font>
                    </span>
                    <font color="#000000">);</font>
                  </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">            </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#2b91af">List</font>
                    </span>
                    <span style="color: ">
                      <font color="#cc0071">&lt;</font>
                    </span>
                    <span style="color: ">
                      <font color="#0000ff">string</font>
                    </span>
                    <span style="color: ">
                      <font color="#cc0071">&gt;</font>
                    </span>
                    <font color="#000000"> connectionStrings </font>
                    <span style="color: ">
                      <font color="#cc0071">=</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="color: ">
                      <font color="#0000ff">new</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="color: ">
                      <font color="#2b91af">List</font>
                    </span>
                    <span style="color: ">
                      <font color="#cc0071">&lt;</font>
                    </span>
                    <span style="color: ">
                      <font color="#0000ff">string</font>
                    </span>
                    <span style="color: ">
                      <font color="#cc0071">&gt;</font>
                    </span>
                    <font color="#000000">();</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">            </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#0000ff">foreach</font>
                    </span>
                    <font color="#000000">(</font>
                    <span style="color: ">
                      <font color="#2b91af">XmlNode</font>
                    </span>
                    <font color="#000000"> node </font>
                    <span style="color: ">
                      <font color="#0000ff">in</font>
                    </span>
                    <font color="#000000"> connStrings)
{</font>
                  </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">               
connectionStrings</font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Add(node</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Attributes[</font>
                    <span style="color: ">
                      <font color="#a31515">"connectionString"</font>
                    </span>
                    <font color="#000000">]</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Value);</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">               
context</font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Log</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">WriteLine(</font>
                    <span style="color: ">
                      <font color="#0000ff">string</font>
                    </span>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Format(</font>
                    <span style="color: ">
                      <font color="#a31515">"Added
connStr: {0}"</font>
                    </span>
                    <font color="#000000">, node</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Attributes[</font>
                    <span style="color: ">
                      <font color="#a31515">"connectionString"</font>
                    </span>
                    <font color="#000000">]</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Value));</font>
                  </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000">           
}</font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">            </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#0000ff">if</font>
                    </span>
                    <font color="#000000">(connectionStrings</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Count </font>
                    <span style="color: ">
                      <font color="#cc0071">&gt;</font>
                    </span>
                    <font color="#000000"> 0)
{</font>
                  </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">               
context</font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">SharedProperties</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Add(</font>
                    <span style="color: ">
                      <font color="#a31515">"ConnectionStrings"</font>
                    </span>
                    <font color="#000000">,
connectionStrings);</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">               
context</font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">SharedProperties</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Add(</font>
                    <span style="color: ">
                      <font color="#a31515">"ExecuteDBUpdate"</font>
                    </span>
                    <font color="#000000">, </font>
                    <span style="color: ">
                      <font color="#0000ff">true</font>
                    </span>
                    <font color="#000000">);</font>
                  </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">               
context</font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">SharedProperties</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Add(</font>
                    <span style="color: ">
                      <font color="#a31515">"CurrentConnectionString"</font>
                    </span>
                    <font color="#000000">, </font>
                    <span style="color: ">
                      <font color="#a31515">""</font>
                    </span>
                    <font color="#000000">);</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">           
} </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#0000ff">else</font>
                    </span>
                    <font color="#000000"> {</font>
                  </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">               
context</font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">SharedProperties</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Add(</font>
                    <span style="color: ">
                      <font color="#a31515">"ExecuteDBUpdate"</font>
                    </span>
                    <font color="#000000">, </font>
                    <span style="color: ">
                      <font color="#0000ff">false</font>
                    </span>
                    <font color="#000000">);</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000">           
}</font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000">       
}</font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000"> </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#0000ff">public</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="color: ">
                      <font color="#0000ff">override</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="color: ">
                      <font color="#0000ff">void</font>
                    </span>
                    <font color="#000000"> RollbackExecute(</font>
                    <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%; color: ">
                      <font style="background-color: #f2dfdf" color="#2b91af">UpdateContext</font>
                    </span>
                    <font color="#000000"> context)
{</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">            </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//Add
code here to undo work that was performed in the Execute</font>
                  </span>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">            </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//method. 
The method is not performed if the Execute method</font>
                  </span>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">            </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//is
not completed.</font>
                  </span>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000"> </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">           
context</font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">SharedProperties</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Remove(</font>
                    <span style="color: ">
                      <font color="#a31515">"ConnectionStrings"</font>
                    </span>
                    <font color="#000000">);</font>
                  </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">           
context</font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">SharedProperties</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Remove(</font>
                    <span style="color: ">
                      <font color="#a31515">"ExecuteDBUpdate"</font>
                    </span>
                    <font color="#000000">);</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000"> </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000"> </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000">       
}</font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000">   
}</font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000">}</font>
                </font>
              </li>
            </ol>
          </div>
        </div>
        <p>
Notice that through the <i>context</i> 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.
</p>
        <p>
          <b>Manipulating the List from other Actions</b>
        </p>
        <p>
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.
</p>
        <p>
Read the Next Connection String
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-Part-II_E9A1/clip_image002.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-Part-II_E9A1/clip_image002_thumb.png" width="559" height="482" />
          </a>
          <i>
          </i>
        </p>
        <p>
Remove the Item after the Database is Updated
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-Part-II_E9A1/clip_image003.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image003" border="0" alt="clip_image003" src="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-Part-II_E9A1/clip_image003_thumb.png" width="559" height="478" />
          </a>
        </p>
        <p>
          <b>Conclusion</b>
        </p>
        <p>
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.
</p>
        <p>
          <a href="http://www.kineticjump.com/files/callactionlistexample2.zip" target="_blank">Download
Example AppLife Update Project</a>
        </p>
        <img width="0" height="0" src="http://blog.kineticjump.com/aggbug.ashx?id=ed1367ed-9e8b-4dcc-8400-3bf2ce9676e7" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Using Callable Action Lists to Update Multiple Databases During a Client Update</title>
    <link rel="alternate" type="text/html" href="http://blog.kineticjump.com/2012/04/20/UsingCallableActionListsToUpdateMultipleDatabasesDuringAClientUpdate.aspx" />
    <id>http://blog.kineticjump.com/PermaLink,guid,00b2af17-d5c9-49ac-a8af-3e94c523b36e.aspx</id>
    <published>2012-04-20T05:05:00-05:00</published>
    <updated>2012-04-21T00:14:04.8778825-05:00</updated>
    <category term="AppLife Update" label="AppLife Update" scheme="http://blog.kineticjump.com/CategoryView,category,AppLifeUpdate.aspx" />
    <category term="Software Updating" label="Software Updating" scheme="http://blog.kineticjump.com/CategoryView,category,SoftwareUpdating.aspx" />
    <author>
      <name>Brian Haas</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
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 <b>Shared Properties</b> and applying <b>conditional statements</b> 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:
</p>
        <p>
1. Identify all of the databases that are present.
</p>
        <p>
2. Iterate each of the local databases, applying the necessary change script to each
one.
</p>
        <p>
3. Update the application assemblies.
</p>
        <p>
For this example, the list of databases will be discovered by inspecting the application
configuration file. Each database connection string is listed in the <b>connectionStrings</b> 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.
</p>
        <p>
          <i>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. </i>
        </p>
        <p>
          <b>Identify and Manage the Local Database List</b>
        </p>
        <p>
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 <b>connectionStrings</b> 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.
</p>
        <p>
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 <b>Run command line</b> update
action. This action includes a helper feature that allows us to use common directories
to define two path variables. The <i>Application Directory</i> is the physical path
of the application that launched the update. This is where the application configuration
file resides. The <i>Update Package Directory</i> is the physical path to the temporary
working directory that is created for this update by the update engine. I define &lt;path1&gt;
to be the path to the application configuration file, and I define &lt;path2&gt; to
be the path of my copy of the config file. I’ll call it <i>config.xml</i>. With the
two paths specified, I’ll use them in the actual command line that copies the config
file:
</p>
        <p>
copy “&lt;path1&gt;” “&lt;path2&gt;”
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image001.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image001" border="0" alt="clip_image001" src="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image001_thumb.png" width="413" height="505" />
          </a>
        </p>
        <p>
To read the entries in the config file, I’ll use a <b>Read Xml Node</b> action. To
use this action we specify an Xml file to read, define an <i>XPath</i> 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.
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image002.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image002_thumb.png" width="413" height="505" />
          </a>
        </p>
        <p>
Here is what the config file section looks like:
</p>
        <p>
&lt;configuration&gt; 
</p>
        <p>
&lt;connectionStrings&gt; 
</p>
        <p>
&lt;add name="Db1" connectionString="Data Source=.\SQLEXPRESS;Initial
Catalog=TestDb1;Integrated Security=True"/&gt; 
</p>
        <p>
&lt;add name="Db2" connectionString="Data Source=.\SQLEXPRESS;Initial
Catalog=TestDb2;Integrated Security=True"/&gt; 
</p>
        <p>
&lt;/connectionStrings&gt; 
</p>
        <p>
&lt;/configuration&gt;
</p>
        <p>
I am interested in the connectionString, so my XPath expression is <b>/configuration/connectionStrings/add/@connectionString</b></p>
        <p>
If multiple nodes are found, the action is configured to read the first node, and
if no node is present a default value of <b>None</b> is assigned. We’ll use this in
a conditional statement. If a node is present, a Shared Property with a key of <b>ConnStr </b>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 <b>ConnStr</b> Shared
Property does not equal the value “None”, we call the action list.
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image003.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image003" border="0" alt="clip_image003" src="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image003_thumb.png" width="413" height="245" />
          </a>
        </p>
        <p>
          <b>Update the Database</b>
        </p>
        <p>
The databases I am updating are SQL Server databases. Therefore I am using the <i>SQL
Server Update Actions</i> 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:
</p>
        <p>
1. Open a Database Connection. I’ll configure the action to place the database in
single-user mode.
</p>
        <p>
2. Begin a SQL Server Transaction.
</p>
        <p>
3. Execute a database query.
</p>
        <p>
4. Commit the SQL Server transaction
</p>
        <p>
5. Close the SQL Connection
</p>
        <p>
To open the connection, I set the connection string directly, and then use the <b>ConnStr</b> Shared
Property we already defined. For many built-in actions, you can use Shared Properties
that are strings by using a $<i>SharedPropertyKey</i>$ 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 <b>SqlConection</b>. We’ll use this Shared Property
in the other database actions.
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image004.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image004" border="0" alt="clip_image004" src="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image004_thumb.png" width="428" height="552" />
          </a>
        </p>
        <p>
With a SQL Connection open, I’ll start a transaction using the <i>Begin SQL Server
Transaction</i> 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 <b>Commit SQL Server transaction</b> action.
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image005.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image005" border="0" alt="clip_image005" src="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image005_thumb.png" width="413" height="532" />
          </a>
        </p>
        <p>
With the transaction started, it can be used by one or more <i>Run SQL Server query</i> actions.
In this example, I’ll just add a table.
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image006.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image006" border="0" alt="clip_image006" src="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image006_thumb.png" width="413" height="532" />
          </a>
        </p>
        <p>
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.
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image007.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image007" border="0" alt="clip_image007" src="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image007_thumb.png" width="413" height="332" />
          </a>
        </p>
        <p>
Closing the connection by specifying the Shared Property key…
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image008.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image008" border="0" alt="clip_image008" src="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image008_thumb.png" width="413" height="319" />
          </a>
        </p>
        <p>
          <b>Remove the Database from the Working Xml File</b>
        </p>
        <p>
With the designated database updated, I am going to remove the connection string from
the working Xml file using a <b>Delete Xml Node</b> 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.
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image009.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image009" border="0" alt="clip_image009" src="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image009_thumb.png" width="459" height="592" />
          </a>
        </p>
        <p>
With the node removed from the working file, we’ll again use a <i>Read Xml Node</i> action
to read the next connection string in the file. If there is another connection string
available, we’ll assign it to the <b>ConnStr</b> Shared Property. Otherwise, just
like before, if no connection strings are left the value of the Shared Property will
be set to “None”.
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image010.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image010" border="0" alt="clip_image010" src="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image010_thumb.png" width="413" height="532" />
          </a>
        </p>
        <p>
And now as long as the value of the <b>ConnStr</b> Shared property is not “None” we’ll
call this same action list again, updating the next database in the list.
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image011.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image011" border="0" alt="clip_image011" src="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image011_thumb.png" width="413" height="304" />
          </a>
        </p>
        <p>
This process is repeated for all of the databases identified in the <b>connectionStrings</b> configuration
element.
</p>
        <p>
          <b>Replace the Application Assemblies</b>
        </p>
        <p>
To complete this update, I’ll use an <i>Add &amp; Replace Files </i>action to replace
the main application executable.
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image012.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image012" border="0" alt="clip_image012" src="http://www.kineticjump.com/images/blog/Using-Callable-Action-Lists-to-Update-Mu_1513C/clip_image012_thumb.png" width="413" height="532" />
          </a>
        </p>
        <p>
          <b>Summary</b>
        </p>
        <p>
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.
</p>
        <p>
          <a href="http://www.kineticjump.com/files/CallActionListExample.zip" target="_blank">Download
Example Project</a>
        </p>
        <p>
          <a href="http://www.kineticjump.com/files/CallActionListExampleUpdateExecutionLog.txt" target="_blank">View
Execution Log</a>
        </p>
        <img width="0" height="0" src="http://blog.kineticjump.com/aggbug.ashx?id=00b2af17-d5c9-49ac-a8af-3e94c523b36e" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Terminal Services Application Updating</title>
    <link rel="alternate" type="text/html" href="http://blog.kineticjump.com/2012/03/21/TerminalServicesApplicationUpdating.aspx" />
    <id>http://blog.kineticjump.com/PermaLink,guid,82f95758-6f6c-4ea9-8845-a4028d063d0a.aspx</id>
    <published>2012-03-21T14:55:57.037625-05:00</published>
    <updated>2012-03-21T15:26:35.912625-05:00</updated>
    <category term="Application Deployment" label="Application Deployment" scheme="http://blog.kineticjump.com/CategoryView,category,ApplicationDeployment.aspx" />
    <category term="AppLife Update" label="AppLife Update" scheme="http://blog.kineticjump.com/CategoryView,category,AppLifeUpdate.aspx" />
    <category term="Software Updating" label="Software Updating" scheme="http://blog.kineticjump.com/CategoryView,category,SoftwareUpdating.aspx" />
    <author>
      <name>Brian Haas</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
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. 
<br /><br /></p>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:a3b5c180-54ef-41ad-8165-67ec859c6734" class="wlWriterEditableSmartContent">
          <div>
            <!-- copy and paste. Modify height and width if desired. -->
            <object id="scPlayer" width="550" height="430" type="application/x-shockwave-flash" data="http://content.screencast.com/users/KineticJump/folders/AppLife%20Update%204.0/media/edb73f7c-0baa-4a4f-8c32-1746ffdac9c2/terminal%20services%20example_controller.swf">
              <param name="movie" value="http://content.screencast.com/users/KineticJump/folders/AppLife%20Update%204.0/media/edb73f7c-0baa-4a4f-8c32-1746ffdac9c2/terminal%20services%20example_controller.swf" />
              <param name="quality" value="high" />
              <param name="bgcolor" value="#FFFFFF" />
              <param name="flashVars" value="containerwidth=550&amp;containerheight=430&amp;showstartscreen=true&amp;showendscreen=true&amp;loop=false&amp;autostart=false&amp;color=000000,000000&amp;thumbscale=45&amp;content=http://content.screencast.com/users/KineticJump/folders/AppLife%20Update%204.0/media/edb73f7c-0baa-4a4f-8c32-1746ffdac9c2/Terminal%20Services%20Example.mp4&amp;blurover=false" />
              <param name="allowFullScreen" value="true" />
              <param name="scale" value="showall" />
              <param name="allowScriptAccess" value="always" />
              <param name="base" value="http://content.screencast.com/users/KineticJump/folders/AppLife%20Update%204.0/media/edb73f7c-0baa-4a4f-8c32-1746ffdac9c2/" />
              <iframe type="text/html" frameborder="0" scrolling="no" style="overflow:hidden;" src="http://www.screencast.com/users/KineticJump/folders/AppLife%20Update%204.0/media/edb73f7c-0baa-4a4f-8c32-1746ffdac9c2/embed" height="430" width="550">
              </iframe>
            </object>
          </div>
          <div style="width:550px;clear:both;font-size:.8em">Terminal Services Application Updating
with AppLife Update
</div>
        </div>
        <p>
          <b>User Experience Customizations</b>
        </p>
        <p>
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.
</p>
        <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: ; color: ; border-top: #000080 1px solid; border-right: #000080 1px solid">
          <div style="padding-bottom: 2px; padding-left: 5px; padding-right: 5px; font-family: ; background: #000080; color: ; padding-top: 2px">
            <font face="Verdana">
              <font style="font-size: 10pt" color="#ffffff">
                <strong>Code
Snippet</strong>
              </font>
            </font>
          </div>
          <div style="background: #ddd; max-height: 500px; overflow: auto">
            <ol style="padding-bottom: 0px; margin: 0px 0px 0px 33px; padding-left: 5px; padding-right: 0px; background: #ffffff; padding-top: 0px" start="start">
              <li>
                <font face="Courier New">
                  <span style="color: ">
                    <font color="#0000ff">
                      <font style="font-size: 10pt">private</font>
                    </font>
                  </span>
                  <font style="font-size: 10pt">
                    <font color="#000000">
                    </font>
                    <span style="color: ">
                      <font color="#0000ff">void</font>
                    </span>
                    <font color="#000000"> checkForUpdatesToolStripMenuItem_Click_1(</font>
                    <span style="color: ">
                      <font color="#0000ff">object</font>
                    </span>
                    <font color="#000000"> sender,</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">            </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#2b91af">EventArgs</font>
                    </span>
                    <font color="#000000"> e)
{</font>
                  </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#0000ff">if</font>
                    </span>
                    <font color="#000000">(updateController1</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">ShowCheckForUpdateDialog(</font>
                    <span style="color: ">
                      <font color="#0000ff">this</font>
                    </span>
                    <font color="#000000">,</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">            </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%; color: ">
                      <font style="background-color: #f0f0f0" color="#732c24">ErrorDisplayLevel</font>
                    </span>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">ShowExceptionMessage) </font>
                    <span style="color: ">
                      <font color="#cc0071">==</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%; color: ">
                      <font style="background-color: #f0f0f0" color="#732c24">DialogResult</font>
                    </span>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">OK)
{</font>
                  </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">            </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#0000ff">if</font>
                    </span>
                    <font color="#000000">(updateController1</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">ShowDownloadUpdateDialog(</font>
                    <span style="color: ">
                      <font color="#0000ff">this</font>
                    </span>
                    <font color="#000000">,</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">                </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%; color: ">
                      <font style="background-color: #f0f0f0" color="#732c24">ErrorDisplayLevel</font>
                    </span>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">ShowExceptionMessage) </font>
                    <span style="color: ">
                      <font color="#cc0071">==</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%; color: ">
                      <font style="background-color: #f0f0f0" color="#732c24">DialogResult</font>
                    </span>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">OK)
{</font>
                  </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">                </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//Launch
the update from another thread</font>
                  </span>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">                </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//To
better accomodate terminal services </font>
                  </span>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">                </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//installations,
the UI will remain </font>
                  </span>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">                </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//responsive
as all of the other </font>
                  </span>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">                </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//instances
of the application are closed.</font>
                  </span>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000"> </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">                </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#2b91af">BackgroundWorker</font>
                    </span>
                    <font color="#000000"> worker </font>
                    <span style="color: ">
                      <font color="#cc0071">=</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="color: ">
                      <font color="#0000ff">new</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="color: ">
                      <font color="#2b91af">BackgroundWorker</font>
                    </span>
                    <font color="#000000">();</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">               
worker</font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">DoWork </font>
                    <span style="color: ">
                      <font color="#cc0071">+=</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="color: ">
                      <font color="#0000ff">new</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="color: ">
                      <font color="#0c0075">DoWorkEventHandler</font>
                    </span>
                    <font color="#000000">(worker_DoWork);</font>
                  </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">               
worker</font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">RunWorkerAsync(updateController1);</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">                </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#2b91af">ApplicationUpdateInitiatedDialog</font>
                    </span>
                    <font color="#000000"> dlg </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#cc0071">=</font>
                  </span>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">                </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#0000ff">new</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="color: ">
                      <font color="#2b91af">ApplicationUpdateInitiatedDialog</font>
                    </span>
                    <font color="#000000">(</font>
                    <span style="color: ">
                      <font color="#0000ff">true</font>
                    </span>
                    <font color="#000000">);</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">               
dlg</font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">ShowDialog(</font>
                    <span style="color: ">
                      <font color="#0000ff">this</font>
                    </span>
                    <font color="#000000">);</font>
                  </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000">           
}</font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000">       
}</font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000">   
}</font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000"> </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">    </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#0000ff">private</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="color: ">
                      <font color="#0000ff">void</font>
                    </span>
                    <font color="#000000"> worker_DoWork(</font>
                    <span style="color: ">
                      <font color="#0000ff">object</font>
                    </span>
                    <font color="#000000"> sender, </font>
                    <span style="color: ">
                      <font color="#2b91af">DoWorkEventArgs</font>
                    </span>
                    <font color="#000000"> e)
{</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//Since
the ApplyUpdate method call is a </font>
                  </span>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//blocking
call, and we want the UI to remain </font>
                  </span>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//response
as the user waits for all instances </font>
                  </span>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//to
close, we'll initiate the update on a </font>
                  </span>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//background
thread.</font>
                  </span>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000"> </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#2b91af">UpdateController</font>
                    </span>
                    <font color="#000000"> controller </font>
                    <span style="color: ">
                      <font color="#cc0071">=</font>
                    </span>
                    <font color="#000000"> e</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">Argument </font>
                    <span style="color: ">
                      <font color="#0000ff">as</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="color: ">
                      <font color="#2b91af">UpdateController</font>
                    </span>
                    <font color="#000000">;</font>
                  </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#0000ff">if</font>
                    </span>
                    <font color="#000000">(controller </font>
                    <span style="color: ">
                      <font color="#cc0071">!=</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="color: ">
                      <font color="#0000ff">null</font>
                    </span>
                    <font color="#000000">)
{</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">           
controller</font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">ApplyUpdate(</font>
                    <span style="background-image: none; background-attachment: scroll; background-repeat: repeat; background-position: 0% 0%; color: ">
                      <font style="background-color: #f0f0f0" color="#732c24">ApplyUpdateOptions</font>
                    </span>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">AutoClose);</font>
                  </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000">       
}</font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000">   
}</font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000"> </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">    </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#0000ff">private</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="color: ">
                      <font color="#0000ff">void</font>
                    </span>
                    <font color="#000000"> updateController1_UpdateStarting(</font>
                    <span style="color: ">
                      <font color="#0000ff">object</font>
                    </span>
                    <font color="#000000"> sender,</font>
                  </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">            </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#2b91af">UpdateStartingEventArgs</font>
                    </span>
                    <font color="#000000"> e)
{</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//An
update has been an initated and this </font>
                  </span>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//application
will shutdown. This dialog will</font>
                  </span>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//inform
any other users that the application </font>
                  </span>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//is
about to shutdown on them. Showing this </font>
                  </span>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//dialog
is import for Terminal Services </font>
                  </span>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//installations.
Note: It is possible to </font>
                  </span>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//allow
other users to cancel the ongoing </font>
                  </span>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//update
process</font>
                  </span>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000"> </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//This
dialog is shown for 5 seconds </font>
                  </span>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <span style="color: ">
                    <font style="font-size: 10pt" color="#008000">//before
it is closed automatically</font>
                  </span>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#0000ff">if</font>
                    </span>
                    <font color="#000000">(</font>
                    <span style="color: ">
                      <font color="#cc0071">!</font>
                    </span>
                    <font color="#000000">e</font>
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">IsInitiatingController)
{</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">            </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#2b91af">ApplicationUpdateInitiatedDialog</font>
                    </span>
                    <font color="#000000"> dlg </font>
                    <span style="color: ">
                      <font color="#cc0071">=</font>
                    </span>
                    <font color="#000000">
                    </font>
                  </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">        </font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#0000ff">new</font>
                    </span>
                    <font color="#000000">
                    </font>
                    <span style="color: ">
                      <font color="#2b91af">ApplicationUpdateInitiatedDialog</font>
                    </span>
                    <font color="#000000">(</font>
                    <span style="color: ">
                      <font color="#0000ff">false</font>
                    </span>
                    <font color="#000000">);</font>
                  </font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font color="#000000">
                    <font style="font-size: 10pt">           
dlg</font>
                  </font>
                  <font style="font-size: 10pt">
                    <span style="color: ">
                      <font color="#cc0071">.</font>
                    </span>
                    <font color="#000000">ShowDialog(</font>
                    <span style="color: ">
                      <font color="#0000ff">this</font>
                    </span>
                    <font color="#000000">);</font>
                  </font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000">       
}</font>
                </font>
              </li>
              <li style="background: #f3f3f3">
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000">   
}</font>
                </font>
              </li>
              <li>
                <font face="Courier New">
                  <font style="font-size: 10pt" color="#000000">}</font>
                </font>
              </li>
            </ol>
          </div>
        </div>
        <p>
          <b>Prevent Users from Restarting During the Update</b>
        </p>
        <p>
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.
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/Terminal-Services_CC10/clip_image001.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image001" border="0" alt="clip_image001" src="http://www.kineticjump.com/images/blog/Terminal-Services_CC10/clip_image001_thumb.png" width="405" height="284" />
          </a>
        </p>
        <p>
          <a href="http://www.kineticjump.com/files/terminalservicesexample.zip" target="_blank">Download
Terminal Services Example Project</a>
        </p>
        <img width="0" height="0" src="http://blog.kineticjump.com/aggbug.ashx?id=82f95758-6f6c-4ea9-8845-a4028d063d0a" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Using AppLife DNA to Analyze, Define, and Review Software Requirements</title>
    <link rel="alternate" type="text/html" href="http://blog.kineticjump.com/2012/02/10/UsingAppLifeDNAToAnalyzeDefineAndReviewSoftwareRequirements.aspx" />
    <id>http://blog.kineticjump.com/PermaLink,guid,43c66277-3b93-4a81-a60b-4f74efaead19.aspx</id>
    <published>2012-02-10T16:27:55.8549998-06:00</published>
    <updated>2012-02-10T16:31:22.3393748-06:00</updated>
    <category term="AppLife DNA" label="AppLife DNA" scheme="http://blog.kineticjump.com/CategoryView,category,AppLifeDNA.aspx" />
    <category term="Requirements Management" label="Requirements Management" scheme="http://blog.kineticjump.com/CategoryView,category,RequirementsManagement.aspx" />
    <author>
      <name>Brian Haas</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
The ability to organize and define software requirements using AppLife DNA just got
better! We’ve released version 3.0 of AppLife DNA and with this release comes an exceptional
user interface mockup designer and collaborative online reviews.
</p>
        <h2>The AppLife DNA Mockup Designer
</h2>
        <p>
Mockups are a major component of defining and designing software systems and having
the ability to quickly insert and create screen mockups directly within AppLife DNA
significantly improves your ability to communicate your ideas and the details of your
requirements elicitation work.
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/fe695cd2501c_DC8A/image.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://www.kineticjump.com/images/blog/fe695cd2501c_DC8A/image_thumb.png" width="420" height="379" />
          </a>
        </p>
        <p>
          <b>Insert and Configure User Interface Elements</b>
        </p>
        <p>
With the new AppLife DNA Mockup Editor, creating screen mockups is a breeze. Simply
drag and drop the visual objects that you are already familiar with from the palette.
Mockup visuals are configured using simple text phrases and click-able adornments.
There are over 50 mockup visuals ready to use, with more to come. The mockup designer
has an image gallery with 100's of images , and gallery images can be inserted into
visual controls by using their names in parentheses.
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/fe695cd2501c_DC8A/clip_image003.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image003" border="0" alt="clip_image003" src="http://www.kineticjump.com/images/blog/fe695cd2501c_DC8A/clip_image003_thumb.png" width="244" height="211" />
          </a>
          <a href="http://www.kineticjump.com/images/blog/fe695cd2501c_DC8A/clip_image004.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image004" border="0" alt="clip_image004" src="http://www.kineticjump.com/images/blog/fe695cd2501c_DC8A/clip_image004_thumb.png" width="244" height="211" />
          </a>
        </p>
        <p>
          <b>Arrange and Align Elements</b>
        </p>
        <p>
User interface elements can be quickly aligned using snap-lines and familiar alignment
commands.
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/fe695cd2501c_DC8A/clip_image005.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image005" border="0" alt="clip_image005" src="http://www.kineticjump.com/images/blog/fe695cd2501c_DC8A/clip_image005_thumb.png" width="244" height="209" />
          </a>
          <a href="http://www.kineticjump.com/images/blog/fe695cd2501c_DC8A/clip_image007.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image007" border="0" alt="clip_image007" src="http://www.kineticjump.com/images/blog/fe695cd2501c_DC8A/clip_image007_thumb.png" width="205" height="244" />
          </a>
        </p>
        <p>
Elements can also be grouped, so that they can be manipulated as a single unit. Container
controls, such as forms, tabs and panels, utilize <i>implicit grouping</i> providing
the ability to move all of their contents around along with the container without
having to create explicit groups to do so.
</p>
        <p>
          <b>Start From Existing Screens</b>
        </p>
        <p>
Get started quickly mocking up new features to existing applications by taking a screen
shot and then paste it right into the mockup editor. Can you spot the mocked up content
below?
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/fe695cd2501c_DC8A/clip_image008.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image008" border="0" alt="clip_image008" src="http://www.kineticjump.com/images/blog/fe695cd2501c_DC8A/clip_image008_thumb.png" width="492" height="390" />
          </a>
        </p>
        <p>
          <a href="http://www.screencast.com/t/LPxFjRQuA1" target="_blank">Watch a mockup being
created</a>
        </p>
        <p>
Using mockups instead of hand sketches to prototype user screens lets you quickly
modify the mockup based on feedback. And speaking of feedback, we've introduced a <b><i>brand
new</i></b> way to solicit stakeholder feedback with AppLife DNA Online Reviews.
</p>
        <h2>AppLife DNA Online Reviews
</h2>
        <p>
You’ve gathered requirements, elaborated some details, described the features and
mocked up some screens. Now you need stakeholder feedback to validate your understanding
and move forward. Getting stakeholder feedback at this point, when it is still cheap
to change things is <i>essential. </i>AppLife DNA Online Reviews helps you get it.
</p>
        <p>
With AppLife DNA Online Reviews you can publish any content in AppLife DNA to the
Online Review Service and invite up to 20 stakeholders to participate in a short duration
(1 - 14 days) online collaborative review session. We've made it as painless as possible
for your stakeholders. No account or licensing needed, just an email address and an
interest in the content you have published. Your stakeholders receive an email invitation
with a link, where they can enter the review session, review your work, read everyone's
comments and post comments themselves.
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/fe695cd2501c_DC8A/clip_image009.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="clip_image009" border="0" alt="clip_image009" src="http://www.kineticjump.com/images/blog/fe695cd2501c_DC8A/clip_image009_thumb.png" width="544" height="409" />
          </a>
        </p>
        <p>
Reviewers can leave page comments, highlight and strike through text, and use digital
ink for comments. When the review closes, return to AppLife DNA where you can use
this valuable feedback to modify your content as necessary. With Online Reviews, everyone
reviews your content <i>at the same time</i> and sees everyone's comments, which drastically
speeds up the process and improves the quality of the feedback. It's a very quick
and painless method to solicit feedback.
</p>
        <p>
          <b>Passcode Encryption</b>
        </p>
        <p>
For users who are concerned with publishing sensitive requirements information to
the cloud, we've taken a big step towards alleviating this concern. When content is
published to the Online Review system, you can choose to protect the review with a
passcode. If a passcode is provided, the published document and all comments are encrypted
using the passcode before being sent to the Online Review Service. The passcode is
never transmitted and no one who doesn't know the passcode will <i>ever </i>be able
to decrypt and review the published content.
</p>
        <p>
          <b>Short Durations for Fast Turnaround</b>
        </p>
        <p>
Online Review durations are short, usually only a few days. This encourages stakeholders
to contribute now, not later, and also encourages collaborative back and fourth feedback.
When a review closes, the Online Review service keeps the content only long enough
for the publisher to retrieve the information from AppLife DNA, and then disposes
of all published data. Online Reviews live for a short, sweet, and <b><i>effective </i></b>period
of time.
</p>
        <p>
The Online Review service can be used during the AppLife DNA 30 day evaluation period,
so <a title="Download AppLife DNA" href="http://www.kineticjump.com/downloads/applifednacurrentversion.aspx" rel="nofollow" target="_blank">download
AppLife DNA</a> and check out this exciting new method of soliciting requirements
feedback today! 
</p>
        <img width="0" height="0" src="http://blog.kineticjump.com/aggbug.ashx?id=43c66277-3b93-4a81-a60b-4f74efaead19" />
      </div>
    </content>
  </entry>
  <entry>
    <title>No IT Needed</title>
    <link rel="alternate" type="text/html" href="http://blog.kineticjump.com/2011/09/06/NoITNeeded.aspx" />
    <id>http://blog.kineticjump.com/PermaLink,guid,d7ca36b3-6115-42e8-b616-99f860175944.aspx</id>
    <published>2011-09-06T13:47:00-05:00</published>
    <updated>2011-09-06T10:57:38.9630252-05:00</updated>
    <category term="Application Deployment" label="Application Deployment" scheme="http://blog.kineticjump.com/CategoryView,category,ApplicationDeployment.aspx" />
    <category term="AppLife Update" label="AppLife Update" scheme="http://blog.kineticjump.com/CategoryView,category,AppLifeUpdate.aspx" />
    <category term="Software Updating" label="Software Updating" scheme="http://blog.kineticjump.com/CategoryView,category,SoftwareUpdating.aspx" />
    <author>
      <name>Brian Haas</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
          <img style="border-right-width: 0px; margin: 0px 0px 0px 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="No IT Needed" border="0" alt="No IT Needed" align="right" src="http://www.kineticjump.com/images/blog/NoITNeeded_98A6/NoITNeeded.png" width="191" height="260" />
        </p>
        <p>
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 <i>all</i> 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. <i>Fortunately for you, AppLife Update provides the tools to keep
your deployed applications maintained without relying on the IT guy.</i></p>
        <p>
What are those tools, you ask? Why it’s the AppLife Update solution, consisting of:
</p>
        <ul>
          <li>
            <b>Update Controller</b>
            <br />
This .Net control integrates into your application to manage discovery, download,
and initiation of your maintenance updates. 
<br /></li>
          <li>
            <b>Update Permissions Elevation Windows Service</b>
            <br />
This Windows Service deploys with your application and <i>securely</i> 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. 
<br />
**Initial deployment requires administrative privileges. 
<br /></li>
          <li>
            <b>Update Engine 
<br /></b>The update engine is downloaded by the Update Controller and performs the update
on the deployed client. <i>The update engine can execute the Windows Installer packages
that you are already creating to update your software.</i> 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 
</li>
        </ul>
        <p>
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.
</p>
        <img width="0" height="0" src="http://blog.kineticjump.com/aggbug.ashx?id=d7ca36b3-6115-42e8-b616-99f860175944" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Implementing a Silent Updating Process</title>
    <link rel="alternate" type="text/html" href="http://blog.kineticjump.com/2011/02/23/ImplementingASilentUpdatingProcess.aspx" />
    <id>http://blog.kineticjump.com/PermaLink,guid,a7348093-c5f5-4f15-9c69-0ddcea9f5d23.aspx</id>
    <published>2011-02-22T20:18:00-06:00</published>
    <updated>2011-02-22T15:38:01.3305666-06:00</updated>
    <category term="AppLife Update" label="AppLife Update" scheme="http://blog.kineticjump.com/CategoryView,category,AppLifeUpdate.aspx" />
    <category term="Software Updating" label="Software Updating" scheme="http://blog.kineticjump.com/CategoryView,category,SoftwareUpdating.aspx" />
    <author>
      <name>Brian Haas</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
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. 
</p>
        <p>
          <b>The Process</b>
        </p>
        <p>
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.
</p>
        <p>
          <b>Handling Unexpected Errors</b>
        </p>
        <p>
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.
</p>
        <p>
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.
</p>
        <p>
Now that we have a plan, we can go forward with implementation.
</p>
        <p>
          <b>Implementation</b>
        </p>
        <p>
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.
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/ImplementingaSilentUpdatingProcess_D764/image_4.png">
            <img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="image" border="0" alt="image" src="http://www.kineticjump.com/images/blog/ImplementingaSilentUpdatingProcess_D764/image.png" width="408" height="337" />
          </a>
        </p>
        <p>
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.
</p>
        <p>
          <i>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. </i>
        </p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/ImplementingaSilentUpdatingProcess_D764/image_5.png">
            <img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="image" border="0" alt="image" src="http://www.kineticjump.com/images/blog/ImplementingaSilentUpdatingProcess_D764/image_thumb.png" width="280" height="152" />
          </a>
        </p>
        <p>
Now that we have an Update Controller in the application and a project setup, we’ll
implement our desired update process.
</p>
        <p>
          <i>Checking For Updates</i>
        </p>
        <p>
To check for updates, we’ll use the <i>CheckForUpdateAsync </i>method on the Update
Controller. This check is performed asynchronously, and when the check completes,
the <i>CheckForUpdateCompleted</i> event is raised.
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="lnum"> 1: </span>
            <strong>
              <span class="kwrd">using</span> Kjs.AppLife.Update.Controller;</strong>
          </pre>
          <pre>
            <span class="lnum"> 2: </span> </pre>
          <pre class="alt">
            <span class="lnum"> 3: </span> </pre>
          <pre>
            <span class="lnum"> 4: </span>
            <span class="kwrd">public</span> Form1() {</pre>
          <pre class="alt">
            <span class="lnum"> 5: </span> InitializeComponent();</pre>
          <pre>
            <span class="lnum"> 6: </span>
          </pre>
          <pre class="alt">
            <span class="lnum"> 7: </span>
            <span class="rem">
              <strong>//check
for updates</strong>
            </span>
          </pre>
          <pre>
            <span class="lnum"> 8: </span>
            <strong>updateController1.CheckForUpdateCompleted
+= </strong>
          </pre>
          <pre class="alt">
            <span class="lnum"> 9: </span>
            <strong>
              <span class="kwrd">new</span> CheckForUpdateCompletedEventHandler(</strong>
          </pre>
          <pre>
            <span class="lnum"> 10: </span>
            <strong>updateController1_CheckForUpdateCompleted);</strong>
          </pre>
          <pre class="alt">
            <span class="lnum"> 11: </span>
            <strong>updateController1.CheckForUpdateAsync();</strong>
          </pre>
          <pre>
            <span class="lnum"> 12: </span>}</pre>
          <pre class="alt">
            <span class="lnum"> 13: </span>
          </pre>
          <pre>
            <span class="lnum"> 14: </span>
            <strong>
              <span class="kwrd">void</span> updateController1_CheckForUpdateCompleted(<span class="kwrd">object</span> sender,</strong>
          </pre>
          <pre class="alt">
            <span class="lnum"> 15: </span>
            <strong>CheckForUpdateCompletedEventArgs
e) {</strong>
          </pre>
          <pre>
            <span class="lnum"> 16: </span>
            <strong>
              <span class="kwrd">if</span>(e.Result
== <span class="kwrd">true</span>) { </strong>
          </pre>
          <pre class="alt">
            <span class="lnum"> 17: </span>
            <span class="rem">
              <strong>//An update
is availabe</strong>
            </span>
          </pre>
          <pre>
            <span class="lnum"> 18: </span>
          </pre>
          <pre class="alt">
            <span class="lnum"> 19: </span>
            <strong>}</strong>
          </pre>
          <pre>
            <span class="lnum"> 20: </span>
            <strong>}</strong>
          </pre>
        </div>
        <style type="text/css">






.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
After the check completes, we can check to see if the update is already downloaded
by inspecting the <i>IsDownloaded </i>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 <i>DownloadUpdateCompleted</i> 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 <i>DownloadUpdateProgressChanged </i>event to monitor download progress. 
<br /></p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="lnum"> 1: </span>
            <span class="kwrd">public</span> Form1()
{</pre>
          <pre>
            <span class="lnum"> 2: </span> InitializeComponent();</pre>
          <pre class="alt">
            <span class="lnum"> 3: </span>
          </pre>
          <pre>
            <span class="lnum"> 4: </span>
            <span class="rem">//check for updates</span>
          </pre>
          <pre class="alt">
            <span class="lnum"> 5: </span> updateController1.CheckForUpdateCompleted
+= </pre>
          <pre>
            <span class="lnum"> 6: </span>
            <span class="kwrd">new</span> CheckForUpdateCompletedEventHandler(</pre>
          <pre class="alt">
            <span class="lnum"> 7: </span> updateController1_CheckForUpdateCompleted);</pre>
          <pre>
            <span class="lnum"> 8: </span>
            <strong>updateController1.DownloadUpdateCompleted
+=</strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 9: </span>
              <span class="kwrd">new</span> AsyncCompletedEventHandler(</strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 10: </span> updateController1_DownloadUpdateCompleted);</strong>
          </pre>
          <pre class="alt">
            <span class="lnum"> 11: </span> updateController1.CheckForUpdateAsync();</pre>
          <pre>
            <span class="lnum"> 12: </span>}</pre>
          <pre class="alt">
            <span class="lnum"> 13: </span>
          </pre>
          <pre>
            <span class="lnum"> 14: </span>
            <strong>
              <span class="kwrd">void</span> updateController1_DownloadUpdateCompleted(<span class="kwrd">object</span> sender,</strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 15: </span> AsyncCompletedEventArgs e)
{</strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 16: </span>
              <span class="rem">//Download completed.
Ready to apply on next startup.</span>
            </strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 17: </span>}</strong>
          </pre>
          <pre>
            <span class="lnum"> 18: </span>
          </pre>
          <pre class="alt">
            <span class="lnum"> 19: </span>
            <span class="kwrd">void</span> updateController1_CheckForUpdateCompleted(<span class="kwrd">object</span> sender,</pre>
          <pre>
            <span class="lnum"> 20: </span> CheckForUpdateCompletedEventArgs e) {</pre>
          <pre class="alt">
            <span class="lnum"> 21: </span>
            <span class="kwrd">if</span>(e.Result
== <span class="kwrd">true</span>) { </pre>
          <pre>
            <span class="lnum"> 22: </span>
            <span class="rem">//An update is available</span>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 23: </span>
              <span class="kwrd">if</span>(updateController1.CurrentUpdate.IsDownloaded
== <span class="kwrd">true</span>) {</strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 24: </span>
              <span class="rem">//the update is already
downloaded, go ahead and apply it.</span>
            </strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 25: </span> } <span class="kwrd">else</span> { </strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 26: </span>
              <span class="rem">//start the download</span>
            </strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 27: </span> updateController1.DownloadUpdateAsync();</strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 28: </span> }</strong>
          </pre>
          <pre class="alt">
            <span class="lnum"> 29: </span> }</pre>
          <pre>
            <span class="lnum"> 30: </span>}</pre>
        </div>
        <style type="text/css">





.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
          <i>Applying the Update</i>
        </p>
        <p>
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. 
<br /></p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="lnum"> 1: </span>
            <span class="kwrd">void</span> updateController1_CheckForUpdateCompleted(<span class="kwrd">object</span> sender, </pre>
          <pre>
            <span class="lnum"> 2: </span> CheckForUpdateCompletedEventArgs e) {</pre>
          <pre class="alt">
            <span class="lnum"> 3: </span>
            <span class="kwrd">if</span>(e.Result
== <span class="kwrd">true</span>) { </pre>
          <pre>
            <span class="lnum"> 4: </span>
            <span class="rem">//An update is availabe</span>
          </pre>
          <pre class="alt">
            <span class="lnum"> 5: </span>
            <span class="kwrd">if</span>(updateController1.CurrentUpdate.IsDownloaded
== <span class="kwrd">true</span>) {</pre>
          <pre>
            <span class="lnum"> 6: </span>
            <span class="rem">//the update is already downloaded,
go ahead and apply it.</span>
          </pre>
          <pre class="alt">
            <span class="lnum"> 7: </span>
            <strong>updateController1.ApplyUpdate(ApplyUpdateOptions.NoUpdateWindow);</strong>
          </pre>
          <pre>
            <span class="lnum"> 8: </span> } <span class="kwrd">else</span> { </pre>
          <pre class="alt">
            <span class="lnum"> 9: </span>
            <span class="rem">//start the download</span>
          </pre>
          <pre>
            <span class="lnum"> 10: </span> updateController1.DownloadUpdateAsync();</pre>
          <pre class="alt">
            <span class="lnum"> 11: </span> }</pre>
          <pre>
            <span class="lnum"> 12: </span> }</pre>
        </div>
        <style type="text/css">





.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
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.
</p>
        <p>
          <i>Error Handling</i>
        </p>
        <p>
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 <i>WebException</i> 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.
</p>
        <p>
 
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="lnum"> 1: </span>
            <span class="kwrd">void</span> updateController1_DownloadUpdateCompleted(<span class="kwrd">object</span> sender,</pre>
          <pre>
            <span class="lnum"> 2: </span> AsyncCompletedEventArgs e) {</pre>
          <pre class="alt">
            <span class="lnum"> 3: </span>
            <span class="rem">//Download completed.
Ready to apply on next startup.</span>
          </pre>
          <pre>
            <span class="lnum"> 4: </span>
            <strong>
              <span class="kwrd">if</span>(e.Error != <span class="kwrd">null</span>)
{</strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 5: </span>
              <span class="rem">//An error
occurred.</span>
            </strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 6: </span>
              <span class="kwrd">if</span>(e.Error <span class="kwrd">is</span> DownloadException)
{</strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 7: </span>
              <span class="rem">//A download
exception is thrown when something unexpected happens.</span>
            </strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 8: </span>
              <span class="rem">//The InnerException
property will hold the exception that occurred.</span>
            </strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 9: </span>
              <span class="kwrd">string</span> errorMsg
= <span class="str">""</span>;</strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 10: </span>
              <span class="kwrd">if</span>(e.Error.InnerException
!= <span class="kwrd">null</span>) {</strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 11: </span> errorMsg = e.Error.InnerException.Message;</strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 12: </span> } <span class="kwrd">else</span> {</strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 13: </span> errorMsg = e.Error.Message;</strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 14: </span> }</strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 15: </span> MessageBox.Show(</strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 16: </span>
              <span class="kwrd">string</span>.Format(<span class="str">"An
error occurred downloading an update: {0}"</span>,</strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 17: </span> errorMsg));</strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 18: </span> }</strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 19: </span> }</strong>
          </pre>
          <pre>
            <span class="lnum"> 20: </span>}</pre>
          <pre class="alt">
            <span class="lnum"> 21: </span>
          </pre>
          <pre>
            <span class="lnum"> 22: </span>
            <span class="kwrd">void</span> updateController1_CheckForUpdateCompleted(<span class="kwrd">object</span> sender,</pre>
          <pre class="alt">
            <span class="lnum"> 23: </span> CheckForUpdateCompletedEventArgs
e) {</pre>
          <pre>
            <span class="lnum"> 24: </span>
            <strong>
              <span class="kwrd">if</span>(e.Error
!= <span class="kwrd">null</span>) {</strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 25: </span>
              <span class="rem">//An error
occurred.</span>
            </strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 26: </span>
              <span class="kwrd">if</span>(e.Error <span class="kwrd">is</span> DownloadException)
{ </strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 27: </span>
              <span class="rem">//A download
exception is thrown when something unexpected happens.</span>
            </strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 28: </span>
              <span class="rem">//The InnerException
property will hold the exception that occurred.</span>
            </strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 29: </span>
              <span class="kwrd">string</span> errorMsg
= <span class="str">""</span>;</strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 30: </span>
              <span class="kwrd">if</span>(e.Error.InnerException
!= <span class="kwrd">null</span>){</strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 31: </span> errorMsg = e.Error.InnerException.Message;</strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 32: </span> }<span class="kwrd">else</span>{</strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 33: </span> errorMsg = e.Error.Message;</strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 34: </span> }</strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 35: </span> MessageBox.Show(</strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 36: </span>
              <span class="kwrd">string</span>.Format(<span class="str">"An
error occurred checking for updates: {0}"</span>,</strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 37: </span> errorMsg)); </strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 38: </span> }</strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 39: </span> }</strong>
          </pre>
          <pre>
            <span class="lnum"> 40: </span> …</pre>
          <pre class="alt">
            <span class="lnum"> 41: </span> </pre>
        </div>
        <style type="text/css">





.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
          <i>Detecting a Failed Update Execution</i>
        </p>
        <p>
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.
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="lnum"> 1: </span>InitializeComponent();</pre>
          <pre>
            <span class="lnum"> 2: </span>
          </pre>
          <pre class="alt">
            <span class="lnum"> 3: </span>
            <span class="rem">//check for updates</span>
          </pre>
          <pre>
            <span class="lnum"> 4: </span> updateController1.CheckForUpdateCompleted += </pre>
          <pre class="alt">
            <span class="lnum"> 5: </span>
            <span class="kwrd">new</span> CheckForUpdateCompletedEventHandler(</pre>
          <pre>
            <span class="lnum"> 6: </span> updateController1_CheckForUpdateCompleted);</pre>
          <pre class="alt">
            <span class="lnum"> 7: </span> updateController1.DownloadUpdateCompleted
+= </pre>
          <pre>
            <span class="lnum"> 8: </span>
            <span class="kwrd">new</span> AsyncCompletedEventHandler(</pre>
          <pre class="alt">
            <span class="lnum"> 9: </span> updateController1_DownloadUpdateCompleted);</pre>
          <pre>
            <span class="lnum"> 10: </span>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 11: </span>
              <span class="rem">//Read
last update results</span>
            </strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 12: </span> LastUpdate lastUpdate = updateController1.ReadLastUpdateInformation();</strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 13: </span>
              <span class="kwrd">if</span>(lastUpdate
!= <span class="kwrd">null</span> &amp;&amp;</strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 14: </span> lastUpdate.Result == UpdateResult.Failure
&amp;&amp; </strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 15: </span> lastUpdate.StartingVersion
== updateController1.Version) {</strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 16: </span>
              <span class="rem">//An update failed.
Prompt the user.</span>
            </strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 17: </span>
              <span class="kwrd">if</span>(MessageBox.Show(<span class="kwrd">string</span>.Format(</strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 18: </span>
            </strong>
            <span class="str">
              <strong>"An
unexpected error occurred while silently applying an update:</strong>
            </span>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 19: </span> {0}\n\nWould you like to
retry the update?"</strong>
            <strong>,</strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 20: </span> lastUpdate.ErrorText), <span class="str">"Update
Error"</span>, MessageBoxButtons.YesNo) == </strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 21: </span> DialogResult.Yes) { </strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 22: </span>
              <span class="rem">//launch an interactive
update</span>
            </strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 23: </span> updateController1.UpdateInteractive(<span class="kwrd">this</span>);</strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 24: </span> }</strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 25: </span> } <span class="kwrd">else</span> { </strong>
          </pre>
          <pre>
            <strong>
              <span class="lnum"> 26: </span> updateController1.CheckForUpdateAsync();</strong>
          </pre>
          <pre class="alt">
            <strong>
              <span class="lnum"> 27: </span> }</strong>
          </pre>
        </div>
        <style type="text/css">





.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
          <b>Conclusion</b>
        </p>
        <p>
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.
</p>
        <img width="0" height="0" src="http://blog.kineticjump.com/aggbug.ashx?id=a7348093-c5f5-4f15-9c69-0ddcea9f5d23" />
      </div>
    </content>
  </entry>
  <entry>
    <title>How to Hide the Error When Out of Network Range</title>
    <link rel="alternate" type="text/html" href="http://blog.kineticjump.com/2011/01/13/HowToHideTheErrorWhenOutOfNetworkRange.aspx" />
    <id>http://blog.kineticjump.com/PermaLink,guid,e4c30f0c-7734-4d22-b8fa-4ff015428329.aspx</id>
    <published>2011-01-13T14:19:00-06:00</published>
    <updated>2011-01-13T10:25:25.6164474-06:00</updated>
    <category term="AppLife Update" label="AppLife Update" scheme="http://blog.kineticjump.com/CategoryView,category,AppLifeUpdate.aspx" />
    <category term="Software Updating" label="Software Updating" scheme="http://blog.kineticjump.com/CategoryView,category,SoftwareUpdating.aspx" />
    <author>
      <name>Brian Haas</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
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.
</p>
        <p>
 
</p>
        <p>
          <img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="image" border="0" alt="image" src="http://www.kineticjump.com/images/blog/HowtoHidetheErrorWhenOutofNetworkRange_91B6/image.png" width="244" height="74" />
        </p>
        <p>
 
</p>
        <p>
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.
</p>
        <p>
By listening for the <em>CheckForUpdateCompleted</em> event of the Update Controller,
information about the error can be inspected and we can hide the control if a connectivity
issue is discovered.
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="lnum"> 1: </span>
            <span class="kwrd">private</span>
            <span class="kwrd">void</span> updateController1_CheckForUpdateCompleted(<span class="kwrd">object</span> sender,</pre>
          <pre>
            <span class="lnum"> 2: </span> Kjs.AppLife.Update.Controller.CheckForUpdateCompletedEventArgs
e) {</pre>
          <pre class="alt">
            <span class="lnum"> 3: </span>
            <span class="kwrd">if</span>(e.Error
!= <span class="kwrd">null</span> &amp;&amp;</pre>
          <pre>
            <span class="lnum"> 4: </span> e.Error.InnerException != <span class="kwrd">null</span> &amp;&amp;</pre>
          <pre class="alt">
            <span class="lnum"> 5: </span> e.Error.InnerException <span class="kwrd">is</span> WebException)
{</pre>
          <pre>
            <span class="lnum"> 6: </span> WebException ex = e.Error.InnerException <span class="kwrd">as</span> WebException;</pre>
          <pre class="alt">
            <span class="lnum"> 7: </span>
            <span class="kwrd">if</span>(ex.Status
== WebExceptionStatus.NameResolutionFailure ||</pre>
          <pre>
            <span class="lnum"> 8: </span> ex.Status == WebExceptionStatus.ConnectFailure)
{</pre>
          <pre class="alt">
            <span class="lnum"> 9: </span>
            <span class="rem">//There is connectivity
issue. </span>
          </pre>
          <pre>
            <span class="lnum"> 10: </span>
            <span class="rem">//Hide the update control,
instead of showing an error.</span>
          </pre>
          <pre class="alt">
            <span class="lnum"> 11: </span>
            <span class="kwrd">this</span>.updateDisplay1.Visible
= <span class="kwrd">false</span>;</pre>
          <pre>
            <span class="lnum"> 12: </span> }</pre>
          <pre class="alt">
            <span class="lnum"> 13: </span> }</pre>
          <pre>
            <span class="lnum"> 14: </span>}</pre>
        </div>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
          <strong>Another Alternative</strong>
        </p>
        <p>
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 <em>Version</em> 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.
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="lnum"> 1: </span>Kjs.AppLife.Update.Controller.CheckForUpdateCompletedEventArgs
e) {</pre>
          <pre>
            <span class="lnum"> 2: </span>
            <span class="kwrd">if</span>(e.Error != <span class="kwrd">null</span> &amp;&amp;</pre>
          <pre class="alt">
            <span class="lnum"> 3: </span> e.Error.InnerException != <span class="kwrd">null</span> &amp;&amp;</pre>
          <pre>
            <span class="lnum"> 4: </span> e.Error.InnerException <span class="kwrd">is</span> WebException)
{</pre>
          <pre class="alt">
            <span class="lnum"> 5: </span> WebException ex = e.Error.InnerException <span class="kwrd">as</span> WebException;</pre>
          <pre>
            <span class="lnum"> 6: </span>
            <span class="kwrd">if</span>(ex.Status == WebExceptionStatus.NameResolutionFailure
||</pre>
          <pre class="alt">
            <span class="lnum"> 7: </span> ex.Status == WebExceptionStatus.ConnectFailure)
{</pre>
          <pre>
            <span class="lnum"> 8: </span>
            <span class="rem">//There is connectivity issue. </span>
          </pre>
          <pre class="alt">
            <span class="lnum"> 9: </span>
            <span class="rem">//Start an update
check that will not find an update.</span>
          </pre>
          <pre>
            <span class="lnum"> 10: </span>
            <span class="kwrd">string</span> appDir = Path.GetDirectoryName(Application.ExecutablePath);</pre>
          <pre class="alt">
            <span class="lnum"> 11: </span>
            <span class="kwrd">this</span>.updateController1.UpdateLocation
= appDir;</pre>
          <pre>
            <span class="lnum"> 12: </span>
            <span class="kwrd">this</span>.updateController1.CheckForUpdateAsync();</pre>
          <pre class="alt">
            <span class="lnum"> 13: </span> }</pre>
          <pre>
            <span class="lnum"> 14: </span>}</pre>
        </div>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
With no network connectivity, this is what is displayed to the user.
</p>
        <p>
          <img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="image" border="0" alt="image" src="http://www.kineticjump.com/images/blog/HowtoHidetheErrorWhenOutofNetworkRange_91B6/image_3.png" width="244" height="77" /> 
</p>
        <p>
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.
</p>
        <img width="0" height="0" src="http://blog.kineticjump.com/aggbug.ashx?id=e4c30f0c-7734-4d22-b8fa-4ff015428329" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Customizing the Application Updating User Interface</title>
    <link rel="alternate" type="text/html" href="http://blog.kineticjump.com/2010/12/08/CustomizingTheApplicationUpdatingUserInterface.aspx" />
    <id>http://blog.kineticjump.com/PermaLink,guid,df3ac6c4-4bf9-4c4f-ac20-2c1371164685.aspx</id>
    <published>2010-12-07T20:39:00-06:00</published>
    <updated>2010-12-08T15:48:38.6517769-06:00</updated>
    <category term="AppLife Update" label="AppLife Update" scheme="http://blog.kineticjump.com/CategoryView,category,AppLifeUpdate.aspx" />
    <category term="Software Updating" label="Software Updating" scheme="http://blog.kineticjump.com/CategoryView,category,SoftwareUpdating.aspx" />
    <author>
      <name>Brian Haas</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
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<i></i>customize
the user experience is a differentiator for AppLife Update over competing options.
We provide <a href="http://www.kineticjump.com/solutionlab-VisualControls.aspx?id=14">turn-key
visual controls</a> and user interfaces for an application updating process right
out of the box, just like the others. <b><i>Where we are different</i></b>, is that
we <i>also</i> provide the ability for you, the integrator, to <i>completely</i> customize
the end-user updating experience. We’re not talking about changing the background
color, or adding an image. We’re talking <i>complete </i>customization. In this post,
I’ll walk through implementing a facelift customization of the AppLife update engine
user interface.
</p>
        <p>
          <b>The Built-In User Interface</b>
        </p>
        <p>
          <img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="image" border="0" alt="image" src="http://www.kineticjump.com/images/blog/CustomizingtheApplicationUpdatingUserInt_CBEE/image.png" width="404" height="231" />
        </p>
        <p>
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:
</p>
        <p align="center">
this.mUpdateController.ApplyUpdate(ApplyUpdateOptions.NoUpdateWindow);
</p>
        <p align="center">
          <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.kineticjump.com/images/blog/CustomizingtheApplicationUpdatingUserInt_CBEE/image_3.png" width="308" height="249" />
        </p>
        <p>
          <b>Replacing the Built-In User Experience</b>
        </p>
        <p>
Notice on the project settings tab above, the option to use a <i>Customized Replacement
Window.</i> 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.
</p>
        <p>
          <b>Meet the <i>IUpdateUI</i> interface. </b>
        </p>
        <p>
Any class that implements the <em>IUpdateUI </em>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.
</p>
        <p>
          <b>Methods – </b>These methods are called by the update engine as the update is executed.
</p>
        <ul>
          <li>
            <b>Open</b>
            <br />
Displays, or initializes, the user interface. 
<br /></li>
          <li>
            <b>Close</b>
            <br />
Closes the user interface. This method will not always be called by the update engine.
The update engine will call this method after the <i>Finish</i> method, only if the
host application code initiated the update with the <i>AutoClose</i> option. <i>Close</i> is
also called immediately after the <i>Finish</i> method if an error occurs during the
update. Otherwise it is expected that the user interface remain open until the user
closes it. 
<br /></li>
          <li>
            <b>Finish 
<br /></b>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 <b><i>not</i></b> be
allowed to be closed before this method is called. 
<br /></li>
          <li>
            <b>Update 
<br /></b>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. 
<br /></li>
          <li>
            <b>ShowYesNoPrompt 
<br /></b>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. 
</li>
        </ul>
        <p>
          <b>Events</b> – These events are raised by the customized update interface to communicate
with the update engine.
</p>
        <ul>
          <li>
            <b>Closed 
<br /></b>Raise this event when the UI has been closed. <b><i>This event must be raised
for the Update Engine to complete the update and shutdown. 
<br /></i></b></li>
          <li>
            <b>RequestCancel 
<br /></b>Raise this event when the user desires to cancel an executing update. The cancel
request is confirmed by the update engine through a <i>Finish</i> method call. The <i>result</i> parameter
will be set to Cancelled. 
<br /></li>
          <li>
            <b>RequestPause 
<br /></b>Raise this event when the user desires to pause the executing update. The pause
request is confirmed by the update engine through an <i>update</i> method call. The <i>uiState</i> parameter
will be set to Paused. 
<br /></li>
          <li>
            <b>RequestResume 
<br /></b>Raise this event when a paused update should be resumed. The resume request is
confirmed by the update engine through an <i>update</i> method call. The <i>uiState</i> parameter
will be set to Updating.<b></b></li>
        </ul>
        <p>
          <b>
          </b>
        </p>
        <p>
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.
</p>
        <ol>
          <li>
Create a new Windows Forms project. Make sure to target the same .Net Framework version
as your host application. Name the project <i>MyCustomUpdatingForm</i>. 
<br /></li>
          <li>
Add a reference to the assembly<em> Kjs.AppLife.Update.Engine.Core.dll.</em> If AppLife
Update is installed on your development computer, this assembly will be in the .NET
list. 
<br /><br /><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.kineticjump.com/images/blog/CustomizingtheApplicationUpdatingUserInt_CBEE/image_4.png" width="484" height="300" /><br /></li>
          <li>
View the code on <i>Form1 </i>and extend this form to implement the <i>Kjs.AppLife.Update.Engine.Core.IUpdateUI</i> interface. 
<br /><br /></li>
        </ol>
        <div class="csharpcode">
          <pre class="alt">
            <span class="lnum"> 1: </span>
            <span class="kwrd">public</span>
            <span class="kwrd">partial</span>
            <span class="kwrd">class</span> Form1
: Form, IUpdateUI {</pre>
          <pre>
            <span class="lnum"> 2: </span>...</pre>
          <pre class="alt">
            <span class="lnum"> 3: </span>}</pre>
          <br />
        </div>
        <li>
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. <i>This is your form.</i> For simplicity, this walkthrough
will use a label and a progress bar in a much smaller form factor than the built-in
updating window. 
<br /><br />
Add a label near the top of the form and name it <i>lblMessage</i>. Then set AutoSize
to false, AutoEllipse to true, and anchor to Top, Left, Right. 
<br /><br />
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. 
<br /><br />
Finally, add a cancel button below the progress bar and name it <i>btnCancel</i>. 
<br /><br /><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="image" border="0" alt="image" src="http://www.kineticjump.com/images/blog/CustomizingtheApplicationUpdatingUserInt_CBEE/image_5.png" width="398" height="147" /><br /></li>
        <li>
Implement Interface Methods 
</li>
        <p>
          <b>Open. </b>In this method, we’ll simply show the form.
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="lnum"> 1: </span>
            <span class="kwrd">public</span>
            <span class="kwrd">void</span> Open(Kjs.AppLife.Update.Engine.Core.UpdateUIContext
context) {</pre>
          <pre>
            <span class="lnum"> 2: </span>
            <span class="kwrd">this</span>.Show();</pre>
          <pre class="alt">
            <span class="lnum"> 3: </span>}</pre>
        </div>
        <style type="text/css">


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
          <b>
          </b>
        </p>
        <p>
          <b>Close. </b>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 <i>OnClosing</i> 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.
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="lnum"> 1: </span>
            <span class="kwrd">private</span>
            <span class="kwrd">bool</span> mCanClose;</pre>
          <pre>
            <span class="lnum"> 2: </span>
            <span class="kwrd">private</span>
            <span class="kwrd">bool</span> mError;</pre>
          <pre class="alt">
            <span class="lnum"> 3: </span> </pre>
          <pre>
            <span class="lnum"> 4: </span>
            <span class="kwrd">protected</span>
            <span class="kwrd">override</span>
            <span class="kwrd">void</span> OnClosing(CancelEventArgs
e) {</pre>
          <pre class="alt">
            <span class="lnum"> 5: </span>
            <span class="kwrd">base</span>.OnClosing(e);</pre>
          <pre>
            <span class="lnum"> 6: </span> </pre>
          <pre class="alt">
            <span class="lnum"> 7: </span>
            <span class="kwrd">if</span>(!mCanClose)
{</pre>
          <pre>
            <span class="lnum"> 8: </span> e.Cancel = <span class="kwrd">true</span>;</pre>
          <pre class="alt">
            <span class="lnum"> 9: </span>
            <span class="kwrd">if</span>(mError
== <span class="kwrd">true</span>) {</pre>
          <pre>
            <span class="lnum"> 10: </span> mCanClose = <span class="kwrd">true</span>;</pre>
          <pre class="alt">
            <span class="lnum"> 11: </span> }</pre>
          <pre>
            <span class="lnum"> 12: </span> }</pre>
          <pre class="alt">
            <span class="lnum"> 13: </span>}</pre>
        </div>
        <style type="text/css">


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <b>
        </b>
        <p>
          <b>
          </b>
        </p>
        <p>
          <b>Finish.</b> After the Finish method is called, the user interface can be closed.
This is signaled by setting the <em>mCanClose</em> 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.<b></b></p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="lnum"> 1: </span>
            <span class="kwrd">public</span>
            <span class="kwrd">void</span> Finish(Kjs.AppLife.Update.Engine.Core.UpdateResult
result, </pre>
          <pre>
            <span class="lnum"> 2: </span>
            <span class="kwrd">string</span> description,
Exception updateError) {</pre>
          <pre class="alt">
            <span class="lnum"> 3: </span> </pre>
          <pre>
            <span class="lnum"> 4: </span>
            <span class="kwrd">if</span>(updateError == <span class="kwrd">null</span>)
{</pre>
          <pre class="alt">
            <span class="lnum"> 5: </span> mCanClose = <span class="kwrd">true</span>;</pre>
          <pre>
            <span class="lnum"> 6: </span> Close();</pre>
          <pre class="alt">
            <span class="lnum"> 7: </span> } <span class="kwrd">else</span> {</pre>
          <pre>
            <span class="lnum"> 8: </span> lblMessage.Text = result.ToString();</pre>
          <pre class="alt">
            <span class="lnum"> 9: </span> progressBar1.Visible = <span class="kwrd">false</span>;</pre>
          <pre>
            <span class="lnum"> 10: </span> btnCancel.Enabled = <span class="kwrd">false</span>;</pre>
          <pre class="alt">
            <span class="lnum"> 11: </span> lblMessage.AutoSize = <span class="kwrd">true</span>;</pre>
          <pre>
            <span class="lnum"> 12: </span> lblMessage.Text = <span class="str">"Error:
"</span> + updateError.Message;</pre>
          <pre class="alt">
            <span class="lnum"> 13: </span> mError = <span class="kwrd">true</span>;</pre>
          <pre>
            <span class="lnum"> 14: </span> }</pre>
          <pre class="alt">
            <span class="lnum"> 15: </span>}</pre>
        </div>
        <style type="text/css">


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
          <b>Update. </b>Update the progress bar and message label.
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="lnum"> 1: </span>
            <span class="kwrd">public</span>
            <span class="kwrd">void</span> Update(Kjs.AppLife.Update.Engine.Core.UpdateUIState
uiState,</pre>
          <pre>
            <span class="lnum"> 2: </span> Kjs.AppLife.Update.Engine.Core.UpdateState updateState, </pre>
          <pre class="alt">
            <span class="lnum"> 3: </span>
            <span class="kwrd">string</span> description, <span class="kwrd">int</span> progressValue, <span class="kwrd">int</span> progressMaximum)
{</pre>
          <pre>
            <span class="lnum"> 4: </span> </pre>
          <pre class="alt">
            <span class="lnum"> 5: </span> progressBar1.Maximum = progressMaximum;</pre>
          <pre>
            <span class="lnum"> 6: </span> progressBar1.Value = progressValue;</pre>
          <pre class="alt">
            <span class="lnum"> 7: </span> </pre>
          <pre>
            <span class="lnum"> 8: </span> lblMessage.Text = description;</pre>
          <pre class="alt">
            <span class="lnum"> 9: </span>}</pre>
        </div>
        <style type="text/css">


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
          <b>ShowYesNoPrompt. </b>The simplest method is to show a message box.
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="lnum"> 1: </span>
            <span class="kwrd">public</span> YesNoResponse
ShowYesNoPrompt(<span class="kwrd">string</span> message) {</pre>
          <pre>
            <span class="lnum"> 2: </span> YesNoResponse result = YesNoResponse.No;</pre>
          <pre class="alt">
            <span class="lnum"> 3: </span>
            <span class="kwrd">if</span>(DialogResult.Yes
== MessageBox.Show(<span class="kwrd">this</span>,</pre>
          <pre>
            <span class="lnum"> 4: </span> message, <span class="str">"Update"</span>, </pre>
          <pre class="alt">
            <span class="lnum"> 5: </span> MessageBoxButtons.YesNo,</pre>
          <pre>
            <span class="lnum"> 6: </span> MessageBoxIcon.Question)) {</pre>
          <pre class="alt">
            <span class="lnum"> 7: </span> result = YesNoResponse.Yes;</pre>
          <pre>
            <span class="lnum"> 8: </span> }</pre>
          <pre class="alt">
            <span class="lnum"> 9: </span> </pre>
          <pre>
            <span class="lnum"> 10: </span>
            <span class="kwrd">return</span> result;</pre>
          <pre class="alt">
            <span class="lnum"> 11: </span>}</pre>
        </div>
        <div class="csharpcode"> 
</div>
        <p>
6.  Implement Cancel by raising the<em> RequestCancel</em> event when the Cancel
button is clicked.
</p>
        <pre class="csharpcode">
          <span class="kwrd">private</span>
          <span class="kwrd">void</span> btnCancel_Click(<span class="kwrd">object</span> sender,
EventArgs e) { <span class="kwrd">if</span>(RequestCancel != <span class="kwrd">null</span>)
{ RequestCancel(<span class="kwrd">this</span>, EventArgs.Empty); } }</pre>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
7. Implement the <i>Closed</i> event. This event informs the update engine that the
user interface has closed. A Windows Form class raises a <i>Closed</i> event when
the form is closed, so we don’t need to implement the event in this example.
</p>
        <p>
          <b>Testing the New User Interface</b>
        </p>
        <p>
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.
</p>
        <p>
          <img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="image" border="0" alt="image" src="http://www.kineticjump.com/images/blog/CustomizingtheApplicationUpdatingUserInt_CBEE/image_6.png" width="484" height="390" />
        </p>
        <p>
On the <i>Update Window</i> tab, we can import the assembly that includes our new
replacement window. The imported assembly must have only one class that implements
the <i>IUpdateUI</i> 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 <em>Test</em> button
will launch a test process.
</p>
        <p>
          <img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="image" border="0" alt="image" src="http://www.kineticjump.com/images/blog/CustomizingtheApplicationUpdatingUserInt_CBEE/image_7.png" width="385" height="135" />
        </p>
        <p>
In conclusion, by using the <i>IUpdateUI</i> 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.
</p>
        <img width="0" height="0" src="http://blog.kineticjump.com/aggbug.ashx?id=df3ac6c4-4bf9-4c4f-ac20-2c1371164685" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Application Updating by File Patching or Replacement</title>
    <link rel="alternate" type="text/html" href="http://blog.kineticjump.com/2010/11/22/ApplicationUpdatingByFilePatchingOrReplacement.aspx" />
    <id>http://blog.kineticjump.com/PermaLink,guid,f3406ab5-2133-46d7-9c85-04cfb1710e9a.aspx</id>
    <published>2010-11-21T19:13:00-06:00</published>
    <updated>2010-11-22T16:20:12.279-06:00</updated>
    <category term="AppLife Update" label="AppLife Update" scheme="http://blog.kineticjump.com/CategoryView,category,AppLifeUpdate.aspx" />
    <category term="Software Updating" label="Software Updating" scheme="http://blog.kineticjump.com/CategoryView,category,SoftwareUpdating.aspx" />
    <author>
      <name>Brian Haas</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <h4>
        </h4>
        <p>
          <img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="File Update Actions" border="0" hspace="12" alt="File Update Actions" align="right" src="http://www.kineticjump.com/images/blog/ApplicationUpdatingbyFilePatchingorRepla_E441/clip_image002.jpg" width="188" height="244" />There
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 <i>replace</i> files, and also actions that <i>patch</i> files and
folders. When would you choose a patching action over a replacement action? What’s
the difference anyways?
</p>
        <p>
          <b>Replacing Files</b>
        </p>
        <p>
Update actions that add &amp; 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. 
</p>
        <p>
          <b>Patching Files</b>
        </p>
        <p>
Actions that patch a file or folder do not place the entire file in an update. Instead,
during the update build process a <i>difference </i>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. D<i>ifference</i> 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.
</p>
        <p>
          <b>Advantages &amp; Disadvantages</b>
        </p>
        <p>
Replacing files makes an update far less dependent on the <i>specific</i> version
of the application being updated on the deployed client. For many applications, using
replacement file actions allows their update to successfully update <i>any </i>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.
</p>
        <p>
The advantage of patching files is that update packages can be significantly smaller
in physical size.
</p>
        <p>
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.
</p>
        <p>
So when would you choose one over the other? Here are a few factors that can contribute
to this decision.
</p>
        <p>
1. <b>Are specific file versions reliably present?</b><br />
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 <i>exact</i> 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.
</p>
        <p>
2. <b>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.</b><br />
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. <img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="Update File Patching vs Replacing" border="0" hspace="12" alt="Update File Patching vs Replacing" align="right" src="http://www.kineticjump.com/images/blog/ApplicationUpdatingbyFilePatchingorRepla_E441/clip_image004.jpg" width="244" height="242" /></p>
        <p>
          <b>3. </b>
          <b>To minimize update package size, use patching actions 
<br /></b>Applications with many deployed clients, or physically large files should consider
using patching actions. A <b>Patch Folder </b>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. 
<br /><b></b></p>
        <p>
          <b>4. </b>
          <b>Consider combining both patching and replacing 
<br /></b>For some applications, certain files can be safely patched while others cannot.
Both file action types can be used in a single update.
</p>
        <p>
          <b>
          </b>
        </p>
        <p>
Wrapping it up, with AppLife Update you have a choice to <em>patch</em> files or <em>replace</em> 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!
</p>
        <img width="0" height="0" src="http://blog.kineticjump.com/aggbug.ashx?id=f3406ab5-2133-46d7-9c85-04cfb1710e9a" />
      </div>
    </content>
  </entry>
</feed>
