<?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>2011-09-06T10:57:38.9630252-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>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>
  <entry>
    <title>Build and Publish Software Updates from Visual Studio</title>
    <link rel="alternate" type="text/html" href="http://blog.kineticjump.com/2010/11/12/BuildAndPublishSoftwareUpdatesFromVisualStudio.aspx" />
    <id>http://blog.kineticjump.com/PermaLink,guid,b26946e7-51fb-418f-a664-b95d990b8252.aspx</id>
    <published>2010-11-11T20:50:00-06:00</published>
    <updated>2010-11-12T16:03:47.578197-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>
So you’ve got AppLife Update <a href="http://www.kineticjump.com/update/basicdemo.aspx">integrated
into your application</a>. That was easy enough. You’ve got your AppLife Update project
set up to build and publish updates from Make Update as you release software versions.
To make the process of building your updates even easier, I’ll show you how to integrate
update building and publishing directly into your Visual Studio project build process. 
</p>
        <p>
AppLife Update ships with an MSBuild task that we can use within a Visual Studio project
file to build and publish updates as part of the Visual Studio build process. Using
this, we’ll add a new <i>Release with Update</i> build configuration to a Visual Studio
project. When this build configuration is chosen, an application update will be built
and published as the Visual Studio project builds. 
</p>
        <p>
Start by extracting the Simple C# Quick Start project. This will give us a common
project to work from. 
</p>
        <p>
          <b>Step 1 – Create a new build configuration.<img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="clip_image002" border="0" alt="clip_image002" align="right" src="http://blog.kineticjump.com/content/binary/WindowsLiveWriter/BuildandPublishSoftwareUpdatesfromVisual_DF21/clip_image002_thumb.jpg" width="244" height="143" /></b>
        </p>
        <p>
From the Visual Studio build menu, select the <i>Configuration Manager</i>. 
</p>
        <p>
Create a new build configuration and call it <i>Release with Update.</i> Select to
copy settings from the existing <i>Release</i> configuration. We’ll modify the project
to build and publish an update when this configuration is built. 
</p>
        <p>
          <b>Step 2 – Modify the Visual Studio Project File</b>
        </p>
        <p>
From the Visual Studio project menu, select to <i>Unload Project</i>. With the project
unloaded, you can edit it within Visual Studio by selecting the Simple project node
from the Solution Explorer and from the context menu, select to <i>Edit Simple.csproj.</i> With
the Visual Studio project file open in the editor, scroll to the bottom and you will
see two commented out <i>Target</i> elements. Uncomment the <b>AfterBuild</b> target
and add a <i>UsingTask</i> element that references the assembly that houses the <i>BuildUpdate</i> MSBuild
task. This assembly is located in the AppLife Update install directory. 
</p>
        <p>
Inside the <i>AfterBuild</i> target, add a <i>BuildUpdate</i> task. Set the Condition
attribute to execute only when the newly created build configuration is used. Details
on the attributes of this task are available in the <i>MSBuildTask ReadMe.rtf </i>file
located in the same folder. 
</p>
        <p>
        </p>
        <div style="width: 99.5%; color: black; overflow: auto">
          <pre style="margin: 0em">
            <span style="color: #0000ff">&lt;<span style="color: #a31515">UsingTask<span style="color: #0000ff"><span style="color: #ff0000">AssemblyFile<span style="color: #0000ff">=</span><span style="color: #000000"> "<span style="color: #0000ff">C:\Program
Files\AppLife Update\Build Automation Utilities\MSBuild\Kjs.AppLife.Update.BuildUpdateTask.dll</span><span style="color: #000000">"
</span></span></span></span></span></span>
          </pre>
          <pre style="margin: 0em">
            <span style="color: #0000ff">
              <span style="color: #ff0000">TaskName<span style="color: #0000ff">=</span><span style="color: #000000"> "<span style="color: #0000ff">Kjs.AppLife.Update.MSBuild.BuildUpdate</span><span style="color: #000000">"<span style="color: #0000ff"> /&gt;</span><span style="color: #000000"></span></span></span></span>
            </span>
          </pre>
          <pre style="margin: 0em">
          </pre>
          <pre style="margin: 0em">
            <span style="color: #0000ff">&lt;<span style="color: #a31515">Target<span style="color: #0000ff"><span style="color: #ff0000">Name<span style="color: #0000ff">=</span><span style="color: #000000"> "<span style="color: #0000ff">AfterBuild</span><span style="color: #000000">"<span style="color: #0000ff">&gt;</span><span style="color: #000000"></span></span></span></span></span></span></span>
          </pre>
          <pre style="margin: 0em">
            <span style="color: #0000ff"> &lt;<span style="color: #a31515">BuildUpdate</span><span style="color: #000000"></span></span>
          </pre>
          <pre style="margin: 0em">
            <span style="color: #0000ff">
              <span style="color: #ff0000">Condition<span style="color: #0000ff">=</span><span style="color: #000000"> " <span style="color: #0000ff">'$(Configuration)|$(Platform)’
