<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:georss="http://www.georss.org/georss" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Mike Bouck's RAM - ClickOnce</title>
    <link>http://blog.gatosoft.com/</link>
    <description>volatile memory sucks...</description>
    <language>en-us</language>
    <copyright>Mike Bouck</copyright>
    <lastBuildDate>Sat, 01 Apr 2006 08:11:29 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.2.8279.16125</generator>
    <managingEditor>michael@bouck.com</managingEditor>
    <webMaster>michael@bouck.com</webMaster>
    <item>
      <trackback:ping>http://blog.gatosoft.com/Trackback.aspx?guid=d0a0dd1e-c9ac-4fa9-a408-615454d49702</trackback:ping>
      <pingback:server>http://blog.gatosoft.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.gatosoft.com/PermaLink,guid,d0a0dd1e-c9ac-4fa9-a408-615454d49702.aspx</pingback:target>
      <dc:creator>Mike Bouck</dc:creator>
      <georss:point>33.13111 -117.226157</georss:point>
      <wfw:comment>http://blog.gatosoft.com/CommentView,guid,d0a0dd1e-c9ac-4fa9-a408-615454d49702.aspx</wfw:comment>
      <wfw:commentRss>http://blog.gatosoft.com/SyndicationService.asmx/GetEntryCommentsRss?guid=d0a0dd1e-c9ac-4fa9-a408-615454d49702</wfw:commentRss>
      <slash:comments>26</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">The <a href="http://msdn2.microsoft.com/en-us/library/t71a733d.aspx">ClickOnce</a> support
in Visual Studio 2005 is nice and easy but falls-down in number of areas:<br /><br /><ol><li>
The application manifest (i.e. the "stuff" that comprises your app) is determined
by walking the project references of your Windows app.  What this means is that
if you have deployment artifacts that are non-reference content or late-bound loaded
assemblies then the default ClickOnce mechanism in Visual Studio will <b>not</b> pick
them up. 
</li><li>
Oftentimes the versioning scheme for your assemblies is driven by your build process
and ideally you'd want the ClickOnce version number to be in-sync with your assembly
version.  The Visual Studio ClickOnce mechanism has a very limited versioning
scheme that is completely decoupled from assembly versioning and is inaccessible outside
of the IDE. 
</li><li>
For enterpirse scenarios, it is very common to have a segmented network dedicated
for specific functions (e.g. development, test, production).  In this scenario
the Windows app has to be designed such that certain information (e.g. connection
strings, web service urls, etc.) are pushed-into environment-specific configuration
files.  The deploy process then involves indicating what environment the built
bits should be pushed into and then the appropriate configuration files are pulled-in
by the deploy process.  In this way the same set of bits may be "promoted" from
dev to test and finally to production.  The default Visual Studio ClickOnce mechanism
has no notion of nor capability of dealing with environment-specific information.<br /></li></ol><br />
For the uninitiated there are four ways to create a ClickOnce deploy package:<br />
  
<br /><ol><li>
Via the Window app's Publish property page in Visual Studio (easiest but essentially
unuseable for apps of even moderate complexity for the reasons listed above). 
</li><li>
Via <a href="http://msdn2.microsoft.com/en-us/library/xc3tc5xx.aspx">mage.exe</a> (command-line
utility). 
</li><li>
Via <a href="http://msdn2.microsoft.com/en-us/library/xc3tc5xx.aspx">mageui.exe</a> (Windows
app). 
</li><li>
Via MSBuild (using the <a href="http://msdn2.microsoft.com/en-us/library/6wc2ccdc.aspx"><i>GenerateApplicationManifest</i></a>, <a href="http://msdn2.microsoft.com/en-us/library/3k2t34e7%28VS.80%29.aspx"><i>GenerateDeploymentManifest</i></a>, <i><a href="http://msdn2.microsoft.com/en-us/library/ms164294%28VS.80%29.aspx">GenerateBootstrapper</a></i>and <a href="http://msdn2.microsoft.com/en-us/library/ms164304%28VS.80%29.aspx"><i>SignFile</i></a> tasks).<br /></li></ol><p><br />
Note that despite the chosen method, everything eventually calls the MSBuild tasks.
So, for the cleanest solution you should just cut straight to the chase and call the
MSBuild tasks, right? Ah, but here's the rub -- you have to determine what your application
manifest is and feed this list to the <i>GenerateApplicationManifest </i>task via
an <a href="http://msdn2.microsoft.com/en-us/library/ms171453.aspx"><i>ItemGroup</i></a>.
You really don't want to have this fixed list that you have to maintain but rather
have the application manifest dynamically generated for you. <i><b>This is the real
value of mage.exe which you can point to a directory and it will build-up the app
manifest for you.</b></i> Where mage is less than useful is generating the deployment
manifest but you can just use the MSBuild task to do this instead. 
<br />
    <br />