== 'Release with Update|AnyCPU' </span><span style="color: #000000">"
</span></span></span>
            </span>
          </pre>
          <pre style="margin: 0em">
            <span style="color: #0000ff">
              <span style="color: #ff0000">ProjectFile<span style="color: #0000ff">=</span><span style="color: #000000"> "<span style="color: #0000ff">..\Simple.aup</span><span style="color: #000000"> "
</span></span></span>
            </span>
          </pre>
          <pre style="margin: 0em">
            <span style="color: #0000ff">
              <span style="color: #ff0000">UpdateVersionSource<span style="color: #0000ff">=</span><span style="color: #000000"> "<span style="color: #0000ff">$(OutputPath)\$(AssemblyName).exe</span><span style="color: #000000">"
</span></span></span>
            </span>
          </pre>
          <pre style="margin: 0em">
            <span style="color: #0000ff">
              <span style="color: #ff0000">TestOnly<span style="color: #0000ff">=</span><span style="color: #000000"> "<span style="color: #0000ff">false</span><span style="color: #000000">"
</span></span></span>
            </span>
          </pre>
          <pre style="margin: 0em">
            <span style="color: #0000ff">
              <span style="color: #ff0000">PublishLocations<span style="color: #0000ff">=</span><span style="color: #000000"> "<span style="color: #0000ff">Update
Location</span>"<span style="color: #0000ff"> /&gt;</span><span style="color: #000000"></span></span></span>
            </span>
          </pre>
          <pre style="margin: 0em">
            <span style="color: #0000ff">&lt;/<span style="color: #a31515">Target<span style="color: #0000ff">&gt;
</span></span></span>
          </pre>
          <pre style="margin: 0em">
          </pre>
        </div>
        <p>
          <b>Step 3 – Modify the aup project file to use the Release with Update output folder</b>
        </p>
        <p>
The Add &amp; Replace files action should look at the <i>Release</i> folder for its
files. Add a path relative to the aup project file. 
</p>
        <p>
Simple\bin\Release\Simple.exe 
</p>
        <p>
          <a href="http://blog.kineticjump.com/content/binary/WindowsLiveWriter/BuildandPublishSoftwareUpdatesfromVisual_DF21/image_2.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://blog.kineticjump.com/content/binary/WindowsLiveWriter/BuildandPublishSoftwareUpdatesfromVisual_DF21/image_thumb.png" width="504" height="314" />
          </a>
        </p>
        <p>
          <b>That’s it!</b>
        </p>
        <p>
Now, whenever you want to publish an update, you can select the <strong>Release with
Update</strong> build configuration and build the project. 
</p>
        <p>
          <a href="http://blog.kineticjump.com/content/binary/WindowsLiveWriter/BuildandPublishSoftwareUpdatesfromVisual_DF21/clip_image002%5B10%5D.jpg">
            <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="clip_image002[10]" border="0" alt="clip_image002[10]" src="http://blog.kineticjump.com/content/binary/WindowsLiveWriter/BuildandPublishSoftwareUpdatesfromVisual_DF21/clip_image002%5B10%5D_thumb.jpg" width="504" height="383" />
          </a>
        </p>
        <p align="center">
          <b>Visual Studio Build Output</b>
        </p>
        <p>
          <b>Parting Thoughts</b>
        </p>
        <p>
Build a test update out of Visual Studio, or build to a test update location. Both
options are just as easy. This prevents an inadvertent build from being available
to end users, and provides a built in updating testing mechanism. 
</p>
        <p>
To build a test update, set the <i>TestOnly</i> attribute to true. For clients to
see test updates, they must have a specific application setting in their app.config
file. 
</p>
        <p>
To publish to a specific test update location, you can name the publish location in
Make Update project settings, then change the PublishLocations attribute value to
match this update location.
</p>
        <img width="0" height="0" src="http://blog.kineticjump.com/aggbug.ashx?id=b26946e7-51fb-418f-a664-b95d990b8252" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Application Updates and Mayhem</title>
    <link rel="alternate" type="text/html" href="http://blog.kineticjump.com/2010/11/08/ApplicationUpdatesAndMayhem.aspx" />
    <id>http://blog.kineticjump.com/PermaLink,guid,d4ed7d72-5d87-4599-a1b8-bbe85cc1c672.aspx</id>
    <published>2010-11-07T22:31:00-06:00</published>
    <updated>2010-11-08T17:35:31.4773034-06: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" />
    <author>
      <name>Brian Haas</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Have you seen the Allstate mayhem commercials? They are pretty good. If you haven’t
seen them, take a few seconds and watch the video below. At this point, you may be
asking yourself what does that have to do with software. But then again if you’ve
been around awhile, you may not be… These spots have a lot in common with software
because in software, <i>mayhem is everywhere</i>. 
</p>
        <div style="padding-bottom: 0px; margin: 0px auto; padding-left: 0px; width: 425px; padding-right: 0px; display: block; float: none; padding-top: 0px" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:e32dcb85-cf08-4807-a777-b40199317ac6" class="wlWriterEditableSmartContent">
          <div id="a2192d2b-f1e3-418c-8961-9f4c02752e70" style="margin: 0px; padding: 0px; display: inline;">
            <div>
              <a href="http://www.youtube.com/watch?v=q9eqj7xRzk0&amp;NR=1" target="_new">
                <img src="http://www.kineticjump.com/images/blog/ApplicationUpdatesandMayhem_F447/video7af6496dc931.jpg" style="border-style: none" galleryimg="no" onload="var downlevelDiv = document.getElementById('a2192d2b-f1e3-418c-8961-9f4c02752e70'); downlevelDiv.innerHTML = &quot;&lt;div&gt;&lt;object width=\&quot;425\&quot; height=\&quot;355\&quot;&gt;&lt;param name=\&quot;movie\&quot; value=\&quot;http://www.youtube.com/v/q9eqj7xRzk0&amp;hl=en\&quot;&gt;&lt;\/param&gt;&lt;embed src=\&quot;http://www.youtube.com/v/q9eqj7xRzk0&amp;hl=en\&quot; type=\&quot;application/x-shockwave-flash\&quot; width=\&quot;425\&quot; height=\&quot;355\&quot;&gt;&lt;\/embed&gt;&lt;\/object&gt;&lt;\/div&gt;&quot;;" alt="" />
              </a>
            </div>
          </div>
        </div>
        <p>
As a software developer, if you are not finding bugs, you’re fixing them. <i>Mayhem</i>.
As a user, unexpected behaviors often occur as you go about using the software you
use. <i>Mayhem</i>. And as an administrator, you spend a lot of time working around
unexpected issues. <i>Mayhem</i>. 
</p>
        <p>
And so it is with maintaining deployed applications, or automatic application updating.
In a perfect world, an application update would never fail. <i>Most</i> don’t. And
most houses don’t catch fire either, yet we buy insurance just in case. Around here,
we put a lot of effort into ensuring that when a software update is applied, one of
two outcomes will result. A successful update, or a complete rollback. We prefer the
former, but plan for the later. And for most actions rolling back, and preparing for
the rollback that hopefully will never occur, requires more development work than
the execution of the action. Let’s look at files. Protection from mayhem is almost
all of the work involved in file actions. The first thing we do is verify that our
update process has permissions to replace the file. If we don’t, there is no sense
in proceeding. We can stop before doing anything, preventing mayhem. Then we back
up the file, including the assigned permissions, just in case mayhem happens later
on, we can restore the original file. Such is the case with all of the built-in updating
actions. With the exception of the <i>Install .Net 4.0 Framework</i> action, they
either complete their work or rollback completely. For that action, mayhem is better
avoided by leaving the framework successfully installed than to remove it during a
rollback.
</p>
        <h3>
          <strong>Our Adjuster</strong>
        </h3>
        <p>