This sample demonstrates how to use mage.exe in conjunction with the ClickOnce MSBuild
tasks to resolve the deficiencies with the Visual Studio approach.  The sample
consists of a simple Windows app which displays a value stored externally in the application's
App.config file.  Note that in this sample there are three versions of this file
(stored under the Config directory) -- a "development" version, a "qa" (i.e. test)
version, and a "production" version.  They are structurally identical, the only
varying bits are the values.  There is also a satellite class library that is
late-bound instantiated and invoked when a button is pressed on the app.  There
is no reference to this assembly from the Windows app.<br /><br />
In my shop we run the deploy scripts seperately from the build scripts but you could
easily tack this on to the end of your build process if so desired.  Have fun!
</p><p><a href="http://blog.gatosoft.com/content/binary/ClickOnceDeployTest.zip"><font face="Arial" size="3">Download
Sample</font></a><br /></p><a href="http://blog.gatosoft.com/content/binary/ClickOnceDeployTest.zip"></a><img width="0" height="0" src="http://blog.gatosoft.com/aggbug.ashx?id=d0a0dd1e-c9ac-4fa9-a408-615454d49702" /></body>
      <title>Taking the ClickPain out of ClickOnce</title>
      <guid isPermaLink="false">http://blog.gatosoft.com/PermaLink,guid,d0a0dd1e-c9ac-4fa9-a408-615454d49702.aspx</guid>
      <link>http://blog.gatosoft.com/2006/04/01/TakingTheClickPainOutOfClickOnce.aspx</link>
      <pubDate>Sat, 01 Apr 2006 08:11:29 GMT</pubDate>
      <description>The &lt;a href="http://msdn2.microsoft.com/en-us/library/t71a733d.aspx"&gt;ClickOnce&lt;/a&gt; support