When mayhem happens, insurance companies like Allstate will send out an adjuster to
determine the cause and extent of the damage. Our adjuster equivalent is the update
action log files. When mayhem occurs, there are few things worse than having to tell
your boss, “I don’t know why that happened”, because that means you also don’t know
the answer to the inevitable next question. “How are we going to prevent it from happening
again?” Update action logs tells the story of what happened (or didn’t happen) during
an update, and with an update log you’ll know what happened and be able to determine
how to prevent it from happening again.
</p>
        <p>
          <a href="http://www.kineticjump.com/images/blog/ApplicationUpdatesandMayhem_F447/logviewer.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="Software Update Log Viewer" border="0" alt="Software Update Log Viewer" src="http://www.kineticjump.com/images/blog/ApplicationUpdatesandMayhem_F447/logviewer_thumb.png" width="454" height="378" />
          </a>
        </p>
        <p>
If your house burns down, we can’t help much. Hopefully you have Allstate for that.
But for protecting your software updates from mayhem, look to AppLife Update. You’ll
be in good hands.
</p>
        <img width="0" height="0" src="http://blog.kineticjump.com/aggbug.ashx?id=d4ed7d72-5d87-4599-a1b8-bbe85cc1c672" />
      </div>
    </content>
  </entry>
  <entry>
    <title>To be Automatic, or be Automated… There is a Difference</title>
    <link rel="alternate" type="text/html" href="http://blog.kineticjump.com/2010/06/22/ToBeAutomaticOrBeAutomatedThereIsADifference.aspx" />
    <id>http://blog.kineticjump.com/PermaLink,guid,570f6bb5-8416-474e-8d7e-3167bd9134aa.aspx</id>
    <published>2010-06-22T13:49:00-05:00</published>
    <updated>2010-06-22T10:16:02.70975-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>
A developer doesn't have to look very hard to find an application that employs <em>automatic</em> updating. 
In fact, there’s a good chance that an icon down in the system tray right now is informing
you of an update’s availability. Some applications tell you ahead of time that updates
are available, and some tell you after the fact that an update has been applied. Some
are painstakingly obnoxious to the user, and some completely transparent. For most
desktop applications, employing a system of automatic updating makes perfect sense. 
But for many applications, especially applications consisting of services, server
components and databases, <em>automatic</em> updating isn't very desirable. 
But almost always, an <em>automated</em> update process does make sense, and should
be employed.<img style="border-right-width: 0px; margin: 10px 0px 0px 5px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Automate Software Updating" border="0" alt="Automate Software Updating" align="right" src="http://blog.kineticjump.com/content/binary/WindowsLiveWriter/TobeAutomaticorbeAutomatedWhatstheDiffer_92E1/AutomatedUpdates_3.jpg" width="227" height="227" /></p>
        <p>
If your application is deployed to more than one location and development is ongoing,
then the application should include an <em>automated</em> means to find updates and
apply them.  Not always <em>automatic</em>, but always <em>automated. </em>There
is a difference. An automated update process won’t just happen on its own, and it
often doesn't even inform the user when an update is available.  It’s there to
provide a simple, consistent, single step process to update the installed software.
Customers will thank you, and it cuts your support costs.   
</p>
        <p>
If your responsible for back office software, you’ve no doubt had the unpleasant experienced
of reviewing a software update procedure.  Software you installed a year ago,
and haven't thought of since.  You first have to re-familiarize yourself with
software terminology and configuration before you can even make sense of the upgrade
procedure. Time consuming.
</p>
        <p>
And if your a developer, you’ve no doubt written an upgrade procedure, supported customers
as they perform the upgrade, then tweaked the procedure for better understanding. 
Time consuming.
</p>
        <p>
AppLife Update provides the means to automate your application maintenance plan, and
could make a significant impact on support costs, especially if your application upgrades
involve a multi-step manual upgrade process. Even if your application is complicated,
don’t assume that implementing an automated update process would be cost prohibitive. 
If you were to start from scratch, it probably would be, but with the built-in actions
in AppLife Update, along with the Dynamic Code Action providing the means to write
and package up application-specific upgrading functionality, you’ll be automated in
no time.
</p>
        <img width="0" height="0" src="http://blog.kineticjump.com/aggbug.ashx?id=570f6bb5-8416-474e-8d7e-3167bd9134aa" />
      </div>
    </content>
  </entry>
  <entry>
    <title>AppLife Update and .Net Deployment Strategies</title>
    <link rel="alternate" type="text/html" href="http://blog.kineticjump.com/2010/04/09/AppLifeUpdateAndNetDeploymentStrategies.aspx" />
    <id>http://blog.kineticjump.com/PermaLink,guid,c4cb270f-9355-4ab8-a24c-a3dc2d847d5a.aspx</id>
    <published>2010-04-08T23:00:00-05:00</published>
    <updated>2010-06-12T23:21:32.4302748-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="ClickOnce" label="ClickOnce" scheme="http://blog.kineticjump.com/CategoryView,category,ClickOnce.aspx" />
    <author>
      <name>Brian Haas</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
To deploy .Net applications, there are two primary activities that must be accomplished. 
The application must be initially deployed (installation), and a deployed application
must be maintained (update).  The two Microsoft technologies offered to accomplish
these goals are the Windows Installer and ClickOnce.  The Windows Installer is
a very powerful technology designed specifically to deploy software onto the Windows
platform.  For many developers though, the Windows Installer can be very challenging
to utilize. In fact, there are many third party vendors competing with each other
to simplify the developer's interactions with the Windows Installer, each providing
their own Windows Installer abstraction layer.  While the Windows Installer is
flexible and can accomplish most any installation goal, it lacks easy maintenance
features (updating), comes with heavy technical resource requirements and expects
a lot from the end user, most notably administrative privileges.
</p>
        <p>
The challenges of application deployment strategies utilizing the Windows Installer,
and the emergence of the web application combined to influence the creation of ClickOnce. 
With ClickOnce, Microsoft attempted to bring the deployment simplicity of a web application
to WinForms and WPF applications. And to a large degree, they succeeded.  For
many applications ClickOnce does provide the best deployment strategy available. 
But it's not for all applications, and because of the huge void in deployment capabilities
between ClickOnce and the Windows Installer, many teams find themselves pushing the
envelope of one or both technologies in order to accomplish their goals. For applications
in that void, AppLife Update can add a tremendous amount of value to a deployment
strategy.
</p>
        <p>
AppLife Update is generally <a href="http://www.kineticjump.com/solutionlab-msi.aspx">used
in conjunction with a Windows Installer</a>, though its flexibility does provide for
the ability to <a href="http://www.kineticjump.com/solutionlab-InitialDeployment.aspx">initially
deploy applications</a> without using an MSI.  Many of our customers adopt AppLife
Update after first trying ClickOnce. Here are the primary reasons given for moving
away from ClickOnce:
</p>
        <ol>
          <li>
            <b>Difficulty in moving applications.</b> For developers who can publish directly
the final deployment location, ClickOnce is very easy to use. But for teams who need
to build at one location, and publish at another, ClickOnce is harder to manage. Development
teams with QA and testing requirements also struggle with the same challenges in moving
applications through their release process. 
<br /></li>
          <li>
            <b>Desire to install per machine. </b> With ClickOnce, applications are installed
per user.  For organizations that utilize roaming profiles, this means that applications
are often installed many times on the same machine. 
<br /></li>
          <li>
            <b>Need for side-by-side installs.  </b>With ClickOnce, installing different
versions of an application on the same machine is challenging. 
<br /></li>
          <li>
            <b>Extensive installation requirements.  </b>While it is possible to install
ClickOnce application prerequisites using an MSI, the ease-of-use that ClickOnce offers
is compromised, and these applications often push other limits of ClickOnce, such
as security requirements. 
<br /></li>
          <li>
            <b>Network Environment.  </b>Development teams whose applications target public
audiences over the internet face browser incompatibility issues, plug-in requirements,
proxy server challenges, the need for publicly recognized code signing certificate
authorities, and security sandboxing issues.  What's worse is that initial ClickOnce
testing usually passes with flying colors, but as the application use proliferates,
costly support issues arise as users run into these problems. <b></b></li>
        </ol>
        <p>
When development teams incorporate AppLife Update into their application deployment
strategy, they get:
</p>
        <ul>
          <li>
            <b>Flexible API / Extensibility. 
<br /></b>AppLife Update is not a black box. The API is extensive and allows for application-specific
manipulation of the update process, from start to finish. 
<br /></li>
          <li>
            <b>Versatile Hosting 
<br /></b>Updates can be hosted on any server (file, ftp, web) and freely moved around to
support varying deployment and testing strategies. 
<br /></li>
          <li>
            <b>Do anything during an update 