in Visual Studio 2005 is nice and easy but falls-down in number of areas:&lt;br&gt;
&lt;br&gt;
&lt;ol&gt;
&lt;li&gt;
The application manifest (i.e. the "stuff" that comprises your app) is determined
by walking the project references of your Windows app.&amp;nbsp; What this means is that
if you have deployment artifacts that are non-reference content or late-bound loaded
assemblies then the default ClickOnce mechanism in Visual Studio will &lt;b&gt;not&lt;/b&gt; pick
them up. 
&lt;li&gt;
Oftentimes the versioning scheme for your assemblies is driven by your build process
and ideally you'd want the ClickOnce version number to be in-sync with your assembly
version.&amp;nbsp; The Visual Studio ClickOnce mechanism has a very limited versioning
scheme that is completely decoupled from assembly versioning and is inaccessible outside
of the IDE. 
&lt;li&gt;
For enterpirse scenarios, it is very common to have a segmented network dedicated
for specific functions (e.g. development, test, production).&amp;nbsp; In this scenario
the Windows app has to be designed such that certain information (e.g. connection
strings, web service urls, etc.) are pushed-into environment-specific configuration
files.&amp;nbsp; The deploy process then involves indicating what environment the built
bits should be pushed into and then the appropriate configuration files are pulled-in
by the deploy process.&amp;nbsp; In this way the same set of bits may be "promoted" from
dev to test and finally to production.&amp;nbsp; The default Visual Studio ClickOnce mechanism
has no notion of nor capability of dealing with environment-specific information.&lt;br&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;br&gt;
For the uninitiated there are four ways to create a ClickOnce deploy package:&lt;br&gt;
&amp;nbsp; 
&lt;br&gt;
&lt;ol&gt;
&lt;li&gt;
Via the Window app's Publish property page in Visual Studio (easiest but essentially
unuseable for apps of even moderate complexity for the reasons listed above). 
&lt;li&gt;
Via &lt;a href="http://msdn2.microsoft.com/en-us/library/xc3tc5xx.aspx"&gt;mage.exe&lt;/a&gt; (command-line
utility). 
&lt;li&gt;
Via &lt;a href="http://msdn2.microsoft.com/en-us/library/xc3tc5xx.aspx"&gt;mageui.exe&lt;/a&gt; (Windows
app). 
&lt;li&gt;
Via MSBuild (using the &lt;a href="http://msdn2.microsoft.com/en-us/library/6wc2ccdc.aspx"&gt;&lt;i&gt;GenerateApplicationManifest&lt;/i&gt;&lt;/a&gt;, &lt;a href="http://msdn2.microsoft.com/en-us/library/3k2t34e7%28VS.80%29.aspx"&gt;&lt;i&gt;GenerateDeploymentManifest&lt;/i&gt;&lt;/a&gt;, &lt;i&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/ms164294%28VS.80%29.aspx"&gt;GenerateBootstrapper&lt;/a&gt; &lt;/i&gt;and &lt;a href="http://msdn2.microsoft.com/en-us/library/ms164304%28VS.80%29.aspx"&gt;&lt;i&gt;SignFile&lt;/i&gt;&lt;/a&gt; tasks).&lt;br&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&lt;br&gt;
Note that despite the chosen method, everything eventually calls the MSBuild tasks.
So, for the cleanest solution you should just cut straight to the chase and call the
MSBuild tasks, right? Ah, but here's the rub -- you have to determine what your application
manifest is and feed this list to the &lt;i&gt;GenerateApplicationManifest &lt;/i&gt;task via
an &lt;a href="http://msdn2.microsoft.com/en-us/library/ms171453.aspx"&gt;&lt;i&gt;ItemGroup&lt;/i&gt;&lt;/a&gt;.
You really don't want to have this fixed list that you have to maintain but rather
have the application manifest dynamically generated for you. &lt;i&gt;&lt;b&gt;This is the real
value of mage.exe which you can point to a directory and it will build-up the app
manifest for you.&lt;/b&gt;&lt;/i&gt; Where mage is less than useful is generating the deployment
manifest but you can just use the MSBuild task to do this instead. 
&lt;br&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;
This sample demonstrates how to use mage.exe in conjunction with the ClickOnce MSBuild
tasks to resolve the deficiencies with the Visual Studio approach.&amp;nbsp; The sample
consists of a simple Windows app which displays a value stored externally in the application's
App.config file.&amp;nbsp; Note that in this sample there are three versions of this file
(stored under the Config directory) -- a "development" version, a "qa" (i.e. test)
version, and a "production" version.&amp;nbsp; They are structurally identical, the only
varying bits are the values.&amp;nbsp; There is also a satellite class library that is
late-bound instantiated and invoked when a button is pressed on the app.&amp;nbsp; There
is no reference to this assembly from the Windows app.&lt;br&gt;
&lt;br&gt;
In my shop we run the deploy scripts seperately from the build scripts but you could
easily tack this on to the end of your build process if so desired.&amp;nbsp; Have fun!
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.gatosoft.com/content/binary/ClickOnceDeployTest.zip"&gt;&lt;font face=Arial size=3&gt;Download
Sample&lt;/font&gt;&lt;/a&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;a href="http://blog.gatosoft.com/content/binary/ClickOnceDeployTest.zip"&gt;&lt;/a&gt;&lt;img width="0" height="0" src="http://blog.gatosoft.com/aggbug.ashx?id=d0a0dd1e-c9ac-4fa9-a408-615454d49702" /&gt;</description>
      <comments>http://blog.gatosoft.com/CommentView,guid,d0a0dd1e-c9ac-4fa9-a408-615454d49702.aspx</comments>
      <category>ClickOnce</category>
      <category>Code</category>
    </item>
  </channel>
</rss>