<br /></b>Any updating activity can be performed during an update. ClickOnce replace files,
but AppLife Update includes actions to perform registry work, config file manipulation,
register COM, Start/Stop Services, execute MSI major, minor upgrades, patches, etc.
There is even a dynamic code action where defined .Net code is compiled during an
update build and executed during an update.<b><br /></b></li>
          <li>
            <b>Customized Look and Feel 
<br /></b>The entire look and feel of the update process is customizable. Use the built-in
updating interface, customize it, or completel<i>y replace</i> it. 
<br /></li>
          <li>
            <b>Permissions Elevation 
<br /></b>Applications installed into Program Files cannot be updated by limited users.
For applications that target controlled desktops, this is a huge maintenance hurdle.
By utilizing AppLife Update's Windows Service to securely elevate permissions during
the update, the application can update itself, even when launched by a limited user.</li>
        </ul>
        <p>
AppLife Update provides the functionality to quickly and easily integrate application
maintenance features into a .Net application, bridging the application deployment
gap between Windows Installer deployed applications, and ClickOnce maintained applications.  
</p>
        <p>
For more information visit the AppLife Update <a href="http://www.kineticjump.com/update/">product
page</a>, <a href="http://www.kineticjump.com/forums/yaf_forum2_AppLife-Update.aspx">forums</a>, <a href="http://www.kineticjump.com/solutionlab.aspx">Solution
Lab</a>, send us an <a href="mailto:techsupport@kineticjump.com">email</a>, or give
us a call. (612) 486-9653.
</p>
        <img width="0" height="0" src="http://blog.kineticjump.com/aggbug.ashx?id=c4cb270f-9355-4ab8-a24c-a3dc2d847d5a" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Pros and Cons of File Patching, Update Chaining, vs. Broader Multi-Version Application Updates</title>
    <link rel="alternate" type="text/html" href="http://blog.kineticjump.com/2010/03/16/ProsAndConsOfFilePatchingUpdateChainingVsBroaderMultiVersionApplicationUpdates.aspx" />
    <id>http://blog.kineticjump.com/PermaLink,guid,a09692ac-115e-4bb1-a09b-9ad51f13f485.aspx</id>
    <published>2010-03-15T22:09:00-05:00</published>
    <updated>2010-06-12T23:17:28.126381-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>
Say you have a .Net application.  From a deployment perspective, your application
is a relatively normal application.  A primary executable, probably Windows Forms
or WPF based, a class library or two, and a few third party controls.  The application
has reached a shipping point and now it's time to distribute it to more than a few
workstations.  You've chosen to distribute your application using the Windows
Installer.  You're now faced with determining the strategy for maintaining the
workstations that have installed your application.  Whatever strategy you choose
to pursue, you will be confronted with this question:
</p>
        <p>
          <b>When I update my application, do I replace all of my assemblies, making updating
simple, or do I replace only what I just changed, making updates smaller, but more
complicated?</b>
        </p>
        <p>
This question is going to arise whether you create Windows Installer upgrades and
patches, use a third party updating solution, or even consider rolling your own updater. 
Regardless of the tool you use, at some point you will find yourself pondering the
topic.  The physically small update is the apparent no-brainer.  The uninitiated
may say, "of course we want our updates small.  Nobody wants to wait on
updates, and we don't want to waste bandwidth.  Net neutrality isn't here yet!"  
This is all true, and can be a compelling argument. So you march forward on the task...
until the details emerge.  To keep updates small, versioning rears its ugly head.  <i>An
incremental update can only target specific previous versions.</i>  For manually
distributed software updates, as is often the case with Windows Installer deployments,
knowing what version you have, and which patch, or patches, you need to apply becomes
as big a deterrent to end-user updating as a larger update.
</p>
        <p>
After considering the challenges of implementation, the <i>simplicity</i> of larger,
but version agnostic updates will cause you to reconsider your seemingly obvious initial
plan. This is a big reason why so many organizations start out attempting to distribute
patches and incremental upgrades, but then revert to the far more common version agnostic
approach of uninstall/re-install. (There are plenty of technical challenges involved
in actually producing working Windows Installer upgrades and patches, which also plays
a role here as well).
</p>
        <p>
So which path do you choose?  Consider the following.
</p>
        <ul>
          <li>
            <b>Frequency of updates</b>
            <br />
If you are creating updates frequently, you want the update process creation to be
as automated as possible. Decreasing the manual involvement increases efficiency as
well as lowers the opportunity for mistakes. If you have the infrastructure to automate
the creation of small, incremental updates then you should do so. If not, your update
process will be simpler and less prone to error if you build larger, version agnostic
updates. Even if you are doing this frequently. 
</li>
          <li>
            <b>Frequency of application use</b>
            <br />
For applications that are launched and updated infrequently, accumulating incremental
updates can create an undesirable user experience. Try to avoid forcing your users
to regularly discover and apply multiple updates, one right after another. You should
build larger updates that apply to more versions, or ensure your update process can
apply multiple individual updates in a single update session. <b><br /></b></li>
          <li>
            <b>Physical size of the application files 
<br /></b>Physically large application assemblies make for large updates. File patching
can significantly reduce this size of an update, but requires strict control of which
previous versions can apply the update. 
<br /><b></b></li>
          <li>
            <b>Number of deployed clients 
<br /></b>For applications with many thousands of deployed clients, the network burden of
larger updates is much more significant than applications with tens or hundreds of
deployed clients. As your installed user base grows, minimizing the physical size
of each update becomes far more important in order to manage your server bandwidth
utilization without resorting to throttled update deployment. 
<br /><b></b></li>
          <li>
            <b>Network Environment</b>
            <br />
The network speed between the update server and deployed clients can dictate your
decisions, especially when slow links are known to exist. When your application lives
within slow networks, smaller updates are more desirable. 
<br /><b></b></li>
          <li>
            <b>Background Download to Reduce the Burden 
<br /></b>Downloading updates in the background and informing the user when an update is
ready to apply removes much of the burden the user experiences with larger updates. 
It doesn't remove the burden from the network though.</li>
          <li>
            <b>Infrequent Exceptions to the Norm 
<br /></b>Targeting multiple versions, and making exceptions when you need to update infrequently
modified files, such as third-party tools and help documentation keeps the initial
update implementation effort low, ongoing update creation simple, and minimizes the
burden that updating places on the end-user.</li>
        </ul>
        <p>
A commonly pursued solution to this updating dilemma is <i>not</i> to consider application
updating as an in incremental progression, but rather a "synchronization"
process.  A process where deployed workstation application files are kept in-sync
with a master version located on a server.  This approach works well if the updating
process <i>only</i> updates files. It doesn't work so well when application maintenance
also requires performing other updating activities, such as registry and data store
maintenance.  Security and licensing concerns also make the "sync"
approach more challenging and less desirable than version migration approaches.
</p>
        <p>
Our updating solution, AppLife Update, is an incremental updating solution. 
Each update is self-contained, and includes all of the updating logic and new files/assemblies
needed to migrate a deployed application from a previous version to a new version. 
When an update is created, you get to choose which previous versions can successfully
apply the new update.  You can target <i>all</i> previous versions, a list of
discrete versions, or all greater than a previous version.  How you've defined
the update obviously determines which previous versions you can target.  When
defining an update, you have a lot of latitude in your decisions.  You can package
and deploy Windows Installer databases, you can replace whole files, you can individually
patch existing files, you can use update actions that automate the determination of
which files need to be updated.  With an update system like AppLife Update, there
is little difference in the effort needed to create updates that target all previous
versions, or just the most recent version, however the bandwidth and user experience
factors still need to be considered. 
</p>
        <p>
The flexibility is there to create the application updating strategy that best fits
your application and your organization.  If the size of the update package necessary
to replace all of the assemblies built in a standard upgrade of your application is
acceptable, your update process will be far simpler to create and maintain if you
target all previous versions with each update.  If the factors involved with
your application dictate smaller updates, you can easily extend your updating process
to <a href="http://www.kineticjump.com/solutionlab-ChainedUpdatesPart1.aspx">seamlessly
discover and download multiple updates</a>, as well as display to the user a <a href="http://www.kineticjump.com/solutionlab-ChainedUpdatesPart2.aspx">unified
updating experience</a>.
</p>
        <img width="0" height="0" src="http://blog.kineticjump.com/aggbug.ashx?id=a09692ac-115e-4bb1-a09b-9ad51f13f485" />
      </div>
    </content>
  </entry>
</feed>
