<?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:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Vlad Hrybok's Tech Notes - Sofware Development</title>
    <link>http://vladsnotes.hrybok.com/</link>
    <description>The future of Internet is &lt;a href='http://httpvpn.com'&gt;HttpVPN&lt;/a&gt;...</description>
    <language>en-us</language>
    <copyright>Vlad Hrybok</copyright>
    <lastBuildDate>Sun, 25 Jul 2010 20:23:48 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 1.9.6264.0</generator>
    <managingEditor>vgribok@dodgeit.com</managingEditor>
    <webMaster>vgribok@dodgeit.com</webMaster>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=13fb0c97-9045-40f5-a28f-f7723ef6ebd3</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,13fb0c97-9045-40f5-a28f-f7723ef6ebd3.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,13fb0c97-9045-40f5-a28f-f7723ef6ebd3.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=13fb0c97-9045-40f5-a28f-f7723ef6ebd3</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It appears that a client proxy instance for and out-of-process ServicedComponent expects
the client to have a compile-time reference to the ServicedComponent assembly,
unless ServicedComponent is either of different CLR version or has different bitness
(either client or server is x64 while another one is x86). This creates a bizarre
problem: if the client has no design-time reference to the ServicedComponent, Activator.CreateInstance(compoentClsID)
fails if the component is of the same bitness and CLR version with a cryptic "Cannot
load type" RemotingException, while working perfectly fine when ServicedComponent
is of different bitness or compiled targeting different .NET Framework version.
Google offered no insight, so I started thinking of why matching CLR and bitness would
lead to failure. I started suspecting that when client and server have mismatched
CLR/bitness attributes, runtime must be doing cross-process marshalling in somewhat
different manner than when attributes match. Now what I needed is to ensure that same
"deep proxying" is taking place when client and server have matching CLR/bitness.
On the hunch I decided to use overloaded <strong><font color="#2b91af" size="2" face="Consolas"><font color="#2b91af" size="2" face="Consolas"><font color="#2b91af" size="2" face="Consolas">Type</font></font></font><font size="2" face="Consolas"><font color="#000000" size="2" face="Consolas">.GetTypeFromCLSID(clsID, </font></font><font color="#a31515" size="2" face="Consolas"><font color="#a31515" size="2" face="Consolas"><font color="#a31515" size="2" face="Consolas">"localhost"</font></font></font></strong><font size="2" face="Consolas"><font size="2" face="Consolas"><font color="#000000"><strong>)</strong></font></font></font>,
and lo and behold, it worked! Now I have a client that at design time is only aware
of ServicedComponent's interface, but does not hold a direct reference to it, and
yet it is able to talk to multiple out-of-process ServicedComponent implementing same
interface while having different CLR and bitness attributes. At the end of the day
it turned out to be possible to instantiate ServicedComponent while knowing neither
its CLSID at the design time nor having a hard reference to the assembly implementing
ServicedComponent.
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=13fb0c97-9045-40f5-a28f-f7723ef6ebd3" />
      </body>
      <title>Instantiating Proxy for Out-of-Process ServicedComponent/Managed COM+ Component</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,13fb0c97-9045-40f5-a28f-f7723ef6ebd3.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,13fb0c97-9045-40f5-a28f-f7723ef6ebd3.aspx</link>
      <pubDate>Sun, 25 Jul 2010 20:23:48 GMT</pubDate>
      <description>&lt;p&gt;
It appears that a client proxy instance for and out-of-process ServicedComponent expects
the client to have a compile-time&amp;nbsp;reference to the ServicedComponent assembly,
unless ServicedComponent is either of different CLR version or has different bitness
(either client or server is x64 while another one is x86). This creates a bizarre
problem: if the client has no design-time reference to the ServicedComponent, Activator.CreateInstance(compoentClsID)
fails if the component is of the same bitness and CLR version with a cryptic "Cannot
load type" RemotingException, while working perfectly fine when ServicedComponent
is of different bitness or compiled&amp;nbsp;targeting different&amp;nbsp;.NET Framework&amp;nbsp;version.
Google offered no insight, so I started thinking of why matching CLR and bitness would
lead to failure. I started&amp;nbsp;suspecting that when client and server have mismatched
CLR/bitness&amp;nbsp;attributes, runtime must be doing cross-process marshalling in somewhat
different manner than when attributes match. Now what I needed is to ensure that same
"deep proxying" is taking place&amp;nbsp;when client and server have matching CLR/bitness.
On the hunch I decided to use overloaded &lt;strong&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;Type&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font color=#000000 size=2 face=Consolas&gt;.GetTypeFromCLSID(clsID, &lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515 size=2 face=Consolas&gt;&lt;font color=#a31515 size=2 face=Consolas&gt;&lt;font color=#a31515 size=2 face=Consolas&gt;"localhost"&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/strong&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt;&lt;font color=#000000&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;,
and lo and behold, it worked! Now I have a client that at design time is only aware
of ServicedComponent's interface, but does not hold a direct reference to it, and
yet it is able to talk to multiple out-of-process ServicedComponent implementing same
interface while having different CLR and bitness attributes. At the end of the day
it turned out to be possible to instantiate ServicedComponent while knowing neither
its CLSID at the design time nor having a hard reference to the assembly implementing
ServicedComponent.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=13fb0c97-9045-40f5-a28f-f7723ef6ebd3" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,13fb0c97-9045-40f5-a28f-f7723ef6ebd3.aspx</comments>
      <category>.NET Programming;Sofware Development;x64</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=fdfab71a-a92a-4a4f-823d-23bc1025aeeb</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,fdfab71a-a92a-4a4f-823d-23bc1025aeeb.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,fdfab71a-a92a-4a4f-823d-23bc1025aeeb.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=fdfab71a-a92a-4a4f-823d-23bc1025aeeb</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I thought I knew ASP.NET. I started ASP.NET programming in 2001, and I started it
with customer/server control development and was cranking them out with no problem.
So theoretically I should not have struggled for six hours with a CompositeControl
not being able to save nested controls' state between postbacks. 
</p>
        <p>
All it came down to is calling EnsureChildControls() from the OnInit().
</p>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">
            <p>
[
</p>
          </font>
        </font>
        <font color="#2b91af" size="2" face="Consolas">
          <font color="#2b91af" size="2" face="Consolas">
            <font color="#2b91af" size="2" face="Consolas">ToolboxData</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">(</font>
        </font>
        <font color="#a31515" size="2" face="Consolas">
          <font color="#a31515" size="2" face="Consolas">
            <font color="#a31515" size="2" face="Consolas">"&lt;{0}:BogusCustomControl
runat=server&gt;&lt;/{0}:BogusCustomControl&gt;"</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">)]<br /></font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">public</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">
          </font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">class</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">
          </font>
        </font>
        <font color="#2b91af" size="2" face="Consolas">
          <font color="#2b91af" size="2" face="Consolas">
            <font color="#2b91af" size="2" face="Consolas">BogusCustomControl</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas"> : </font>
        </font>
        <font color="#2b91af" size="2" face="Consolas">
          <font color="#2b91af" size="2" face="Consolas">
            <font color="#2b91af" size="2" face="Consolas">CompositeControl<br /></font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">{<br />
    </font>
        </font>
        <font color="#2b91af" size="2" face="Consolas">
          <font color="#2b91af" size="2" face="Consolas">
            <font color="#2b91af" size="2" face="Consolas">Button</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas"> btn
= </font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">new</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">
          </font>
        </font>
        <font color="#2b91af" size="2" face="Consolas">
          <font color="#2b91af" size="2" face="Consolas">
            <font color="#2b91af" size="2" face="Consolas">Button</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">();
<p></p></font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">
              <font color="#003300">    </font>protected</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">
          </font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">override</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">
          </font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">void</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas"> OnInit(</font>
        </font>
        <font color="#2b91af" size="2" face="Consolas">
          <font color="#2b91af" size="2" face="Consolas">
            <font color="#2b91af" size="2" face="Consolas">EventArgs</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas"> e)<br />
    {<br />
        </font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">base</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">.OnInit(e);
<p></p></font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">
              <font color="#003300">        </font>
              <span style="BACKGROUND-COLOR: yellow">
                <strong>this</strong>
              </span>
            </font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">
            <strong>.EnsureChildControls();</strong>
            <font color="#008000" size="2" face="Consolas">
              <font color="#008000" size="2" face="Consolas">
                <font color="#008000" size="2" face="Consolas">//
&lt;&lt; This is it! This makes ViewState work for a CompositeControl</font>
              </font>
            </font>
            <br />
    }
<p></p></font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">
              <font color="#003300">    </font>protected</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">
          </font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">override</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">
          </font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">void</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas"> OnLoad(</font>
        </font>
        <font color="#2b91af" size="2" face="Consolas">
          <font color="#2b91af" size="2" face="Consolas">
            <font color="#2b91af" size="2" face="Consolas">EventArgs</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas"> e)<br />
    {<br /></font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">
              <font color="#003300">        </font>if</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas"> (!</font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">this</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">.Page.IsPostBack)<br />
        {<br /><font color="#008000" size="2" face="Consolas"><font color="#008000" size="2" face="Consolas"><font color="#008000" size="2" face="Consolas">           
// Set value once to test whether it's preserved between postbacks</font></font></font><br />
            </font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">this</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">.btn.Text
= </font>
        </font>
        <font color="#2b91af" size="2" face="Consolas">
          <font color="#2b91af" size="2" face="Consolas">
            <font color="#2b91af" size="2" face="Consolas">DateTime</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">.Now.ToLongTimeString();<br />
        }
<p></p></font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">
              <font color="#003300">        </font>base</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">.OnLoad(e);<br />
    }
<p></p></font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">
              <font color="#003300">    </font>protected</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">
          </font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">override</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">
          </font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">void</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas"> CreateChildControls()<br />
    {<br />
        </font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">this</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">.btn.ID
= </font>
        </font>
        <font color="#a31515" size="2" face="Consolas">
          <font color="#a31515" size="2" face="Consolas">
            <font color="#a31515" size="2" face="Consolas">"whatever"</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">;<br />
        </font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">this</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">.Controls.Add(</font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">this</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">.btn);
<p></p></font>
        </font>
        <font color="#0000ff" size="2" face="Consolas">
          <font color="#0000ff" size="2" face="Consolas">
            <font color="#0000ff" size="2" face="Consolas">
              <font color="#003300">        </font>base</font>
          </font>
        </font>
        <font size="2" face="Consolas">
          <font size="2" face="Consolas">.CreateChildControls();<br />
    }<br />
}
</font>
        </font>
        <p>
 
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=fdfab71a-a92a-4a4f-823d-23bc1025aeeb" />
      </body>
      <title>Preserving ViewState in ASP.NET CompositeControl</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,fdfab71a-a92a-4a4f-823d-23bc1025aeeb.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,fdfab71a-a92a-4a4f-823d-23bc1025aeeb.aspx</link>
      <pubDate>Fri, 16 Jul 2010 15:33:00 GMT</pubDate>
      <description>&lt;p&gt;
I thought I knew ASP.NET. I started ASP.NET programming in 2001, and I started it
with customer/server control development and was cranking them out with no problem.
So&amp;nbsp;theoretically I should not have struggled for six hours with a CompositeControl
not being able to save nested controls' state&amp;nbsp;between postbacks. 
&lt;/p&gt;
&lt;p&gt;
All it came down to is calling EnsureChildControls() from the OnInit().
&lt;/p&gt;
&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt; 
&lt;p&gt;
[
&lt;/font&gt;&lt;/font&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;ToolboxData&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt;(&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515 size=2 face=Consolas&gt;&lt;font color=#a31515 size=2 face=Consolas&gt;&lt;font color=#a31515 size=2 face=Consolas&gt;"&amp;lt;{0}:BogusCustomControl
runat=server&amp;gt;&amp;lt;/{0}:BogusCustomControl&amp;gt;"&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt;)]&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt; &lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;class&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt; &lt;/font&gt;&lt;/font&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;BogusCustomControl&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt; : &lt;/font&gt;&lt;/font&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;CompositeControl&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/font&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;Button&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt; btn
= &lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;new&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt; &lt;/font&gt;&lt;/font&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;Button&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt;();&gt;
&lt;p&gt;
&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#003300&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;protected&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt; &lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;override&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt; &lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;void&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt; OnInit(&lt;/font&gt;&lt;/font&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;EventArgs&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt; e)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;base&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt;.OnInit(e);&gt;
&lt;p&gt;
&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#003300&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="BACKGROUND-COLOR: yellow"&gt;&lt;strong&gt;this&lt;/strong&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt;&lt;strong&gt;.EnsureChildControls()&gt;;&lt;/strong&gt; &lt;font color=#008000 size=2 face=Consolas&gt;&lt;font color=#008000 size=2 face=Consolas&gt;&lt;font color=#008000 size=2 face=Consolas&gt;//
&amp;lt;&amp;lt; This is it! This makes ViewState work for a CompositeControl&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&gt;
&lt;p&gt;
&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#003300&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;protected&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt; &lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;override&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt; &lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;void&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt; OnLoad(&lt;/font&gt;&lt;/font&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;EventArgs&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt; e)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#003300&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;if&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt; (!&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;this&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt;.Page.IsPostBack)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&lt;font color=#008000 size=2 face=Consolas&gt;&lt;font color=#008000 size=2 face=Consolas&gt;&lt;font color=#008000 size=2 face=Consolas&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
// Set value once to test whether it's preserved between postbacks&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;this&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt;.btn.Text
= &lt;/font&gt;&lt;/font&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;&lt;font color=#2b91af size=2 face=Consolas&gt;DateTime&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt;.Now.ToLongTimeString();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&gt;
&lt;p&gt;
&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#003300&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;base&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt;.OnLoad(e);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&gt;
&lt;p&gt;
&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#003300&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;protected&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt; &lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;override&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt; &lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;void&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt; CreateChildControls()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;this&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt;.btn.ID
= &lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515 size=2 face=Consolas&gt;&lt;font color=#a31515 size=2 face=Consolas&gt;&lt;font color=#a31515 size=2 face=Consolas&gt;"whatever"&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;this&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt;.Controls.Add(&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;this&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt;.btn);&gt;
&lt;p&gt;
&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#0000ff size=2 face=Consolas&gt;&lt;font color=#003300&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;base&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2 face=Consolas&gt;&lt;font size=2 face=Consolas&gt;.CreateChildControls();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
}&gt;
&lt;/font&gt;&lt;/font&gt; 
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=fdfab71a-a92a-4a4f-823d-23bc1025aeeb" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,fdfab71a-a92a-4a4f-823d-23bc1025aeeb.aspx</comments>
      <category>.NET Programming;ASP.NET;Sofware Development</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=10c17b62-dc64-45d1-a175-50482baaa9b2</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,10c17b62-dc64-45d1-a175-50482baaa9b2.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,10c17b62-dc64-45d1-a175-50482baaa9b2.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=10c17b62-dc64-45d1-a175-50482baaa9b2</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Whenever I setup a new Windows PC, I always forget which virutal CD/DVD software I
use. So this is a note to myself: it's <a href="http://www.magiciso.com/tutorials/miso-magicdisc-overview.htm">MagicISO</a>.
It allows to mount an ISO image right after the software is installed, without requiring
a reboot, and it works with both x64 and 32-bit version of Windows, including Vista
and Win 7. Great tool!
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=10c17b62-dc64-45d1-a175-50482baaa9b2" />
      </body>
      <title>MagicISO (MagicDIsk) is a Superb Free Virtual CD/DVD Drive Emulator</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,10c17b62-dc64-45d1-a175-50482baaa9b2.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,10c17b62-dc64-45d1-a175-50482baaa9b2.aspx</link>
      <pubDate>Mon, 17 Aug 2009 15:42:59 GMT</pubDate>
      <description>&lt;p&gt;
Whenever I setup a new Windows PC, I always forget which virutal CD/DVD software I
use. So this is a note to myself: it's &lt;a href="http://www.magiciso.com/tutorials/miso-magicdisc-overview.htm"&gt;MagicISO&lt;/a&gt;.
It allows to mount an ISO image right after the software is installed, without requiring
a reboot, and it works with both x64 and 32-bit version of Windows, including Vista
and Win 7. Great tool!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=10c17b62-dc64-45d1-a175-50482baaa9b2" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,10c17b62-dc64-45d1-a175-50482baaa9b2.aspx</comments>
      <category>Sofware Development;Vista;Windows 7</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=16dae195-a52d-4977-9e57-5d8242c1569d</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,16dae195-a52d-4977-9e57-5d8242c1569d.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,16dae195-a52d-4977-9e57-5d8242c1569d.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=16dae195-a52d-4977-9e57-5d8242c1569d</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
HttpVPN™, a redistributable component for hosting web applications targeting home
users and small businesses, is <a href="http://ultidev.com/products/httpvpn/">released</a> as
Beta. It makes web applications accessible on the web at <a href="https://MyOwnSecureWeb.com">MyOwnSecureWeb.com</a> right
after the installation and does not require users to fiddle with routers, set up DMZ,
etc. Just a consumer-friendly, secure self-hosting of web apps.
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=16dae195-a52d-4977-9e57-5d8242c1569d" />
      </body>
      <title>HttpVPN is Released - First Public Beta is Launched</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,16dae195-a52d-4977-9e57-5d8242c1569d.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,16dae195-a52d-4977-9e57-5d8242c1569d.aspx</link>
      <pubDate>Fri, 31 Jul 2009 04:35:58 GMT</pubDate>
      <description>&lt;p&gt;
HttpVPN™, a redistributable component for hosting web applications targeting home
users and small businesses, is &lt;a href="http://ultidev.com/products/httpvpn/"&gt;released&lt;/a&gt;&amp;nbsp;as
Beta. It makes web applications accessible on the web at &lt;a href="https://MyOwnSecureWeb.com"&gt;MyOwnSecureWeb.com&lt;/a&gt; right
after the installation and does not require users to fiddle with routers, set up DMZ,
etc. Just a consumer-friendly, secure self-hosting of web apps.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=16dae195-a52d-4977-9e57-5d8242c1569d" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,16dae195-a52d-4977-9e57-5d8242c1569d.aspx</comments>
      <category>ASP.NET;Digital Home;HttpVPN;Sofware Development</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=868a8d58-6ea6-4285-9fe7-2f30c9e8bca6</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,868a8d58-6ea6-4285-9fe7-2f30c9e8bca6.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,868a8d58-6ea6-4285-9fe7-2f30c9e8bca6.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=868a8d58-6ea6-4285-9fe7-2f30c9e8bca6</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In general, I love Microsoft development tools. The reason I never felt compelled
to venture far into either Java or LAMP world is because combination of the Visual
Studio, .NET Framework runtime, SQL Server and other MS tools has always been
an extremely strong development platform, both for the value delivery for
end users, and for something as prosaic as having fun programming 8 hours day in and day
out. Therefore, it's borderline pathological that Microsoft HTML editing tools
have not evolved beyond "D-" grade since their first tool I tried over a decade ago,
Front Page 98. Consider this, I am taking a short break (to vent my dissatisfaction) from
writing content for a web site because when I edit an HTML file using Visual Studio
2008 SP1, it mangles the HTML by cutting up closing tags, turning "&lt;/a&gt;", "&lt;/h3&gt;", "&lt;/span&gt;" and
others into "&gt;". I thought, alright, Expression Web 2 is going to save
the day. I open the page in the Expression Web, and what I found is that it doesn't
handle keyboard key strokes well, ranging from failing to respond to arrow keys,
to Ctrl+V shortcut for Paste simply not working, rendering Expression Web
unusable. I use Microsoft keyboard and their drivers. I am a developer, not a designer,
but if getting such basic functions as arrow keys in their editor is impossible for
MS, what chances do they have with professional designers? And don't get me even started
with Expression suite not supporting MS own source controls for two versions. Microsoft's
inability to get HTML design tools right for such a long time creates a fear that
MS is losing it.
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=868a8d58-6ea6-4285-9fe7-2f30c9e8bca6" />
      </body>
      <title>Microsoft Visual Studio 2008 and Expression Web 2 are Still Horrible at HTML Editing</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,868a8d58-6ea6-4285-9fe7-2f30c9e8bca6.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,868a8d58-6ea6-4285-9fe7-2f30c9e8bca6.aspx</link>
      <pubDate>Sun, 28 Jun 2009 21:04:41 GMT</pubDate>
      <description>&lt;p&gt;
In general, I love Microsoft development tools. The&amp;nbsp;reason I never felt compelled
to&amp;nbsp;venture far into either Java or LAMP world is because combination of the Visual
Studio, .NET Framework&amp;nbsp;runtime, SQL Server&amp;nbsp;and other MS tools&amp;nbsp;has always&amp;nbsp;been
an extremely&amp;nbsp;strong development platform, both for the&amp;nbsp;value delivery for
end users, and for something as prosaic as having fun programming 8 hours day in and&amp;nbsp;day
out. Therefore,&amp;nbsp;it's borderline pathological that Microsoft HTML editing tools
have not evolved beyond "D-" grade since their first tool I tried over a decade ago,
Front Page 98. Consider this, I am taking a short break (to vent my dissatisfaction)&amp;nbsp;from
writing content for a web site because when I edit an HTML file using Visual Studio
2008 SP1, it mangles the HTML by cutting up closing tags, turning "&amp;lt;/a&amp;gt;", "&amp;lt;/h3&amp;gt;",&amp;nbsp;"&amp;lt;/span&amp;gt;"&amp;nbsp;and
others&amp;nbsp;into "&amp;gt;". I thought, alright, Expression&amp;nbsp;Web 2 is going to save
the day. I open the page in the Expression Web, and what I found is that it doesn't
handle keyboard key strokes well, ranging&amp;nbsp;from failing to respond to arrow keys,
to&amp;nbsp;Ctrl+V shortcut for Paste simply&amp;nbsp;not working, rendering Expression Web
unusable. I use Microsoft keyboard and their drivers. I am a developer, not a designer,
but if getting such basic functions as arrow keys in their editor is impossible for
MS, what chances do they have with professional designers? And don't get me even started
with Expression suite not supporting MS own source controls for two versions.&amp;nbsp;Microsoft's
inability to get HTML design tools right for such a long time creates a fear that
MS is losing it.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=868a8d58-6ea6-4285-9fe7-2f30c9e8bca6" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,868a8d58-6ea6-4285-9fe7-2f30c9e8bca6.aspx</comments>
      <category>ASP.NET;Rants;Sofware Development;Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=012170b9-7a6c-4d43-8169-e2e062f18274</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,012170b9-7a6c-4d43-8169-e2e062f18274.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,012170b9-7a6c-4d43-8169-e2e062f18274.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=012170b9-7a6c-4d43-8169-e2e062f18274</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
After spending a day and a half on migrating Visual Source Safe (VSS) to Microsoft
Team Foundation Server (TFS) source control, I want to share a few points that may
save somebody a little bit of time.
</p>
        <p>
Migration process consists of two phases: a) migrating data from VSS to TFS, and b)
switching Visual Studio projects' source control bindings from VSS to TFS. 
</p>
        <p>
Data migration is done more or less the way Microsoft describes it: <a href="http://msdn.microsoft.com/en-us/library/ms181246.aspx">analyze</a>, <a href="http://msdn.microsoft.com/en-us/library/ms253175.aspx">map
users</a>, and finally, <a href="http://msdn.microsoft.com/en-us/library/ms181247.aspx">migrate
data</a>. This part of the process didn't go as smooth as it could because my VSS
data lived on a machine that is not a member of the domain, while TFS database
lives on a domain computer. Unfortunately I wasted a lot of time before I found
that out: after all, "analyze" step worked leading me to believe that
migration itself will be possible, but in the end security problems didn't allow data
migration. So here's the time saver hint #1: <strong>copy your VSS data </strong>(a
folder with the srcsafe.ini file) <strong>to the domain computer where migration
process will take place</strong>. Also, please keep in mind that the machine
where you will run migration utility should:<br />
- Have SQL Server or SQL Server Express installed;<br />
- Have Visual Source Safe 2005 installed;<br />
- Have Visual Studio 2008 installed. This one is important. MS says it's enough to
have only Team Explorer for the migration process, but that's not quite correct: Team
Explorer package of the VS does not contain "Visual Studio 2008 Command Prompt" BAT
file necessary for the process. It's possible to work around it and create your
own BAT file that sets all the paths properly, but it will take time. Running
migration on the machine with the real Visual Studio is a time saver tip #2.<br />
Once these requirements are observed, data migration problems are limited to
the tedium of mapping VSS folders to TFS folders - if you want to consolidate and
re-organize projects while moving them to TFS. If your VSS structure was OK as is,
then you can simply move VSS to TFS structure without changing it.
</p>
        <p>
Switching Visual Studio projects' source control bindings is no less a time sucker
than data migration. This part should be done at one of the developers' machines, with
Visual Studio 2008 with Team Explorer installed and projects that are being switched
over from VSS to TFS already present as local files. <br />
Here's a high-level sequence of steps required for changing source control bindings:<br />
- Open a solution bound to the VSS in the Visual Studio.<br />
- Select the solution in the Solution Explorer, and then do File | Source Control
| Change Source Control, then select all items in the list and hit Unbind button.<br />
- Select Tools | Options | Source Control and then select Team Foundation Server from
the list. Hit OK to close the dialog.<br />
- Use Team Explorer to open TFS source control window, and there use Workspaces drop-down
list to select "Workspaces..." item and update mappings of your local file folders
to TFS folders for this machine's workspace.<br />
- Once done adjusting TFS to local folders mappings, select solution in the Solution
Explorer and do File | Source Control | Change Source Control again. Now select all
items in the dialog and hit Bind button. If all projects got "Valid" status next
to them, it means your TFS-to-local-folders mappings are done correctly. If some project
bindings are Invalid, find where these project folders are located on your file system
and map them to corresponding TFS folders (see previous step) in your workspace. After
that try to re-bind your projects to TFS source control again. Once you got all your
projects in the Valid state, click OK to close the window, and at this point you are
likely to get a nagging message from VS telling that you need to get latest version
from TFS. Accept defaults.<br />
- Get latest version for the solution. Project files are likely to need manual conflict
resolution. I don't know why it's considered to be a conflict when it's just a change
to the project files reflecting new source control bindings. Choose default type
of resolution - Overwrite.<br />
- After this Visual Studio may revert some projects to unbound state - leaving them
off them source control. All you need to do is to, again, bind your projects. This
time binding process offers to do regular Check Out for project files in question.
Accept defaults and in the end you should end up with the solution that has a solution
file and maybe some project files checked out, but otherwise the solution should be
bound to the TFS now.<br />
- Test-build the solution, and if everything is alright, check in modified solution
and project files.<br /><br />
If this list seems convoluted - that's because the process of re-binding from VSS
to TFS itself is incredibly awkward. Imagine making up this list of steps
by trial and error. Hopefully using this list, as much pain as it is, will save you
some time.
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=012170b9-7a6c-4d43-8169-e2e062f18274" />
      </body>
      <title>Migrating Visual Source Safe to TFS Source Control</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,012170b9-7a6c-4d43-8169-e2e062f18274.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,012170b9-7a6c-4d43-8169-e2e062f18274.aspx</link>
      <pubDate>Thu, 07 May 2009 02:40:59 GMT</pubDate>
      <description>&lt;p&gt;
After spending a day and a half on migrating Visual Source Safe (VSS) to Microsoft
Team Foundation Server (TFS) source control, I want to share a few points that may
save somebody a little bit of time.
&lt;/p&gt;
&lt;p&gt;
Migration process consists of two phases: a) migrating data from VSS to TFS, and b)
switching Visual Studio projects' source control bindings from VSS to TFS. 
&lt;/p&gt;
&lt;p&gt;
Data migration is done more or less the way Microsoft describes it: &lt;a href="http://msdn.microsoft.com/en-us/library/ms181246.aspx"&gt;analyze&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/ms253175.aspx"&gt;map
users&lt;/a&gt;, and finally, &lt;a href="http://msdn.microsoft.com/en-us/library/ms181247.aspx"&gt;migrate
data&lt;/a&gt;. This part of the process didn't go as smooth as it could because my VSS
data lived on&amp;nbsp;a machine that is not a member of the domain, while TFS database
lives on a domain computer.&amp;nbsp;Unfortunately I wasted a lot of time before I found
that out:&amp;nbsp;after all,&amp;nbsp;"analyze" step&amp;nbsp;worked leading me to believe that
migration itself will be possible, but in the end security problems didn't allow data
migration. So here's the time saver hint #1: &lt;strong&gt;copy your VSS data &lt;/strong&gt;(a
folder with the srcsafe.ini file)&amp;nbsp;&lt;strong&gt;to the domain computer where migration
process will take place&lt;/strong&gt;. Also, please&amp;nbsp;keep in mind that the machine
where you will run migration utility should:&lt;br&gt;
- Have SQL Server or SQL Server Express installed;&lt;br&gt;
- Have Visual Source Safe 2005 installed;&lt;br&gt;
- Have Visual Studio 2008 installed. This one is important. MS says it's enough to
have only Team Explorer for the migration process, but that's not quite correct: Team
Explorer package of the VS does not contain "Visual Studio 2008 Command Prompt" BAT
file&amp;nbsp;necessary for the process. It's possible to work around it and create your
own BAT file that&amp;nbsp;sets all the paths properly, but it will take time.&amp;nbsp;Running
migration on the machine with the real&amp;nbsp;Visual Studio is a time saver tip #2.&lt;br&gt;
Once these&amp;nbsp;requirements are observed, data migration problems are limited to
the tedium of mapping VSS folders to TFS folders - if you want to consolidate and
re-organize projects while moving them to TFS. If your VSS structure was OK as is,
then you can simply move VSS to TFS structure without changing it.
&lt;/p&gt;
&lt;p&gt;
Switching Visual Studio projects' source control bindings is no less&amp;nbsp;a time sucker
than data migration. This part should be done&amp;nbsp;at one of the developers' machines,&amp;nbsp;with
Visual Studio 2008 with Team Explorer&amp;nbsp;installed and projects that are being switched
over from VSS to TFS already present&amp;nbsp;as local files.&amp;nbsp;&lt;br&gt;
Here's a high-level sequence of steps required for changing source control bindings:&lt;br&gt;
- Open a solution bound to the VSS in the Visual Studio.&lt;br&gt;
- Select the solution in the Solution Explorer, and then do File | Source Control
| Change Source Control, then&amp;nbsp;select all items in the list and hit Unbind button.&lt;br&gt;
- Select Tools | Options | Source Control and then select Team Foundation Server from
the list. Hit OK to close the dialog.&lt;br&gt;
- Use Team Explorer to open TFS source control window, and there use Workspaces drop-down
list to select "Workspaces..." item and update mappings of your local file folders
to TFS folders for this machine's workspace.&lt;br&gt;
- Once done adjusting TFS to local folders mappings, select solution in the Solution
Explorer and do File | Source Control | Change Source Control again. Now select all
items in the dialog and&amp;nbsp;hit Bind button. If all projects got "Valid" status next
to them, it means your TFS-to-local-folders mappings are done correctly. If some project
bindings are Invalid, find where these project folders are located on your file system
and map them to corresponding TFS folders (see previous step) in your workspace. After
that try to re-bind your projects to TFS source control again. Once you got all your
projects in the Valid state, click OK to close the window, and at this point you are
likely to get a nagging message from VS telling that you need to get latest version
from TFS. Accept defaults.&lt;br&gt;
- Get latest version for the solution. Project files are likely to need manual conflict
resolution. I don't know why it's considered to be a conflict when it's just a change
to the project files reflecting new source control bindings.&amp;nbsp;Choose default type
of resolution - Overwrite.&lt;br&gt;
- After this Visual Studio may revert some projects to unbound state - leaving them
off them source control. All you need to do is to, again, bind your projects. This
time binding process offers to do&amp;nbsp;regular Check Out for project files in question.
Accept defaults and in the end you should end up with the solution that has a solution
file and maybe some project files checked out, but otherwise the solution should be
bound to the TFS now.&lt;br&gt;
- Test-build the solution, and if everything is alright, check in modified solution
and project files.&lt;br&gt;
&lt;br&gt;
If this list seems convoluted - that's because the process of re-binding from VSS
to TFS itself is incredibly awkward. Imagine&amp;nbsp;making up&amp;nbsp;this list of steps
by trial and error. Hopefully using this list, as much pain as it is, will save you
some time.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=012170b9-7a6c-4d43-8169-e2e062f18274" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,012170b9-7a6c-4d43-8169-e2e062f18274.aspx</comments>
      <category>.NET Programming;Sofware Development;Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=e8b32d50-e9a9-4925-991c-288a0a95cd23</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,e8b32d50-e9a9-4925-991c-288a0a95cd23.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,e8b32d50-e9a9-4925-991c-288a0a95cd23.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=e8b32d50-e9a9-4925-991c-288a0a95cd23</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It all started with a need to use TimeZoneInfo class of .NET Framework 3.5. My
ASP.NET application, however, was of ASP.NET 2.0, even though I develop it in Visual
Studio 2008. Since moving from ASP.NET 2.0 to 3.5 should be pretty easy, I promptly
switched target .NET Framework to 3.5 in the project settings, recompiled and
ran it without a problem - at first. Suddenly, one page failed with "control with
id 'whatever' requires a ScriptManager on the page", while ScriptManager was already
there - set at the master page level. Googling provided solutions that didn't
work.
</p>
        <p>
What it turned out to be is that my old AjaxControlToolkit version was apparently
incompatible with .NET Framework 3.5. Once I got <a href="http://www.codeplex.com/AjaxControlToolkit">Ajax
Control Toolkit</a> made specifically for ASP.NET 3.5, my pages started working properly.
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=e8b32d50-e9a9-4925-991c-288a0a95cd23" />
      </body>
      <title>Migrating ASP.NET App with AjaxControlToolkit from .NET Framework 2.0 to 3.5</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,e8b32d50-e9a9-4925-991c-288a0a95cd23.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,e8b32d50-e9a9-4925-991c-288a0a95cd23.aspx</link>
      <pubDate>Wed, 11 Mar 2009 22:09:40 GMT</pubDate>
      <description>&lt;p&gt;
It all&amp;nbsp;started with a need to use TimeZoneInfo class of .NET Framework 3.5. My
ASP.NET application, however, was of ASP.NET 2.0, even though I develop it in Visual
Studio 2008. Since moving from ASP.NET 2.0 to 3.5 should be pretty easy, I promptly
switched&amp;nbsp;target .NET Framework to 3.5 in the project settings, recompiled and
ran it without a problem - at first. Suddenly, one page failed with "control with
id 'whatever' requires a ScriptManager on the page", while ScriptManager was already
there&amp;nbsp;- set at the master page level. Googling provided solutions that didn't
work.
&lt;/p&gt;
&lt;p&gt;
What it turned out to be is that my old AjaxControlToolkit version was apparently
incompatible with .NET Framework 3.5. Once I got &lt;a href="http://www.codeplex.com/AjaxControlToolkit"&gt;Ajax
Control Toolkit&lt;/a&gt; made specifically for ASP.NET 3.5, my pages started working properly.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=e8b32d50-e9a9-4925-991c-288a0a95cd23" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,e8b32d50-e9a9-4925-991c-288a0a95cd23.aspx</comments>
      <category>.NET Programming;ASP.NET;Sofware Development</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=16e5572c-dce4-4b09-9af2-35b6c207a4f9</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,16e5572c-dce4-4b09-9af2-35b6c207a4f9.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,16e5572c-dce4-4b09-9af2-35b6c207a4f9.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=16e5572c-dce4-4b09-9af2-35b6c207a4f9</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I had this seemingly simple task yesterday: populate TreeView control (ASP.NET) with
data from SQL Server 2005. The query returning data from SQL Server was spanning
three joined tables with one-to-many relations, returning the denormalized set of
records that has some redundancy due to information from parent tables replicated
in each record (like having Company and Department information in each Employee record).
Populating hierarchical TreeView from flat recordset is pretty
inconvenient, so I decided to give a shot to the XML output feature of SQL
Server 2005.
</p>
        <p>
Converting flat denormalized result set output into hierarchical XML was as easy as
adding "FOR XML AUTO" to the end of my query. I ran the query and the output was exactly
what I wanted - no redundancy at all, with child records neatly nested inside the
parent table XML nodes (for proper record nesting be sure to use correct order of
the selected columns: parent table columns should precede child table columns in the
T-SQL SELECT statement). Now I needed to bring this result back from SQL to the business
tier of my C# application. I extensively use DataSets with the the convenience of
built-in data-access methods created using DataSet Editor's query wizards. I right-clicked
an appropriate table adapter and went through the "Add Query..." wizard, mapping my
new stored procedure returning XML to the new data access method. At the end of the
wizard "Tabular Data" option for the query result type was understandably grayed,
because XML is hierarchical, not tabular. But generated method turned out to return
Object type, and you would never know it unless you looked at the generated source
code - properties of the generated methods do now show the return type of the method.
I test-ran the method and it turned out to return what you would expect - XML
text with all the data. 
</p>
        <p>
One could stop digging right here and simply use XmlDocument and XPath to parse out
and the walk the XML, populating tree nodes in the process, but I wanted to turn
XML data into a strongly-typed hierarchical structure instead of walking XML nodes. In
.NET all you need to turn XML into a strongly-typed structure is XML schema. A nice
little utility called xsd.exe converts XSD schemas into C# or VB.NET classes, which
are XML-serializable. SQL Server 2005 is sweet enough to generate schema, along with
bringing the XML data. I temporarily modified my query to have "FOR XML AUTO, XMLSCHEMA"
appendix, ran it in SQL Server and got the XML preceded by the schema. I copied schema
over to an XSD file and undid the change to the query, reverting the appendix back
to "FOR XML AUTO".
</p>
        <p>
Now, having created XSD schema defining XML structure returned by my query, all I
needed to do is to feed the XSD file to XSD.exe utility to produce C# file with classes
corresponding to m XML nodes, right? Almost. This was the part where things stopped
going smoothly. First, xsd.exe complained, as it always does, that it could not find
sqltypes.xsd schema, which is imported by the schema produced by SQL server. If you
ever used either xsd.exe or wsdl.exe against schemas that import other files, you
probably know that all the imported files need to be <a href="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd">downloaded</a> and
saved locally, and in the case of xsd.exe, all imported schemas should be explicitly
listed in the command line. Here's the example of xsd.exe command line (run Visual
Studio Command Prompt to load command prompt window with all environment variables
set):<br />
   <font face="Courier New">xsd.exe yourschema.xsd sqltypes.xsd /classes
/namespace:WhateverIsYourNamespace</font><br />
This command will produce <font face="Courier New">yourschema</font>_<font face="Courier New">sqltypes</font>.cs
file with strongl-typed C# classes wrapped into the <font face="Courier New">WhateverIsYourNamspace</font> namespace.
If you expect to simply include this file into your project and rejoice at this point,
not so fast. Although the code will compile, at run time using XmlSerializer.Deserialize()
produced odd results - it complained that my root element with xmlns='' attribute was
not expected. That was because schema got the default name when it was generated by
SQL Server, while actual XML data did not reference the schema at all. To fix that
I had to remove <font color="#008000" size="2"><font color="#008000" size="2">XmlTypeAttribute</font></font> and <font color="#008000" size="2"><font color="#008000" size="2">XmlRootAttribute</font></font> attributes
from declarations of the generated classes. I had to keep XmlRoot attribute for the
class representing root node, by its declaration was simplified to look like <font size="2">[System.Xml.Serialization.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">XmlRootAttribute</font></font><font size="2">(IsNullable
= </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">false</font></font><font size="2">)]</font>.
</p>
        <p>
Once that part was done, deserialization of XML into strongly-typed hierarchical
data structure started working just fine. 
</p>
        <p>
One more quick note: when .NET classes are generated from XSD schema, nullable
data fields get done in a slightly different way compared to the DataSet. In the dataset,
you'll get "type&lt;Nullable&gt;" or "type?" declaration for nullable data columns
of value types (int, DateTime, etc). .NET classes generated by xsd.exe won't
have nullable fields. Instead they will have extra boolean fields telling whether
the field is nullable. For example, if your SQL data table has nullable BirthDate,
the C# class produced by xsd.exe will have boolean BirthDateSpecified property, which
does what BirthDate.HasValue would do in the dataset.
</p>
        <p>
The whole process was not terribly smooth, but also not prohibitively burdensome. Of
course, much better design would be if Microsoft allowed to specify XML schema for
the TreeView control, and then to let data-bind the TreeView control to a SQL query
or an object method that returns XML. This way it would be still strongly-typed, but
the whole business of building XML-serializable C# classes out of the schema would
not be necessary. This approach would also allow design-time definition of TreeView
node formatting, just like GridView does it with strongly-typed datasets. Another
useful feature would be automatic generation of C# classes - just like generation
of strongly-typed datasets - for data-access methods returning XML.<br /></p>
        <p>
          <br />
 
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=16e5572c-dce4-4b09-9af2-35b6c207a4f9" />
      </body>
      <title>Manually Binding ASP.NET TreeView to XML Data From SQL Server</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,16e5572c-dce4-4b09-9af2-35b6c207a4f9.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,16e5572c-dce4-4b09-9af2-35b6c207a4f9.aspx</link>
      <pubDate>Sun, 18 Jan 2009 15:57:38 GMT</pubDate>
      <description>&lt;p&gt;
I had this seemingly simple task yesterday: populate TreeView control (ASP.NET) with
data&amp;nbsp;from SQL Server 2005. The query returning data from SQL Server was spanning
three joined tables with one-to-many relations, returning the denormalized set of
records that has some redundancy due to information from parent tables replicated
in each record (like having Company and Department information in each Employee record).
Populating hierarchical&amp;nbsp;TreeView&amp;nbsp;from&amp;nbsp;flat recordset&amp;nbsp;is pretty
inconvenient, so I decided to&amp;nbsp;give a shot to the&amp;nbsp;XML output feature of SQL
Server 2005.
&lt;/p&gt;
&lt;p&gt;
Converting flat denormalized result set output into hierarchical XML was as easy as
adding "FOR XML AUTO" to the end of my query. I ran the query and the output was exactly
what I wanted - no redundancy at all, with child records neatly nested inside the
parent table XML nodes (for proper record nesting be sure to use correct order of
the selected columns: parent table columns should precede child table columns in the
T-SQL SELECT statement). Now I needed to bring this result back from SQL to the business
tier of my C# application. I extensively use DataSets with the the convenience of
built-in data-access methods&amp;nbsp;created using DataSet Editor's query wizards. I&amp;nbsp;right-clicked
an appropriate table adapter and went through the "Add Query..." wizard, mapping my
new stored procedure returning XML to the new data access method. At the end of the
wizard "Tabular Data" option for the query result type was understandably grayed,
because XML is hierarchical, not tabular. But generated method turned out to return
Object type, and you would never know it unless you looked at the generated source
code - properties of the generated methods do now show the return type of the method.
I test-ran the method and it turned out to return what you would expect -&amp;nbsp;XML
text with all the data. 
&lt;/p&gt;
&lt;p&gt;
One could stop digging right here and simply use XmlDocument and XPath to parse out
and the walk the XML, populating tree nodes in the process, but I wanted to&amp;nbsp;turn
XML data into a strongly-typed hierarchical structure instead of walking XML nodes.&amp;nbsp;In
.NET all you need to turn XML into a strongly-typed structure is XML schema. A nice
little utility called xsd.exe converts XSD schemas into C# or VB.NET classes, which
are XML-serializable. SQL Server 2005 is sweet enough to generate schema, along with
bringing the XML data. I temporarily modified my query to have "FOR XML AUTO, XMLSCHEMA"
appendix, ran it in SQL Server and got the XML preceded by the schema. I copied schema
over to an XSD file and undid the change to the query, reverting the appendix back
to "FOR XML AUTO".
&lt;/p&gt;
&lt;p&gt;
Now, having created XSD schema defining XML structure returned by my query, all I
needed to do is to feed the XSD file to XSD.exe utility to produce C# file with classes
corresponding to m XML nodes, right? Almost. This was the part where things stopped
going smoothly. First, xsd.exe complained, as it always does, that it could not find
sqltypes.xsd schema, which is imported by the schema produced by SQL server. If you
ever used either xsd.exe or wsdl.exe against schemas that import other files, you
probably know that all the imported files need to be &lt;a href="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd"&gt;downloaded&lt;/a&gt; and
saved locally, and in the case of xsd.exe, all imported schemas should be explicitly
listed in the command line. Here's the example of xsd.exe command line (run Visual
Studio Command Prompt to load command prompt window with all environment variables
set):&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font face="Courier New"&gt;xsd.exe yourschema.xsd sqltypes.xsd /classes
/namespace:WhateverIsYourNamespace&lt;/font&gt;
&lt;br&gt;
This command will produce &lt;font face="Courier New"&gt;yourschema&lt;/font&gt;_&lt;font face="Courier New"&gt;sqltypes&lt;/font&gt;.cs
file with strongl-typed C# classes wrapped into the &lt;font face="Courier New"&gt;WhateverIsYourNamspace&lt;/font&gt;&amp;nbsp;namespace.
If you expect to simply include this file into your project and rejoice at this point,
not so fast. Although the code will compile, at run time using XmlSerializer.Deserialize()
produced odd results - it complained that my root element with xmlns='' attribute&amp;nbsp;was
not expected. That was because schema got the default name when it was generated by
SQL Server, while actual XML data did not reference the schema at all. To fix that
I had to remove &lt;font color=#008000 size=2&gt;&lt;font color=#008000 size=2&gt;XmlTypeAttribute&lt;/font&gt;&lt;/font&gt;&amp;nbsp;and &lt;font color=#008000 size=2&gt;&lt;font color=#008000 size=2&gt;XmlRootAttribute&lt;/font&gt;&lt;/font&gt;&amp;nbsp;attributes
from declarations of the generated classes. I had to keep XmlRoot attribute for the
class representing root node, by its declaration was simplified to look like &lt;font size=2&gt;[System.Xml.Serialization.&lt;/font&gt;&lt;font color=#2b91af size=2&gt;&lt;font color=#2b91af size=2&gt;XmlRootAttribute&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;(IsNullable
= &lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;false&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;)]&lt;/font&gt;.
&lt;/p&gt;
&lt;p&gt;
Once that part was done,&amp;nbsp;deserialization of XML into strongly-typed hierarchical
data structure&amp;nbsp;started working just fine. 
&lt;/p&gt;
&lt;p&gt;
One more quick note: when&amp;nbsp;.NET classes are generated from XSD schema, nullable
data fields get done in a slightly different way compared to the DataSet. In the dataset,
you'll get "type&amp;lt;Nullable&amp;gt;" or "type?" declaration for nullable data columns
of value types (int, DateTime, etc).&amp;nbsp;.NET classes generated by xsd.exe&amp;nbsp;won't
have nullable fields. Instead they will have extra boolean fields telling whether
the field is nullable. For example, if your SQL data table&amp;nbsp;has nullable&amp;nbsp;BirthDate,
the C# class produced by xsd.exe will have boolean BirthDateSpecified property, which
does what BirthDate.HasValue would do in the dataset.
&lt;/p&gt;
&lt;p&gt;
The whole process was not terribly smooth, but also not prohibitively burdensome.&amp;nbsp;Of
course, much better design would be if Microsoft allowed to specify XML schema&amp;nbsp;for
the TreeView control, and then to let data-bind the TreeView control to a SQL query
or an object method that returns XML. This way it would be still strongly-typed, but
the whole business of building XML-serializable C# classes out of the schema would
not be necessary. This approach would also allow design-time definition of TreeView
node formatting, just like GridView does it with strongly-typed datasets. Another
useful feature would be automatic generation of&amp;nbsp;C# classes - just like generation
of strongly-typed datasets - for data-access methods returning XML.&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=16e5572c-dce4-4b09-9af2-35b6c207a4f9" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,16e5572c-dce4-4b09-9af2-35b6c207a4f9.aspx</comments>
      <category>.NET Programming;ASP.NET;Sofware Development</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=f5da1c61-cccf-458e-9b23-06960bfef242</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,f5da1c61-cccf-458e-9b23-06960bfef242.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,f5da1c61-cccf-458e-9b23-06960bfef242.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=f5da1c61-cccf-458e-9b23-06960bfef242</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Updated on 7/25/2009.
</p>
        <p>
Visual Studio setup project <a href="PermaLink,guid,33e12a70-d0f9-4a79-9e97-ffbcd60f9d53.aspx">produced
MSI packages with problems</a> for a while now. It looks like with introduction
of Visual Studio 2008, setup project added a couple of new twists, compared to VS'05: 
<br />
1. Order in which custom actions are called has changed. 
<br />
2. When installation is an upgrade, old binary files (EXE and DLL) will only
be replaced by new ones if new binaries have higher file version.
</p>
        <p>
Here's what used to happen. MSIs produced by VS 2005 had the intuitive order:<br />
- Uninstall step from the old installer version.<br />
- Install and Commit steps from the new installer version.
</p>
        <p>
In other words, installing an MSI created by VS 2005 was a <a href="PermaLink,guid,33e12a70-d0f9-4a79-9e97-ffbcd60f9d53.aspx">very
rough</a> equivalent of uninstalling the old version, followed by installing
the new one. VS 2008 order has become a bit more complex, arguably smarter, but also
less intuitive. 
</p>
        <p>
MSIs produced by VS 2008 seem to have this new order:<br />
- Install step from new installer version.<br />
- Commit step from the new installer version.<br />
Note that <strong>Uninstall step of old version installation is not
called at all during an upgrade-installation of an MSI generated by VS'08</strong> (with
RemoveOldVersion set to True). Funny, but even though Uninstall steps does not seem
to be invoked, the custom action assembly of previous version is still getting
loaded, which may lead to installation crash if old version uses .NET Framework
1.x. Custom action order change is the biggest departure from VS'05 MSIs. Also,
only files that have been changed in the new version of the installed package, will
be replaced in the upgrade mode, while unchanged files will remain.
</p>
        <p>
Also, <strong>upgrade flow</strong> of the MSIs generated by Visual Studio 2008 also
replaces binary files only if their FileVersion property has changed. Since this was
not a requirement in Visual Studio 2005, you may want to go through your AssemblyInfo.cs
files and ensure that they either have the wildcard in their version name (<font size="2">[</font><font color="#0000ff" size="2"><font color="#0000ff" size="2">assembly</font></font><font size="2">: </font><font color="#2b91af" size="2"><font color="#2b91af" size="2">AssemblyVersion</font></font><font size="2">(</font><font color="#a31515" size="2"><font color="#a31515" size="2">"1.0.*"</font></font><font size="2">)]</font>),
or you manually increment version before releasing a new build. If AssemblyVersion
and FileVersion are in sync, you can remove FileVersion attribute from the AssemblyInfo.cs.
</p>
        <p>
You are most likely going to experience the effect of these changes after
porting your Visual Studio 2005 windows service installer project to Visual Studio
2008, and getting the "Error 1001. The specified service already exists." error. Explaining
this all would make this rather a long story, but the gist of it is this: ServiceInstaller's
Install() method attempts to register the service even if service is already registered,
which is the case in the upgrade service installation (remember, Uninstall step, which
unregisters a service is not called anymore). ServiceInstaller's Install() throws the
above-mentioned exception if service is already registered. 
</p>
        <p>
To successfully upgrade a Windows Service, it needs to be stopped before files can
be replaced. If service was not stopped and files are replaced - target system is
likely to be required to reboot at the end of the installation process. Stopping service during
upgrade installation from Install custom action will be too late - at this point files
are already replaced and reboot is imminent. You see what happens here: it appears
that upgrade installation of a windows service created in Visual Studio 2008 will
*always* lead to rebooting the target machine. Given the fact that windows
services are very often created for server applications deployed on high-availability
machines, it's seems that windows service installation done by the book in Visual
Studio 2008 is all but useless.
</p>
        <p>
Here are <strong>two solutions</strong>. 
</p>
        <h4>Solution #1 (for Windows Service Installers): Make your MSI act the old (VS'05) way
</h4>
        <p>
Keep your old custom steps and do <a href="http://stackoverflow.com/questions/617409/script-to-change-action-sequence-records-in-an-msi">this</a>.
It was a pain to copy the script to clipboard from IE. I had to do View | Source to copy
&amp; paste the script. Also, if you save the MSI_SetActionSequence.js file in
the solution folder, your post-build event command will be exactly this:<br /><font color="#000000" face="Courier New">cscript.exe "$(ProjectDir)..\MSI_SetActionSequence.js"
"$(BuiltOuputPath)" InstallExecuteSequence RemoveExistingProducts 1525<br /><font color="#003300"><font face="Verdana">(Path to </font><font face="Courier New">MSI_SetActionSequence.js</font><font face="Verdana"> may
vary.)</font></font></font></p>
        <h4>Solution #2 - Update your VS'05 custom actions code to comply with new
(VS'08) way
</h4>
        <p>
When registering a service, two things need to be done differently compared to how
you did it in Visual Studio 2005 setup project:<br />
   1. Invoke Install step only for clean (non-upgrade) installation.<br />
   2. Commit step needs to restart the service in the case of upgrade
installation.
</p>
        <p>
Here's a bit more details and a few snippets that should help.
</p>
        <p>
1. First, in your setup project, select Install custom action of the service installer,
and set its Condition value to <strong>NOT PREVIOUSVERSIONSINSTALLED</strong>. This
will eliminate calling ServiceInstaller's Install() custom action for upgrade installation.<br /><br />
2. Select Commit action and set its CustomActionData value to <strong>/OldProductCode="[PREVIOUSVERSIONSINSTALLED]"</strong>.
This will pass the ProductCode of the old version to the Commit custom action - if
it's an upgrade installation, and blank string if it's a new installation. You can
use it in the Commit() code to determine whether it's an upgrade installation and
restart the service:<br /><font color="#0000ff" size="2"><font color="#0000ff" size="2"></font></font></p>
        <p>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">
              <br />
private</font>
          </font>
          <font size="2">
          </font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">bool</font>
          </font>
          <font size="2"> IsUpgrade<br />
{<br />
   </font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">get<br />
   </font>
          </font>
          <font size="2">{<br />
      </font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">return</font>
          </font>
          <font size="2"> !</font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">string</font>
          </font>
          <font size="2">.IsNullOrEmpty(</font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">this</font>
          </font>
          <font size="2">.Context.Parameters[</font>
          <font color="#a31515" size="2">
            <font color="#a31515" size="2">"OldProductCode"</font>
          </font>
          <font size="2">]);<br />
   }<br />
}
</font>
        </p>
        <font size="2">
          <p>
          </p>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">public</font>
        </font>
        <font size="2">
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">override</font>
        </font>
        <font size="2">
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">void</font>
        </font>
        <font size="2"> Commit(</font>
        <font color="#2b91af" size="2">
          <font color="#2b91af" size="2">IDictionary</font>
        </font>
        <font size="2"> savedState)<br />
{<br />
   </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">base</font>
        </font>
        <font size="2">.Commit
(savedState);<br /><br />
   </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">if</font>
        </font>
        <font size="2"> (</font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">this</font>
        </font>
        <font size="2">.IsUpgrade)<br />
   {<br />
      </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">this</font>
        </font>
        <font size="2">.StopService(); <font color="#008000">//
Implement your StopService() method</font><br />
   }
<p></p></font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">   this</font>
        </font>
        <font size="2">.StartService();  <font color="#008000" size="2"><font color="#008000" size="2">//
Implement your StartService() method </font></font><br /></font>
        <font size="2">}</font>
        <p>
          <font size="2">
            <br />
          </font>
          <font size="3">
            <strong>Making VS'05-generated Installers Act Like VS'08-made</strong>
          </font>
        </p>
        <p>
          <font size="2">Despite breaking windows services installers, changes to the installation
process introduced by Visual Studio 2008 do benefit other types of installations,
because being able to tell whether it's an upgrade installation and make the installer
act accordingly is quite valuable. Developers of Visual Studio 2005 can have the same functionality
if they modify their final MSI by running this PostBuildEvent command in your Setup
project:<br /><font face="Courier New">cscript.exe "$(ProjectDir)..\MSI_SetActionSequence.js" "$(BuiltOuputPath)"
InstallExecuteSequence RemoveExistingProducts <strong>6650</strong><br /></font><font face="Verdana">(Path to <font face="Courier New">MSI_SetActionSequence.js</font> may
vary.) </font></font>
        </p>
        <p>
          <font size="2">
            <font face="Verdana">If you go this route, then you likely will need
to use a pattern shown from the "Solution #2" shown above:<br />
- </font>
          </font>
          <font size="2">
            <font face="Verdana">
              <strong>Install</strong> custom
step should be called on the <strong>NOT PREVIOUSVERSIONSINSTALLED</strong> condition. 
<br />
- And to</font>
          </font>
          <font size="2">
            <font face="Verdana"> tell whether your code
runs in the upgrade mode, <strong>Commit</strong> custom steps should have <strong>/OldProductCode="[PREVIOUSVERSIONSINSTALLED]"</strong> parameter
passed to it so Commit() implementation could use this.IsUpgrade property
as shown above.</font>
          </font>
        </p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=f5da1c61-cccf-458e-9b23-06960bfef242" />
      </body>
      <title>Visual Studio 2008 Deployment Project: Custom Actions and File Upgrade Flows Have Changed</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,f5da1c61-cccf-458e-9b23-06960bfef242.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,f5da1c61-cccf-458e-9b23-06960bfef242.aspx</link>
      <pubDate>Tue, 02 Dec 2008 21:13:32 GMT</pubDate>
      <description>&lt;p&gt;
Updated on 7/25/2009.
&lt;/p&gt;
&lt;p&gt;
Visual Studio setup project &lt;a href="PermaLink,guid,33e12a70-d0f9-4a79-9e97-ffbcd60f9d53.aspx"&gt;produced
MSI packages&amp;nbsp;with problems&lt;/a&gt; for a while now. It looks like with introduction
of Visual Studio 2008, setup project added a couple of new twists, compared to VS'05: 
&lt;br&gt;
1. Order in which custom actions are called has changed. 
&lt;br&gt;
2. When installation is an upgrade, old binary files (EXE and DLL)&amp;nbsp;will only
be replaced by new ones if new binaries have higher file version.
&lt;/p&gt;
&lt;p&gt;
Here's what used to happen. MSIs produced by VS 2005 had the intuitive order:&lt;br&gt;
- Uninstall step from the old installer version.&lt;br&gt;
- Install and Commit&amp;nbsp;steps from the new installer version.
&lt;/p&gt;
&lt;p&gt;
In other words, installing an MSI created by VS 2005 was a &lt;a href="PermaLink,guid,33e12a70-d0f9-4a79-9e97-ffbcd60f9d53.aspx"&gt;very
rough&lt;/a&gt; equivalent of uninstalling&amp;nbsp;the old version, followed by installing
the new one. VS 2008 order has become a bit more complex, arguably smarter, but&amp;nbsp;also
less intuitive. 
&lt;/p&gt;
&lt;p&gt;
MSIs produced by VS 2008 seem to have this new order:&lt;br&gt;
- Install step from new installer version.&lt;br&gt;
- Commit step from the new installer version.&lt;br&gt;
Note that &lt;strong&gt;Uninstall step&amp;nbsp;of&amp;nbsp;old version installation&amp;nbsp;is not
called at all during&amp;nbsp;an upgrade-installation of an MSI generated by VS'08&lt;/strong&gt; (with
RemoveOldVersion set to True). Funny, but even though Uninstall steps does not seem
to be invoked, the&amp;nbsp;custom action assembly&amp;nbsp;of previous version is still getting
loaded, which may lead to installation crash if old version uses&amp;nbsp;.NET Framework
1.x.&amp;nbsp;Custom action order change is the biggest departure from VS'05 MSIs. Also,
only files that have been changed in the new version of the installed package, will
be replaced in the upgrade mode, while unchanged files will remain.
&lt;/p&gt;
&lt;p&gt;
Also, &lt;strong&gt;upgrade flow&lt;/strong&gt; of the MSIs generated by Visual Studio 2008 also
replaces binary files only if their FileVersion property has changed. Since this was
not a requirement in Visual Studio 2005, you may want to go through your AssemblyInfo.cs
files and ensure that they either have the wildcard in their version name (&lt;font size=2&gt;[&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;assembly&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;: &lt;/font&gt;&lt;font color=#2b91af size=2&gt;&lt;font color=#2b91af size=2&gt;AssemblyVersion&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;(&lt;/font&gt;&lt;font color=#a31515 size=2&gt;&lt;font color=#a31515 size=2&gt;"1.0.*"&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;)]&lt;/font&gt;),
or you manually&amp;nbsp;increment version before releasing a new build.&amp;nbsp;If&amp;nbsp;AssemblyVersion
and FileVersion are in sync, you can remove FileVersion&amp;nbsp;attribute from the AssemblyInfo.cs.
&lt;/p&gt;
&lt;p&gt;
You are most likely going to&amp;nbsp;experience the effect of&amp;nbsp;these changes&amp;nbsp;after
porting your Visual Studio 2005 windows service installer project&amp;nbsp;to Visual Studio
2008, and getting the "Error 1001. The specified service already exists." error. Explaining
this all would make this rather a long story, but the gist of it is this: ServiceInstaller's
Install() method attempts to register the service even if service is already registered,
which is the case in the upgrade service installation (remember, Uninstall step, which
unregisters a service&amp;nbsp;is not called anymore). ServiceInstaller's Install() throws&amp;nbsp;the
above-mentioned&amp;nbsp;exception if service is&amp;nbsp;already registered. 
&lt;/p&gt;
&lt;p&gt;
To successfully upgrade a Windows Service, it needs to be stopped before files can
be replaced. If service was not stopped and files are replaced -&amp;nbsp;target system&amp;nbsp;is
likely to be required to reboot at the end of the installation process. Stopping service&amp;nbsp;during
upgrade installation from Install custom action will be too late - at this point files
are already replaced and reboot is imminent. You see what happens here: it appears
that upgrade installation of a windows service created in Visual Studio 2008 will
*always* lead to rebooting the target machine. Given&amp;nbsp;the fact that&amp;nbsp;windows
services are very often created for server applications deployed on high-availability
machines, it's seems that windows service&amp;nbsp;installation done by the book in Visual
Studio 2008 is all but useless.
&lt;/p&gt;
&lt;p&gt;
Here are &lt;strong&gt;two&amp;nbsp;solutions&lt;/strong&gt;. 
&lt;/p&gt;
&lt;h4&gt;Solution #1 (for Windows Service Installers): Make your MSI act the old (VS'05)&amp;nbsp;way
&lt;/h4&gt;
&lt;p&gt;
Keep your old custom steps and do &lt;a href="http://stackoverflow.com/questions/617409/script-to-change-action-sequence-records-in-an-msi"&gt;this&lt;/a&gt;.
It was a pain to copy the script to clipboard from IE. I had to do View | Source to&amp;nbsp;copy
&amp;amp; paste&amp;nbsp;the script. Also, if you save the MSI_SetActionSequence.js file in
the solution folder, your&amp;nbsp;post-build event command will be exactly this:&lt;br&gt;
&lt;font color=#000000 face="Courier New"&gt;cscript.exe "$(ProjectDir)..\MSI_SetActionSequence.js"
"$(BuiltOuputPath)" InstallExecuteSequence RemoveExistingProducts 1525&lt;br&gt;
&lt;font color=#003300&gt;&lt;font face=Verdana&gt;(Path to &lt;/font&gt;&lt;font face="Courier New"&gt;MSI_SetActionSequence.js&lt;/font&gt;&lt;font face=Verdana&gt;&amp;nbsp;may
vary.)&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;h4&gt;Solution&amp;nbsp;#2 - Update your&amp;nbsp;VS'05 custom actions code to comply with new
(VS'08)&amp;nbsp;way
&lt;/h4&gt;
&lt;p&gt;
When registering a service, two things need to be done differently compared to how
you did it in Visual Studio 2005 setup project:&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;1. Invoke Install step only for clean (non-upgrade) installation.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;2. Commit step needs to restart the service in the case of upgrade
installation.
&lt;/p&gt;
&lt;p&gt;
Here's a bit more details and a few snippets that should help.
&lt;/p&gt;
&lt;p&gt;
1. First, in your setup project, select Install custom action of the service installer,
and set its Condition value to &lt;strong&gt;NOT PREVIOUSVERSIONSINSTALLED&lt;/strong&gt;. This
will eliminate calling ServiceInstaller's Install() custom action for upgrade installation.&lt;br&gt;
&lt;br&gt;
2. Select Commit action and set its CustomActionData value to &lt;strong&gt;/OldProductCode="[PREVIOUSVERSIONSINSTALLED]"&lt;/strong&gt;.
This will pass the ProductCode of the old version to the Commit custom action - if
it's an upgrade installation, and blank string if it's a new installation. You can
use it in the Commit() code to determine whether it's an upgrade installation and
restart the service:&lt;br&gt;
&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;
&lt;br&gt;
private&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt; &lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;bool&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt; IsUpgrade&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;get&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;return&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt; !&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;string&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;.IsNullOrEmpty(&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;this&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;.Context.Parameters[&lt;/font&gt;&lt;font color=#a31515 size=2&gt;&lt;font color=#a31515 size=2&gt;"OldProductCode"&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;]);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}
&lt;/p&gt;
&gt;&lt;font size=2&gt; 
&lt;p&gt;
&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;public&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt; &lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;override&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt; &lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;void&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt; Commit(&lt;/font&gt;&lt;font color=#2b91af size=2&gt;&lt;font color=#2b91af size=2&gt;IDictionary&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt; savedState)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;base&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;.Commit
(savedState);&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;if&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt; (&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;this&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;.IsUpgrade)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;this&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;.StopService(); &lt;font color=#008000&gt;//
Implement your StopService() method&lt;/font&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&gt;
&lt;p&gt;
&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;this&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;.StartService();&amp;nbsp; &lt;font color=#008000 size=2&gt;&lt;font color=#008000 size=2&gt;//
Implement your StartService() method &lt;/font&gt;&lt;/font&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font size=2&gt;}&lt;/font&gt;&gt;
&lt;p&gt;
&lt;font size=2&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font size=3&gt;&lt;strong&gt;Making VS'05-generated&amp;nbsp;Installers Act Like VS'08-made&lt;/strong&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font size=2&gt;Despite breaking windows services installers, changes to the installation
process introduced by Visual Studio 2008 do benefit other types of installations,
because being able to tell whether it's an upgrade installation and make the installer
act accordingly is quite valuable. Developers of Visual Studio 2005 can have the same&amp;nbsp;functionality
if they modify their final MSI by running this PostBuildEvent command in your Setup
project:&lt;br&gt;
&lt;font face="Courier New"&gt;cscript.exe "$(ProjectDir)..\MSI_SetActionSequence.js" "$(BuiltOuputPath)"
InstallExecuteSequence RemoveExistingProducts &lt;strong&gt;6650&lt;/strong&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font face=Verdana&gt;(Path to &lt;font face="Courier New"&gt;MSI_SetActionSequence.js&lt;/font&gt;&amp;nbsp;may
vary.)&amp;nbsp;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font size=2&gt;&lt;font face=Verdana&gt;If you go this route, then you likely will need to
use a pattern shown&amp;nbsp;from the&amp;nbsp;"Solution #2" shown above:&lt;br&gt;
- &lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font face=Verdana&gt;&lt;strong&gt;Install&lt;/strong&gt; custom step
should be called on the &lt;strong&gt;NOT PREVIOUSVERSIONSINSTALLED&lt;/strong&gt;&amp;nbsp;condition. 
&lt;br&gt;
- And to&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font face=Verdana&gt; tell whether your code runs
in the upgrade mode, &lt;strong&gt;Commit&lt;/strong&gt; custom steps should have &lt;strong&gt;/OldProductCode="[PREVIOUSVERSIONSINSTALLED]"&lt;/strong&gt;&amp;nbsp;parameter
passed to it so&amp;nbsp;Commit() implementation could&amp;nbsp;use this.IsUpgrade property
as shown above.&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=f5da1c61-cccf-458e-9b23-06960bfef242" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,f5da1c61-cccf-458e-9b23-06960bfef242.aspx</comments>
      <category>.NET Programming;MSI;Sofware Development;Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=7885abfa-f502-429f-8016-309e233e4554</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,7885abfa-f502-429f-8016-309e233e4554.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,7885abfa-f502-429f-8016-309e233e4554.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=7885abfa-f502-429f-8016-309e233e4554</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Since I use ASP.NET HTTP handlers quite often, I decided to figure out what advantages
IHttpAsyncHandler has compared with IHttpHandler. As I looked at many people's claim
that IHttpAsyncHandler somehow magically improves performance by shifting request processing
on to another thread, I realized that MSDN documentation of IHttpAsyncHandler is laking
in a fundamental way: it fails to mention that simply moving request rendering
onto another thread does not yield any benefit. 
</p>
        <p>
When you simply move your request handling logic from the original
ASP.NET thread to your own thread (IHttpAsyncHandler), you gain exactly nothing because
both threads come from the same pool. The benefit of IHttpAsyncHandler comes in only
when your request processing thread is blocking, waiting for <strong>another
thread</strong>. For example, if your request processing calls a web service, your
request processing thread will wait for the IO completion happening on another thread
- where request is sent to the web service. In this case there
will be <strong>two</strong> threads involved: your request processing thread, and
the IO thread where outgoing web service request is being executed. This is the situation
where IHttpAsyncHandler can help: instead of holding on to the request processing
thread while waiting for the outgoing request to complete, one can release the original
request processing thread back to the pool, and finish response rendering on the IO
thread after the web service request has completed. This way, instead of holding two
threads for the duration of the relatively long-running process of invoking
a web service, your request processing is using only one thread.
</p>
        <p>
So, the bottom line is this:<br />
- You should only concert yourself with IHttpAsyncHandler if you are running out of
request processing threads.<br />
- If you do, check your logic for whether it's waiting for an IO completion (or
is using other threads for other reasons), and only if that's the case, switch to
IHttpAsyncHandler.<br />
- Otherwise simply increase the size of the ASP.NET thread pool in the web.config
and stick with good ole' IHttpHandler.<br /></p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=7885abfa-f502-429f-8016-309e233e4554" />
      </body>
      <title>ASP.NET IHttpAsyncHandler vs IHttpHandler</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,7885abfa-f502-429f-8016-309e233e4554.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,7885abfa-f502-429f-8016-309e233e4554.aspx</link>
      <pubDate>Mon, 10 Nov 2008 20:52:23 GMT</pubDate>
      <description>&lt;p&gt;
Since I use ASP.NET HTTP handlers quite often, I decided to figure out what advantages
IHttpAsyncHandler has compared with IHttpHandler. As I looked at many people's claim
that IHttpAsyncHandler somehow magically improves performance by shifting&amp;nbsp;request&amp;nbsp;processing
on to another thread, I realized that MSDN documentation of IHttpAsyncHandler is laking
in&amp;nbsp;a fundamental way: it fails to mention that simply&amp;nbsp;moving request rendering
onto another thread&amp;nbsp;does not&amp;nbsp;yield any benefit. 
&lt;/p&gt;
&lt;p&gt;
When you simply&amp;nbsp;move your&amp;nbsp;request handling logic from&amp;nbsp;the original
ASP.NET thread to your own thread (IHttpAsyncHandler), you gain exactly nothing&amp;nbsp;because
both threads come from the same pool. The benefit of IHttpAsyncHandler comes in only
when your request processing thread&amp;nbsp;is blocking, waiting for &lt;strong&gt;another
thread&lt;/strong&gt;. For example, if your request processing calls a web service, your
request processing thread will wait for the IO completion happening on another thread
- where&amp;nbsp;request&amp;nbsp;is sent to&amp;nbsp;the web&amp;nbsp;service. In this case there
will be &lt;strong&gt;two&lt;/strong&gt; threads involved: your request processing thread, and
the IO thread where outgoing web service request is being executed. This is the situation
where IHttpAsyncHandler can help: instead of holding on to the request processing
thread while waiting for the outgoing request to complete, one can release the original
request processing thread back to the pool, and finish response rendering on the IO
thread after the web service request has completed. This way, instead of holding two
threads&amp;nbsp;for the duration of the&amp;nbsp;relatively long-running process of invoking
a web service, your request processing is using only one thread.
&lt;/p&gt;
&lt;p&gt;
So, the bottom line is this:&lt;br&gt;
- You should only concert yourself with IHttpAsyncHandler if you are running out of
request processing threads.&lt;br&gt;
- If you do, check your logic for whether it's waiting for&amp;nbsp;an IO completion (or
is using other threads for other reasons), and only if that's the case, switch to
IHttpAsyncHandler.&lt;br&gt;
- Otherwise simply increase the size of the ASP.NET thread pool in the web.config
and stick with good ole' IHttpHandler.&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=7885abfa-f502-429f-8016-309e233e4554" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,7885abfa-f502-429f-8016-309e233e4554.aspx</comments>
      <category>.NET Programming;AJAX;ASP.NET;Sofware Development</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=c46a9fb6-041e-4cdc-adca-6fd6bf0a3c36</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,c46a9fb6-041e-4cdc-adca-6fd6bf0a3c36.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,c46a9fb6-041e-4cdc-adca-6fd6bf0a3c36.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=c46a9fb6-041e-4cdc-adca-6fd6bf0a3c36</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Microsoft marketing folks are incorrigible. When explaining new technology they invariably
fail to make anything any more clear. Case in point: Microsoft Azure. Parsing through
the Azure site left an impression that MS don't really want anyone to find out what
in the world they are really doing.
</p>
        <p>
For those who don't have time to filter through MS marketing noise, consider
reading this very concise, pretty funny even if somewhat crude-worded Windows Azure
review:<br /><a href="http://www.theregister.co.uk/2008/11/03/dziuba_azure/print.html">http://www.theregister.co.uk/2008/11/03/dziuba_azure/print.html</a></p>
        <p>
          <strong>Update</strong>: <a href="http://download.microsoft.com/download/e/4/3/e43bb484-3b52-4fa8-a9f9-ec60a32954bc/Azure_Services_Platform.pdf">This
white paper</a> penned by David Chappell is most to-the-point Azure doc so far.
</p>
        <p>
          <strong>Update 2</strong>: <a href="http://www.microsoft.com/azure/Pricing.mspx">Azure
pricing information</a>.
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=c46a9fb6-041e-4cdc-adca-6fd6bf0a3c36" />
      </body>
      <title>Microsoft Azure Critique/Review</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,c46a9fb6-041e-4cdc-adca-6fd6bf0a3c36.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,c46a9fb6-041e-4cdc-adca-6fd6bf0a3c36.aspx</link>
      <pubDate>Fri, 07 Nov 2008 14:53:48 GMT</pubDate>
      <description>&lt;p&gt;
Microsoft marketing folks are incorrigible. When explaining new technology they invariably
fail to make anything any more clear. Case in point: Microsoft Azure. Parsing through
the Azure site left an impression that MS don't really want anyone to find out what
in the world they are really doing.
&lt;/p&gt;
&lt;p&gt;
For those who&amp;nbsp;don't have time to filter&amp;nbsp;through MS marketing noise, consider
reading this very concise, pretty funny even if somewhat crude-worded Windows Azure
review:&lt;br&gt;
&lt;a href="http://www.theregister.co.uk/2008/11/03/dziuba_azure/print.html"&gt;http://www.theregister.co.uk/2008/11/03/dziuba_azure/print.html&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Update&lt;/strong&gt;: &lt;a href="http://download.microsoft.com/download/e/4/3/e43bb484-3b52-4fa8-a9f9-ec60a32954bc/Azure_Services_Platform.pdf"&gt;This
white paper&lt;/a&gt; penned by David Chappell is most to-the-point Azure doc so far.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Update 2&lt;/strong&gt;: &lt;a href="http://www.microsoft.com/azure/Pricing.mspx"&gt;Azure
pricing information&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=c46a9fb6-041e-4cdc-adca-6fd6bf0a3c36" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,c46a9fb6-041e-4cdc-adca-6fd6bf0a3c36.aspx</comments>
      <category>.NET Programming;ASP.NET;Sofware Development;Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=43484701-c89a-4b78-9cf7-7e3acd8a3a0b</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,43484701-c89a-4b78-9cf7-7e3acd8a3a0b.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,43484701-c89a-4b78-9cf7-7e3acd8a3a0b.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=43484701-c89a-4b78-9cf7-7e3acd8a3a0b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It's very easy to write a windows service using C# or VB.NET. Easy to write, easy
to install, but for a price. 
</p>
        <p>
It's an often overlooked fact, but in .NET runtime, <strong>Garbage Collector does
not merge together freed memory chunks, if they are larger than 85K</strong>. What
does it mean? It means that if your managed windows service allocates and frees buffers
larger than 85K on a continuous basis, your service will crash because it will eventually
run of memory due to Large Object Heap (LOH) fragmentation. Again, it will only happen
if your managed windows service allocates objects of 84,000+ (give or take) byte,
but IT WILL HAPPEN!
</p>
        <p>
There are <strong>workarounds</strong>, somewhat expensive, like wrapping your service
logic in COM+ server-activated process, which can be set up to recycle - just like
IIS AppPools are recycled. Or one could create a proprietary memory manager with
a pool of large buffers, making of which, of course, would be kind of ironic since
the whole point of having garbage-collected memory manager was to eliminate hassles
of memory management.
</p>
        <p>
Anyway, the purpose of this post is to raise awareness among fellow windows service
developers. If your service is high-throughput, high memory usage, it will go
down in flames even if your code is perfect. The choices are: a) ensure all your memory
allocations do not take more than 84K, b) implement your own memory manager, or c)
implement worker process recycling.
</p>
        <p>
Good luck to all of us.
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=43484701-c89a-4b78-9cf7-7e3acd8a3a0b" />
      </body>
      <title>Why Managed Windows Services Hog Memory and Eventually Crash</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,43484701-c89a-4b78-9cf7-7e3acd8a3a0b.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,43484701-c89a-4b78-9cf7-7e3acd8a3a0b.aspx</link>
      <pubDate>Thu, 30 Oct 2008 02:52:59 GMT</pubDate>
      <description>&lt;p&gt;
It's very easy to write a windows service using C# or VB.NET. Easy to write, easy
to install, but for a price. 
&lt;/p&gt;
&lt;p&gt;
It's an often overlooked fact, but in .NET runtime, &lt;strong&gt;Garbage Collector&amp;nbsp;does
not merge together freed memory chunks, if they are larger than 85K&lt;/strong&gt;. What
does it mean? It means that if your managed windows service allocates and frees buffers
larger than 85K on a continuous basis, your service will crash because it will eventually
run of memory due to Large Object Heap (LOH) fragmentation. Again, it will only happen
if your managed windows service allocates&amp;nbsp;objects of 84,000+ (give or take) byte,
but IT WILL HAPPEN!
&lt;/p&gt;
&lt;p&gt;
There are &lt;strong&gt;workarounds&lt;/strong&gt;, somewhat expensive, like wrapping your service
logic in COM+ server-activated process, which can be set up to recycle - just like
IIS AppPools are recycled. Or one could create a&amp;nbsp;proprietary memory manager with
a pool of large buffers, making of which, of course, would be kind of ironic since
the whole point of having garbage-collected memory manager was to eliminate hassles
of memory management.
&lt;/p&gt;
&lt;p&gt;
Anyway, the purpose of this post is to raise awareness among fellow windows service
developers. If your service is high-throughput,&amp;nbsp;high memory usage, it will go
down in flames even if your code is perfect. The choices are: a) ensure all your memory
allocations do not take more than 84K, b) implement your own memory manager, or c)
implement worker process recycling.
&lt;/p&gt;
&lt;p&gt;
Good luck to all of us.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=43484701-c89a-4b78-9cf7-7e3acd8a3a0b" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,43484701-c89a-4b78-9cf7-7e3acd8a3a0b.aspx</comments>
      <category>.NET Programming;Software Testing;Sofware Development;Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=cfe694cd-5bb9-4b3d-8cbd-cc95e9681f99</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,cfe694cd-5bb9-4b3d-8cbd-cc95e9681f99.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,cfe694cd-5bb9-4b3d-8cbd-cc95e9681f99.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=cfe694cd-5bb9-4b3d-8cbd-cc95e9681f99</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It's much easier to read large numbers when thousands are separated by commas. But
I can never remember how the numeric format with thousands comma-separated is
defined for .NET String.Format() method and for the databinding. So more as a note
to self, here it is:
</p>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
            <p>
string
</p>
          </font>
        </font>
        <font color="#000000" size="2"> output = </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">string</font>
        </font>
        <font color="#000000" size="2">.Format(</font>
        <font color="#a31515" size="2">
          <font color="#a31515" size="2">"{0:#,#}"</font>
        </font>
        <font color="#000000" size="2">,
123456789); </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">//
Will produce 123,456,789
</font>
        </font>
        <p>
The same goes for data binding data sources to data controls like DataGridView. Specify
format as <font color="#a31515" size="2"><font color="#a31515" size="2">"{0:#,#}"</font></font>.
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=cfe694cd-5bb9-4b3d-8cbd-cc95e9681f99" />
      </body>
      <title>Thousands Separator When Formatting Numeric String in .NET (C#, VB.NET) Programming</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,cfe694cd-5bb9-4b3d-8cbd-cc95e9681f99.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,cfe694cd-5bb9-4b3d-8cbd-cc95e9681f99.aspx</link>
      <pubDate>Sat, 26 Jul 2008 15:18:35 GMT</pubDate>
      <description>&lt;p&gt;
It's much easier to read large numbers when thousands are separated by commas. But
I can never remember how the numeric format&amp;nbsp;with thousands comma-separated is
defined for .NET String.Format() method and for the databinding. So more as a note
to self, here it is:
&lt;/p&gt;
&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt; 
&lt;p&gt;
string
&lt;/font&gt;&lt;/font&gt;&lt;font color=#000000 size=2&gt; output = &lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;string&lt;/font&gt;&lt;/font&gt;&lt;font color=#000000 size=2&gt;.Format(&lt;/font&gt;&lt;font color=#a31515 size=2&gt;&lt;font color=#a31515 size=2&gt;"{0:#,#}"&lt;/font&gt;&lt;/font&gt;&lt;font color=#000000 size=2&gt;,
123456789); &lt;/font&gt;&lt;font color=#008000 size=2&gt;&lt;font color=#008000 size=2&gt;// Will produce
123,456,789&gt;
&lt;/font&gt;&lt;/font&gt; 
&lt;p&gt;
The same goes for data binding data sources to data controls like DataGridView. Specify
format as &lt;font color=#a31515 size=2&gt;&lt;font color=#a31515 size=2&gt;"{0:#,#}"&lt;/font&gt;&lt;/font&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=cfe694cd-5bb9-4b3d-8cbd-cc95e9681f99" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,cfe694cd-5bb9-4b3d-8cbd-cc95e9681f99.aspx</comments>
      <category>.NET Programming;ASP.NET;Sofware Development;Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=70ed5fdc-0489-410b-9f59-9d69c3e6bcfc</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,70ed5fdc-0489-410b-9f59-9d69c3e6bcfc.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,70ed5fdc-0489-410b-9f59-9d69c3e6bcfc.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=70ed5fdc-0489-410b-9f59-9d69c3e6bcfc</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
If your ASP.NET 1.1 or 2.0 application throws "<em>This implementation is not part
of the Windows Platform FIPS validated cryptographic algorithms</em>" exception, the
easiest way to fix is to add <br /><font color="#0000ff" size="2"><font color="#0000ff" size="2">      &lt;</font></font><font color="#a31515" size="2"><font color="#a31515" size="2">machineKey</font></font><font color="#0000ff" size="2"><font color="#0000ff" size="2"></font></font><font color="#ff0000" size="2"><font color="#ff0000" size="2">validationKey</font></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">=</font></font><font color="#000000" size="2">"</font><font color="#0000ff" size="2"><font color="#0000ff" size="2">AutoGenerate,IsolateApps</font></font><font color="#000000" size="2">"</font><font color="#0000ff" size="2"><font color="#0000ff" size="2"></font></font><font color="#ff0000" size="2"><font color="#ff0000" size="2">decryptionKey</font></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">=</font></font><font color="#000000" size="2">"</font><font color="#0000ff" size="2"><font color="#0000ff" size="2">AutoGenerate,IsolateApps</font></font><font color="#000000" size="2">"</font><font color="#0000ff" size="2"><font color="#0000ff" size="2"></font></font><font color="#ff0000" size="2"><font color="#ff0000" size="2">validation</font></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">=</font></font><font color="#000000" size="2">"</font><font color="#0000ff" size="2"><font color="#0000ff" size="2">3DES</font></font><font color="#000000" size="2">"</font><font color="#0000ff" size="2"><font color="#0000ff" size="2"></font></font><font color="#ff0000" size="2"><font color="#ff0000" size="2">decryption</font></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">=</font></font><font color="#000000" size="2">"</font><font color="#0000ff" size="2"><font color="#0000ff" size="2">3DES</font></font><font color="#000000" size="2">"</font><font color="#0000ff" size="2"><font color="#0000ff" size="2">/&gt;<br /></font></font>line to the <font color="#0000ff" size="2"><font color="#0000ff" size="2">&lt;</font></font><font color="#a31515" size="2"><font color="#a31515" size="2">system.web</font></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">&gt;</font></font> section
of the <strong>web.config</strong> file of your application. 
</p>
        <p>
FIPS compliance is required for software installed on US government computers.
The compliance requirement can be <a href="http://blogs.msdn.com/shawnfa/archive/2005/05/16/417975.aspx">turned
on and off</a>.
</p>
        <p>
Source: <a href="http://support.microsoft.com/kb/911722">http://support.microsoft.com/kb/911722</a><br /><br /></p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=70ed5fdc-0489-410b-9f59-9d69c3e6bcfc" />
      </body>
      <title>Make Your ASP.NET Application FIPS Compliant for US Government Use</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,70ed5fdc-0489-410b-9f59-9d69c3e6bcfc.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,70ed5fdc-0489-410b-9f59-9d69c3e6bcfc.aspx</link>
      <pubDate>Wed, 23 Jul 2008 18:23:18 GMT</pubDate>
      <description>&lt;p&gt;
If your ASP.NET 1.1 or 2.0 application throws "&lt;em&gt;This implementation is not part
of the Windows Platform FIPS validated cryptographic algorithms&lt;/em&gt;" exception, the
easiest way to fix is to add&amp;nbsp;&lt;br&gt;
&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515 size=2&gt;&lt;font color=#a31515 size=2&gt;machineKey&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt; &lt;/font&gt;&lt;/font&gt;&lt;font color=#ff0000 size=2&gt;&lt;font color=#ff0000 size=2&gt;validationKey&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;=&lt;/font&gt;&lt;/font&gt;&lt;font color=#000000 size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;AutoGenerate,IsolateApps&lt;/font&gt;&lt;/font&gt;&lt;font color=#000000 size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt; &lt;/font&gt;&lt;/font&gt;&lt;font color=#ff0000 size=2&gt;&lt;font color=#ff0000 size=2&gt;decryptionKey&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;=&lt;/font&gt;&lt;/font&gt;&lt;font color=#000000 size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;AutoGenerate,IsolateApps&lt;/font&gt;&lt;/font&gt;&lt;font color=#000000 size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt; &lt;/font&gt;&lt;/font&gt;&lt;font color=#ff0000 size=2&gt;&lt;font color=#ff0000 size=2&gt;validation&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;=&lt;/font&gt;&lt;/font&gt;&lt;font color=#000000 size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;3DES&lt;/font&gt;&lt;/font&gt;&lt;font color=#000000 size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt; &lt;/font&gt;&lt;/font&gt;&lt;font color=#ff0000 size=2&gt;&lt;font color=#ff0000 size=2&gt;decryption&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;=&lt;/font&gt;&lt;/font&gt;&lt;font color=#000000 size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;3DES&lt;/font&gt;&lt;/font&gt;&lt;font color=#000000 size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;/&amp;gt;&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;line to the &lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;&amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;font color=#a31515 size=2&gt;&lt;font color=#a31515 size=2&gt;system.web&lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&lt;font color=#0000ff size=2&gt;&amp;gt;&lt;/font&gt;&lt;/font&gt;&amp;nbsp;section
of the &lt;strong&gt;web.config&lt;/strong&gt; file of your application. 
&lt;/p&gt;
&lt;p&gt;
FIPS compliance&amp;nbsp;is required for software installed on US government computers.
The compliance requirement can be &lt;a href="http://blogs.msdn.com/shawnfa/archive/2005/05/16/417975.aspx"&gt;turned
on and off&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Source: &lt;a href="http://support.microsoft.com/kb/911722"&gt;http://support.microsoft.com/kb/911722&lt;/a&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=70ed5fdc-0489-410b-9f59-9d69c3e6bcfc" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,70ed5fdc-0489-410b-9f59-9d69c3e6bcfc.aspx</comments>
      <category>ASP.NET;Security;Sofware Development</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=8e4e53ea-e4ec-48fc-bbf8-84b441b3aa8f</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,8e4e53ea-e4ec-48fc-bbf8-84b441b3aa8f.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,8e4e53ea-e4ec-48fc-bbf8-84b441b3aa8f.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=8e4e53ea-e4ec-48fc-bbf8-84b441b3aa8f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
After I have <a href="PermaLink,guid,8002e762-5aff-4f1a-8020-56ce0f238e28.aspx">upgraded
the motherboard on my desktop</a>, a few things got messed up, the most annoying of
which was that Visual Studio 2008 has lost its XSD/Dataset editor. Opening a data
set resulted in opening it as a text or XML, and when I right-clicked the XSD file
and selected "Open With..." from the menu, the XSD editor was not there. Repairing
and completely uninstalling and reinstalling VS 2008 did not help. After searching
the web I found that some people have the same problem, but I found no solution for
Visual Studio 2008. The solution that worked for me was described for the <a href="http://forums.asp.net/t/1116852.aspx">similar
problem with Visual Studio 2005</a>. I ran “devenv /resetsettings” and it didn't help.
Then I ran <strong>“devenv /setup”</strong> and hallelujah: XSDs are opening
again in the Design mode! To launch devenv you will need to start VS 2008 command
prompt first.
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=8e4e53ea-e4ec-48fc-bbf8-84b441b3aa8f" />
      </body>
      <title>Dealing with Missing Dataset Editor in Visual Studio 2008</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,8e4e53ea-e4ec-48fc-bbf8-84b441b3aa8f.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,8e4e53ea-e4ec-48fc-bbf8-84b441b3aa8f.aspx</link>
      <pubDate>Fri, 04 Jul 2008 23:25:39 GMT</pubDate>
      <description>&lt;p&gt;
After I have &lt;a href="PermaLink,guid,8002e762-5aff-4f1a-8020-56ce0f238e28.aspx"&gt;upgraded
the motherboard on my desktop&lt;/a&gt;, a few things got messed up, the most annoying of
which was that Visual Studio 2008 has lost its XSD/Dataset editor. Opening a data
set resulted in opening it as a text or XML, and when I right-clicked the XSD file
and selected "Open With..." from the menu, the XSD editor was not there. Repairing
and completely uninstalling and reinstalling VS 2008 did not help. After searching
the web I found that some people have the same problem, but I found no solution for
Visual Studio 2008. The solution that worked for me was described for the &lt;a href="http://forums.asp.net/t/1116852.aspx"&gt;similar
problem with Visual Studio 2005&lt;/a&gt;. I ran “devenv /resetsettings” and it didn't help.
Then I ran &lt;strong&gt;“devenv /setup”&lt;/strong&gt; and&amp;nbsp;hallelujah: XSDs are opening
again in the Design mode!&amp;nbsp;To launch devenv you will need to start VS 2008 command
prompt first.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=8e4e53ea-e4ec-48fc-bbf8-84b441b3aa8f" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,8e4e53ea-e4ec-48fc-bbf8-84b441b3aa8f.aspx</comments>
      <category>Sofware Development;Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=c27f99da-8899-4006-a69b-d601826dae53</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,c27f99da-8899-4006-a69b-d601826dae53.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,c27f99da-8899-4006-a69b-d601826dae53.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=c27f99da-8899-4006-a69b-d601826dae53</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
WebService Studio 2.0 (a.k.a. Web Service Studio) is a quick &amp; dirty web service
client tool that can import your web service's WSDL and allow you to call web service's
methods without having to create your own test client.
</p>
        <p>
WebService Studio used to be hosted on Microsoft's GotDotNet web site, but ever since
GotDotNet was replaced by Codeplex, Web Service Studio was nowhere to be found. Fortunately,
some kind stranger made WSS available for download at his blog: <a href="http://mattharrah.com/blog/web-tools/net-web-service-studio-20/">http://mattharrah.com/blog/web-tools/net-web-service-studio-20/</a>.
</p>
        <p>
          <strong>Update:</strong> BTW, if you are planning to use WebService Studio to test
WCF web services, you will need to configure your web service to use basicHttpBinding
instead of wsHttpBinding.
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=c27f99da-8899-4006-a69b-d601826dae53" />
      </body>
      <title>Download WebService Studio 2.0</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,c27f99da-8899-4006-a69b-d601826dae53.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,c27f99da-8899-4006-a69b-d601826dae53.aspx</link>
      <pubDate>Mon, 19 May 2008 14:32:03 GMT</pubDate>
      <description>&lt;p&gt;
WebService Studio 2.0 (a.k.a. Web Service Studio) is a quick &amp;amp; dirty web service
client tool that can import your web service's WSDL and allow you to call web service's
methods without having to create your own test client.
&lt;/p&gt;
&lt;p&gt;
WebService Studio used to be hosted on Microsoft's GotDotNet web site, but ever since
GotDotNet was replaced by Codeplex, Web Service Studio was nowhere to be found. Fortunately,
some kind stranger made WSS available for download at his blog: &lt;a href="http://mattharrah.com/blog/web-tools/net-web-service-studio-20/"&gt;http://mattharrah.com/blog/web-tools/net-web-service-studio-20/&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Update:&lt;/strong&gt; BTW, if you are planning to use WebService Studio to test
WCF web services, you will need to configure your web service to use basicHttpBinding
instead of wsHttpBinding.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=c27f99da-8899-4006-a69b-d601826dae53" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,c27f99da-8899-4006-a69b-d601826dae53.aspx</comments>
      <category>.NET Programming;Software Testing;Sofware Development</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=0de04deb-9ef1-4bd1-afc9-c642af7f7593</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,0de04deb-9ef1-4bd1-afc9-c642af7f7593.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,0de04deb-9ef1-4bd1-afc9-c642af7f7593.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=0de04deb-9ef1-4bd1-afc9-c642af7f7593</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
After installing Visual Studio 2008 on a new machine and starting playing with a simple
Windows Communication Foundation project, I attempted to change service's WCF settings
using WCF Service Configuration Editor utility (SvcConfigEditor.exe). However, I got
the "Windows SDK is not installed correctly" error. "<a href="http://en.wikipedia.org/wiki/Internets_(colloquialism)">Internets</a>"
were surprisingly mum on the subject, so I had to figure out the solution myself.
</p>
        <p>
To fix the problem, I had to <strong>install <a href="http://go.microsoft.com/fwlink/?LinkId=64674">Windows
SDK 6.0</a></strong> manually. After I did that, the problem went away. Just quit
Visual Studio 2008 before installing Windows SDK.
</p>
        <p>
          <strong>Update:</strong> Even after reinstalling Windows SDK, first time right-clicking
on the web.config in the Visual Studio '08 Solution Explorer does not bring "Edit
WCF Configuration" item to the menu. However, after I did <strong>Tools</strong> |
"<strong>WCF Service Configuration Editor</strong>", "Edit WCF Configuration" item
started showing up upon right-clicking the .config file.
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=0de04deb-9ef1-4bd1-afc9-c642af7f7593" />
      </body>
      <title>VS 2008: Windows SDK 6.0 Needed for WCF "Service Configuration Editor" Utility</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,0de04deb-9ef1-4bd1-afc9-c642af7f7593.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,0de04deb-9ef1-4bd1-afc9-c642af7f7593.aspx</link>
      <pubDate>Thu, 15 May 2008 20:53:38 GMT</pubDate>
      <description>&lt;p&gt;
After installing Visual Studio 2008 on a new machine and starting playing with a simple
Windows Communication Foundation project, I attempted to change service's WCF settings
using WCF Service Configuration Editor utility (SvcConfigEditor.exe). However, I got
the "Windows SDK is not installed correctly" error. "&lt;a href="http://en.wikipedia.org/wiki/Internets_(colloquialism)"&gt;Internets&lt;/a&gt;"
were surprisingly mum on the subject, so I had to figure out the solution myself.
&lt;/p&gt;
&lt;p&gt;
To fix the problem, I had to &lt;strong&gt;install &lt;a href="http://go.microsoft.com/fwlink/?LinkId=64674"&gt;Windows
SDK 6.0&lt;/a&gt;&lt;/strong&gt; manually. After I did that, the problem went away. Just quit
Visual Studio 2008 before installing Windows SDK.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Update:&lt;/strong&gt; Even after reinstalling Windows SDK, first time right-clicking
on the web.config in the Visual Studio '08 Solution Explorer does not bring "Edit
WCF Configuration" item to the menu. However, after I did &lt;strong&gt;Tools&lt;/strong&gt; |
"&lt;strong&gt;WCF Service Configuration Editor&lt;/strong&gt;", "Edit WCF Configuration" item
started showing up upon right-clicking the .config file.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=0de04deb-9ef1-4bd1-afc9-c642af7f7593" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,0de04deb-9ef1-4bd1-afc9-c642af7f7593.aspx</comments>
      <category>.NET Programming;ASP.NET;Sofware Development;Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=06b316fa-fffb-484d-90e0-1c89467865af</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,06b316fa-fffb-484d-90e0-1c89467865af.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,06b316fa-fffb-484d-90e0-1c89467865af.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=06b316fa-fffb-484d-90e0-1c89467865af</wfw:commentRss>
      <title>How Windows Performance Counters of "Average" Types Linked to Their Bases</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,06b316fa-fffb-484d-90e0-1c89467865af.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,06b316fa-fffb-484d-90e0-1c89467865af.aspx</link>
      <pubDate>Thu, 20 Mar 2008 22:04:21 GMT</pubDate>
      <description>&lt;p&gt;
Some time ago I added performance counters to the application I was working on, and
for some inexplicable reason all counters of "Average" type, like &lt;font size=2&gt;AverageCount64
or &lt;font size=2&gt;AverageTimer32, didn't work at all, always having 0 value. Then I
had no time to find out why it was not working, but today I did. As you may know,
"Average" counters are made of two distinct counters:&amp;nbsp;the base counter and the
average counter itself. The mystery was that by looking at all the samples returned
by Google, it was unclear how the Base and the Average itself are linked together.
It looked like you create the Base and the Average, add them to the collection and
somehow magically Windows figures they need to be linked together when averages are
calculated. After some research it looks like the two are &lt;strong&gt;linked by counter
name&lt;/strong&gt;! It appears that base's name should be the name of real counter, plus
word " base". For example, when you define your counter category that has average
performance counter, you do something like this:&lt;br&gt;
&lt;font size=2&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;counters.Add(&lt;/font&gt;&lt;font color=#0000ff size=2&gt;new&lt;/font&gt;&lt;font size=2&gt; &lt;/font&gt;&lt;font color=#008080 size=2&gt;CounterCreationData&lt;/font&gt;&lt;font size=2&gt;(&lt;/font&gt;&lt;font color=#800000 size=2&gt;"whatever"&lt;/font&gt;&lt;font size=2&gt;, &lt;/font&gt;&lt;font color=#800000 size=2&gt;"whatever
desc"&lt;/font&gt;&lt;font size=2&gt;, &lt;/font&gt;&lt;font color=#008080 size=2&gt;PerformanceCounterType&lt;/font&gt;&lt;font size=2&gt;.AverageCount64));&lt;br&gt;
&lt;/font&gt;&lt;font size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;counters.Add(&lt;/font&gt;&lt;font color=#0000ff size=2&gt;new&lt;/font&gt;&lt;font size=2&gt; &lt;/font&gt;&lt;font color=#008080 size=2&gt;CounterCreationData&lt;/font&gt;&lt;font size=2&gt;(&lt;/font&gt;&lt;font color=#800000 size=2&gt;"whatever&lt;strong&gt; base&lt;/strong&gt;"&lt;/font&gt;&lt;font size=2&gt;, &lt;/font&gt;&lt;font color=#800000 size=2&gt;"whatever
base desc"&lt;/font&gt;&lt;font size=2&gt;, &lt;/font&gt;&lt;font color=#008080 size=2&gt;PerformanceCounterType&lt;/font&gt;&lt;font size=2&gt;.AverageBase));&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font size=2&gt;&lt;font size=2&gt;&lt;font size=2&gt;To my surprise, changing the &lt;font color=#800000&gt;"whatever&lt;strong&gt; base&lt;/strong&gt;"&amp;nbsp;&lt;/font&gt;value&amp;nbsp;of
the counter&amp;nbsp;name&amp;nbsp;in both &lt;font color=#008080&gt;CounterCreationData &lt;/font&gt;and &lt;font color=#008080 size=2&gt;PerformanceCounter&lt;/font&gt; to
something like "&lt;font color=#800000&gt;whatever&lt;strong&gt; base1&lt;/strong&gt;&lt;/font&gt;" breaks
the perf counter! It looks like there is a &lt;strong&gt;naming convention&lt;/strong&gt; requiring
that AverageBase proformance counter has the &lt;font size=2&gt;CounterName&lt;/font&gt;&amp;nbsp;property
value on both &lt;font color=#008080&gt;CounterCreationData &lt;/font&gt;and &lt;font color=#008080 size=2&gt;PerformanceCounter &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;to
be counter name plus " base", but I never saw this mentioned anywhere - neither by
MSDN, nor by Codeproject articles. So, since average perf counters always come in
pairs, linked by name, these helpers should make creating average perf counters simpler
(uinsg C#/.NET):&lt;br&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;private&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: blue"&gt;static&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: blue"&gt;void&lt;/span&gt;&lt;font color=#000000&gt; AddAverageCounterDefinition(&lt;/font&gt;&lt;span style="COLOR: teal"&gt;CounterCreationDataCollection&lt;/span&gt;&lt;font color=#000000&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt; counters,&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&lt;font color=#000000&gt; counterName, &lt;/font&gt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&lt;font color=#000000&gt; counterDescription, &lt;/font&gt;&lt;span style="COLOR: teal"&gt;PerformanceCounterType&lt;/span&gt;&lt;font color=#000000&gt; averageType)&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;counters.Add(&lt;/font&gt;&lt;span style="COLOR: blue"&gt;new&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: teal"&gt;CounterCreationData&lt;/span&gt;&lt;font color=#000000&gt;(counterName,
counterDescription, averageType));&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;counters.Add(&lt;/font&gt;&lt;span style="COLOR: blue"&gt;new&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: teal"&gt;CounterCreationData&lt;/span&gt;&lt;font color=#000000&gt;(counterName
+ &lt;/font&gt;&lt;span style="COLOR: maroon"&gt;" base"&lt;/span&gt;&lt;font color=#000000&gt;, &lt;/font&gt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&lt;font color=#000000&gt;.Empty, &lt;/font&gt;&lt;span style="COLOR: teal"&gt;PerformanceCounterType&lt;/span&gt;&lt;font color=#000000&gt;.AverageBase));&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;
&lt;o:p&gt;
&lt;font color=#000000&gt;&amp;nbsp;&lt;/font&gt;
&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: blue"&gt;class&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: teal"&gt;AveragePerfCounter&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;private&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: teal"&gt;PerformanceCounter&lt;/span&gt;&lt;font color=#000000&gt; averageCounter;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;private&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: teal"&gt;PerformanceCounter&lt;/span&gt;&lt;font color=#000000&gt; averageCounterBase;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;
&lt;o:p&gt;
&lt;font color=#000000&gt;&amp;nbsp;&lt;/font&gt;
&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt;&lt;font color=#000000&gt; AveragePerfCounter(&lt;/font&gt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&lt;font color=#000000&gt; categoryName, &lt;/font&gt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&lt;font color=#000000&gt; counterName)&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;&lt;font color=#000000&gt;.averageCounter
= &lt;/font&gt;&lt;span style="COLOR: blue"&gt;new&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: teal"&gt;PerformanceCounter&lt;/span&gt;&lt;font color=#000000&gt;(categoryName,
counterName, &lt;/font&gt;&lt;span style="COLOR: blue"&gt;false&lt;/span&gt;&lt;font color=#000000&gt;);&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;&lt;font color=#000000&gt;.averageCounterBase
= &lt;/font&gt;&lt;span style="COLOR: blue"&gt;new&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: teal"&gt;PerformanceCounter&lt;/span&gt;&lt;font color=#000000&gt;(categoryName,
counterName + &lt;/font&gt;&lt;span style="COLOR: maroon"&gt;" base"&lt;/span&gt;&lt;font color=#000000&gt;, &lt;/font&gt;&lt;span style="COLOR: blue"&gt;false&lt;/span&gt;&lt;font color=#000000&gt;);&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;
&lt;o:p&gt;
&lt;font color=#000000&gt;&amp;nbsp;&lt;/font&gt;
&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: blue"&gt;void&lt;/span&gt;&lt;font color=#000000&gt; IncrementBy(&lt;/font&gt;&lt;span style="COLOR: blue"&gt;long&lt;/span&gt;&lt;font color=#000000&gt; val)&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;&lt;font color=#000000&gt;.averageCounter.IncrementBy(val);&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;&lt;font color=#000000&gt;.averageCounterBase.Increment();&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;o:p&gt;
&lt;font face="Times New Roman" color=#000000 size=3&gt;&amp;nbsp;&lt;/font&gt;
&lt;/o:p&gt;
&lt;/p&gt;
&lt;p&gt;
After this, when creating performance counter definition, you could use following
code instead of the one shown by the very first snippet:&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font size=2&gt;AddAverageCounterDefinition(counters, &lt;/font&gt;&lt;font color=#800000 size=2&gt;"whatever"&lt;/font&gt;&lt;font size=2&gt;, &lt;/font&gt;&lt;font color=#800000 size=2&gt;"whatever
desc"&lt;/font&gt;&lt;font size=2&gt;, &lt;/font&gt;&lt;font color=#008080 size=2&gt;PerformanceCounterType&lt;/font&gt;&lt;font size=2&gt;.AverageCount64);&lt;br&gt;
&lt;/font&gt;&lt;font size=2&gt;It will add " base" to the name of the sidekick automatically.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font size=2&gt;And to create corresponding performance counter, you now can do this:&lt;br&gt;
&lt;/font&gt;&lt;font size=2&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: teal"&gt;AveragePerfCounter&lt;/span&gt;&lt;font color=#000000&gt; avgCount
= &lt;/font&gt;&lt;span style="COLOR: blue"&gt;new&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: teal"&gt;AveragePerfCounter&lt;/span&gt;&lt;font color=#000000&gt;(&lt;/font&gt;&lt;span style="COLOR: maroon"&gt;"MyCategory"&lt;/span&gt;&lt;font color=#000000&gt;, &lt;/font&gt;&lt;span style="COLOR: maroon"&gt;"whatever"&lt;/span&gt;&lt;font color=#000000&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;avgCount.IncrementBy(&lt;/font&gt;&lt;span style="COLOR: blue"&gt;new&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: teal"&gt;Random&lt;/span&gt;&lt;font color=#000000&gt;().Next(100));&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&amp;nbsp;
&lt;/p&gt;
&gt;&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=06b316fa-fffb-484d-90e0-1c89467865af" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,06b316fa-fffb-484d-90e0-1c89467865af.aspx</comments>
      <category>.NET Programming;Performance;Software Testing;Sofware Development</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=0eb204ae-ef15-454e-abbd-58ce08753e97</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,0eb204ae-ef15-454e-abbd-58ce08753e97.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,0eb204ae-ef15-454e-abbd-58ce08753e97.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=0eb204ae-ef15-454e-abbd-58ce08753e97</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://CodePlex.com">CodePlex.com</a> - a relatively new open-source collaboration
platform from Microsoft that came to replace old and cranky GotDotNet - has impressed
me quite a lot. Of course it closely resembles <a href="http://sourceforge.net/top/mostactive.php">SourceForge.net</a>,
with the main difference of CodePlex being underpinned by Team Foundation Server (TFS)
for source control and issue tracking functionality. 
</p>
        <p>
People often don't realize that <a href="http://www.codeplex.com/CodePlex/Wiki/View.aspx?title=Obtaining%20the%20Team%20Explorer%20Client">TFS
client that integrates into Visual Studio 2005 can be downloaded</a> and is completely
free.
</p>
        <p>
I currently host a couple of projects on Codeplex:
</p>
        <ul>
          <li>
            <a href="http://www.codeplex.com/MSAjax10SetupPrereq">MS AJAX 1.0 Setup Project Prerequisite
for Visual Studio 2005</a>.<br />
It makes MS AJAX redistributable by including it into the Setup.exe bootstrapper prerequisite
manifest. The prerequisite integrates nicely with Visual Studio 2005.<br /><br /></li>
          <li>
            <a href="http://www.codeplex.com/UltiDevWebBasedMP3Pl">Simple ASP.NET 2.0/C# MP3 Player</a>.<br />
This application demonstrates a possibility of building a web application for home
users. It includes redistributable UltiDev Cassini Web Server for ASP.NET 2.0 to not
make the application dependent on the presence of IIS on users machines. The
app is AJAXed to minimize music interruptions and uses Flash player to playback
MP3 to avoid dependency on any particular media player. </li>
        </ul>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=0eb204ae-ef15-454e-abbd-58ce08753e97" />
      </body>
      <title>Open-Source And Me</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,0eb204ae-ef15-454e-abbd-58ce08753e97.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,0eb204ae-ef15-454e-abbd-58ce08753e97.aspx</link>
      <pubDate>Wed, 01 Aug 2007 15:51:18 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://CodePlex.com"&gt;CodePlex.com&lt;/a&gt; - a relatively new open-source collaboration
platform from Microsoft that came to replace old and cranky GotDotNet -&amp;nbsp;has impressed
me quite a lot. Of course it closely resembles &lt;a href="http://sourceforge.net/top/mostactive.php"&gt;SourceForge.net&lt;/a&gt;,
with the main difference of CodePlex being underpinned by Team Foundation Server (TFS)
for source control and issue tracking functionality. 
&lt;/p&gt;
&lt;p&gt;
People often don't realize that &lt;a href="http://www.codeplex.com/CodePlex/Wiki/View.aspx?title=Obtaining%20the%20Team%20Explorer%20Client"&gt;TFS
client that integrates into Visual Studio 2005 can be downloaded&lt;/a&gt; and&amp;nbsp;is completely
free.
&lt;/p&gt;
&lt;p&gt;
I currently host a couple of projects on Codeplex:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.codeplex.com/MSAjax10SetupPrereq"&gt;MS AJAX 1.0 Setup Project Prerequisite
for Visual Studio 2005&lt;/a&gt;.&lt;br&gt;
It makes MS AJAX redistributable by including it into the Setup.exe bootstrapper prerequisite
manifest. The prerequisite integrates nicely with Visual Studio 2005.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
&lt;a href="http://www.codeplex.com/UltiDevWebBasedMP3Pl"&gt;Simple ASP.NET 2.0/C# MP3 Player&lt;/a&gt;.&lt;br&gt;
This application demonstrates a possibility of building a web application for home
users. It includes redistributable UltiDev Cassini Web Server for ASP.NET 2.0 to not
make the application dependent on the presence of IIS on users machines.&amp;nbsp;The
app&amp;nbsp;is AJAXed to minimize music interruptions and uses Flash player to playback
MP3&amp;nbsp;to&amp;nbsp;avoid dependency on any particular media player.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=0eb204ae-ef15-454e-abbd-58ce08753e97" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,0eb204ae-ef15-454e-abbd-58ce08753e97.aspx</comments>
      <category>AJAX;Digital Home;Sofware Development;Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=dd75a329-1969-473a-996a-01ff9a90a84a</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,dd75a329-1969-473a-996a-01ff9a90a84a.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,dd75a329-1969-473a-996a-01ff9a90a84a.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=dd75a329-1969-473a-996a-01ff9a90a84a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
To AJAX-enable your existing ASP.NET 2.0 application follow <a href="http://www.asp.net/learn/videos/view.aspx?tabid=63&amp;id=81">this
video</a>. It takes only a few minutes and essentially makes you create a dummy new
Ajax-enabled ASP.NET application and then copy &amp; paste relevant pieces of its
web.config file into your application's web.config. 
</p>
        <p>
If you are planning to use <a href="http://www.codeplex.com/AtlasControlToolkit">Ajax
Control Toolkit</a>, then instead of creating dummy project from the "ASP.NET AJAX-Enabled
Web Site" Visual Studio project template, create the dummy project using "AJAX Control
Toolkit Web Site" template. Its web.config has additional entry in the &lt;controls&gt;
section of the web.config that will be necessary for your application.
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=dd75a329-1969-473a-996a-01ff9a90a84a" />
      </body>
      <title>Microsoft Ajax 1.0 Extensions: Converting Existing ASP.NET Application Into AJAX-Enabled One</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,dd75a329-1969-473a-996a-01ff9a90a84a.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,dd75a329-1969-473a-996a-01ff9a90a84a.aspx</link>
      <pubDate>Fri, 22 Jun 2007 17:01:40 GMT</pubDate>
      <description>&lt;p&gt;
To AJAX-enable your existing ASP.NET 2.0 application follow &lt;a href="http://www.asp.net/learn/videos/view.aspx?tabid=63&amp;amp;id=81"&gt;this
video&lt;/a&gt;. It takes only a few minutes and essentially makes you create a dummy new
Ajax-enabled ASP.NET application and then copy &amp;amp; paste relevant pieces of its
web.config file into your application's web.config. 
&lt;/p&gt;
&lt;p&gt;
If you are planning to use &lt;a href="http://www.codeplex.com/AtlasControlToolkit"&gt;Ajax
Control Toolkit&lt;/a&gt;, then instead of creating dummy project from the "ASP.NET AJAX-Enabled
Web Site" Visual Studio project template, create the dummy project using "AJAX Control
Toolkit Web Site" template. Its web.config has additional entry in the &amp;lt;controls&amp;gt;
section of the web.config that will be necessary for your application.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=dd75a329-1969-473a-996a-01ff9a90a84a" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,dd75a329-1969-473a-996a-01ff9a90a84a.aspx</comments>
      <category>AJAX;ASP.NET;Sofware Development</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=db963574-16c9-41d0-be0a-07d2b72412d3</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,db963574-16c9-41d0-be0a-07d2b72412d3.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,db963574-16c9-41d0-be0a-07d2b72412d3.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=db963574-16c9-41d0-be0a-07d2b72412d3</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Microsoft is showing off its new <a href="http://msdn2.microsoft.com/en-us/library/bb499794(VS.90).aspx">Acropolis
framework</a> for .NET. It seems to be a little more than good old CCmdTarget of late
MFC. 
</p>
        <p>
Back in 2001 when I was making a transition from C++/MFC to C#/.NET two things I missed
the most were C++ templates and CCmdTarget/Doc/View architecture of MFC-based Windows
UI. I could not believe Microsoft didn't port CCmdTarget at the time and naturally
wrote my own. But pretty soon it was obvious that with C# and Visual Studio .NET writing
ASP.NET web applications was easier than making Windows UI apps, and people
wanted web UI more than windows UI. 
</p>
        <p>
Combine dwindling demand for Windows UI with inferior development tools and you end
up in the situation where software architects don't even debate whether their
next enterprise application should have Windows UI or web UI. It's assumed and
understood that it will be a web-based application. If you think an application needs
to have Windows UI - you will face an uphill battle convincing other project stakeholders
it's the right way to go. 
</p>
        <p>
Simply put, Windows UI is so out, and web UI is so in that incremental improvements
in Windows UI world like WPF and Acropolis is too little and way too late to save
the day. We've got AJAX, thank you very much. In my arrogant opinion enterprise
apps will not go back into Windows UI world. The last bastion of Windows UI applications
is SOHO market, but that is about to change with <a href="http://www.ultidev.com/products/HttpVPN/">HttpVPN</a> making
it possible to make easily redistributable web applications for consumers and small
businesses. Once that happens, Windows UI will become just gaming and other graphics-heavy applications
platform.
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=db963574-16c9-41d0-be0a-07d2b72412d3" />
      </body>
      <title>Microsoft "Acropolis" six years too late. I liked CCmdTarget of MFC back in nineties.</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,db963574-16c9-41d0-be0a-07d2b72412d3.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,db963574-16c9-41d0-be0a-07d2b72412d3.aspx</link>
      <pubDate>Tue, 19 Jun 2007 14:42:13 GMT</pubDate>
      <description>&lt;p&gt;
Microsoft is showing off its new&amp;nbsp;&lt;a href="http://msdn2.microsoft.com/en-us/library/bb499794(VS.90).aspx"&gt;Acropolis
framework&lt;/a&gt; for .NET. It seems to be a little more than good old CCmdTarget of late
MFC.&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Back in 2001 when I was making a transition from C++/MFC to C#/.NET two things I missed
the most were C++ templates and CCmdTarget/Doc/View architecture of MFC-based Windows
UI. I could not believe Microsoft didn't port CCmdTarget at the time and naturally
wrote my own. But pretty soon it was obvious that with C# and Visual Studio .NET writing
ASP.NET&amp;nbsp;web&amp;nbsp;applications was easier than making Windows UI apps, and people
wanted web UI more than windows UI. 
&lt;/p&gt;
&lt;p&gt;
Combine dwindling demand for Windows UI with inferior development tools and you end
up in the situation where software architects don't even debate whether&amp;nbsp;their
next&amp;nbsp;enterprise application should have Windows UI or web UI. It's assumed and
understood that it will be a web-based application. If you think an application needs
to have Windows UI - you will face an uphill battle convincing other project stakeholders
it's the right way to go. 
&lt;/p&gt;
&lt;p&gt;
Simply put, Windows UI is so out, and web UI is so in that incremental improvements
in Windows UI world like WPF and Acropolis is too little and way too late to save
the day.&amp;nbsp;We've got AJAX, thank you very much. In my arrogant opinion enterprise
apps will not go back into Windows UI world. The last bastion of Windows UI applications
is SOHO market, but that is about to change with &lt;a href="http://www.ultidev.com/products/HttpVPN/"&gt;HttpVPN&lt;/a&gt; making
it possible to make easily redistributable web applications for consumers and small
businesses. Once that happens, Windows UI will become just gaming and other graphics-heavy&amp;nbsp;applications
platform.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=db963574-16c9-41d0-be0a-07d2b72412d3" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,db963574-16c9-41d0-be0a-07d2b72412d3.aspx</comments>
      <category>.NET Programming;HttpVPN;Rants;Sofware Development</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=92fb8609-995a-4c0b-bd7b-48eb8182c366</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,92fb8609-995a-4c0b-bd7b-48eb8182c366.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,92fb8609-995a-4c0b-bd7b-48eb8182c366.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=92fb8609-995a-4c0b-bd7b-48eb8182c366</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <h5>Summary
</h5>
        <p>
UPDATE: This sample is an <strong><a href="http://www.codeplex.com/UltiDevWebBasedMP3Pl">open-source
project now</a></strong>.
</p>
        <p>
This article describes how to build a redistributable ASP.NET application that allows
users browse remote server's file system and pick folders with MP3 files
to be played by embedded Macromedia Flash-based MP3 player.
</p>
        <h5>
          <br />
Article Sources
</h5>
        <p>
          <a href="http://www.codeplex.com/UltiDevWebBasedMP3Pl/Release/ProjectReleases.aspx">Download
article's C# source</a> in a form of Visual Studio 2005 Solution comprising ASP.NET
application and a Setup Project. Unzip the archive to "C:\".
</p>
        <h5>
          <br />
End Result
</h5>
        <p>
          <a href="./content/binary/UltiDevMP3Player-2.PNG">
            <img height="155" alt="UltiDevMP3Player-2-Thumbnail.PNG" src="content/binary/UltiDevMP3Player-2-Thumbnail.PNG" width="177" border="0" />
          </a>   <a href="http://vladsnotes.hrybok.com/content/binary/UltiDevMP3Player.JPG"><img src="content/binary/UltiDevMP3Player-thumbnail.PNG" border="0" /></a><br /><br />
After building the project you will have an MSI-based setup package that
can be installed on virtually any Windows-based PC. Installed application will
be accessible from inside the LAN as an intranet application without having to install
IIS.
</p>
        <h5>
          <br />
Prerequisites
</h5>
        <p>
- Visual Studio 2005.<br />
- <a href="http://ultidev.com/download/">UltiDev Cassini Web Server for ASP.NET 2.0</a>.
UltiDev Cassini is packaged together with the application into the Setup.exe
so that the final application would not depend on IIS being present on target system.
</p>
        <h5>
          <br />
Let's Begin (Getting Ducks in a Row)
</h5>
        <p>
A few weeks ago I stumbled upon a great piece of free software:<a href="http://musicplayer.sourceforge.net/">Flash-based
XSPF-compatible MP3 player</a>. When embedded on a page, it can take playlist over
HTTP and play it. Second nice thing was that XSPF play list format has <a href="http://www.xspf.org/validation/xspf-1_0.2.xsd">XSD
schema available</a>. .NET Framework <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cptools/html/cpconxmlschemadefinitiontoolxsdexe.asp">xsd.exe
utility</a> allows easy conversion of XSD schemas into C# or VB.NET classes
incapsulating the structure of the data defined by the XSD, as well as implementing
XML serialization to and from XML files conforming to the schema. So I had an XSPF-compatible
MP3 player and a free code generating XSPF-compatible XML. That meant I could easily
create XSPF-compatible playlists on a fly. Only if I had free ID3 tag (MP3
file metadata) access API...
</p>
        <p>
Finding ID3v2 library for .NET <a href="PermaLink,guid,7017a381-30b2-4a94-bcd4-ac17c799cf40.aspx">was
harder than I expected</a>. However search was ultimately successful. The <a href="http://home.fuse.net/honnert/hundred/UltraID3Lib/"><font color="#547699">UltraID3Lib</font></a> ended
up being just what I needed. It's a nice library; may be just be a bit over the top
object-oriented.
</p>
        <p>
Final piece is <a href="http://ultidev.com/products/Cassini/">UltiDev Cassini Web
Server for ASP.NET 2.0</a>. It's necessary because first, it can be packaged and shipped
along with any ASP.NET application eliminating requirement for IIS. Second, unlike
IIS UltiDev Cassini service works under "Local System" account, which enables access
to any local file and folder on the server. One thing to note, while this is
quite convenient to have a web server running under powerful account, it may pose
a risk if the application is exposed on the web. It's best to work with the application inside
protected local area network.
</p>
        <p>
After you have <a href="http://download.ultidev.com/Products/Samples/UltiDevMusicPlayerSampleSource.zip">downloaded the
solution</a>, unzip it on C:\. It will create "C:\UltiDevMusicPlayerSample" folder.
If you want to put it in some other folder - you can do that too - simply adjust
your project debugging settings later to point to the correct application folder
(see below).
</p>
        <h5>
          <br />
Application Flow
</h5>
        <p>
- Application has a single page (Default.aspx) containing the player control
and file a system browser (Controls/PlayerControl.ascx and Controls/PlayerControl.ascx.cs). 
<br />
- After user selected a folder with MP3 files, file system browser tree gets hidden
and player control is re-rendered to point to the dynamically-generated
playlist representing selected folder.<br />
- Player control requests dynamic playlist and custom IHttpHandler (AppCode/PlaylistClass.cs
and AppCode/xspf.cs) serves XSPF-encoded playlist containing songs in the selected
folder. Playlist contains song information retrieved from songs' ID3v2 and ID3v1 MP3
tags.<br />
- Player plays songs one by one: requesting each one from the custom IHttpHandler
(Handlers/Song.ashx) serving songs from local file system. After song started
playing player also requests song album artwork (cover art) from custom IHttpHandler
(Handlers/CoverArt.ashx) which serves image extracted from song's ID3v2 tag.<br /></p>
        <h5>Debugging
</h5>
        <p>
I had troubles getting Visual Studio 2005 internal web server to serve Flash
component. I switched to UltiDev Cassini for debugging and that has solved the problem.
Debugging with UltiDev Cassini is probably a good idea anyway since the application
is eventually going to run under UltiDev Cassini. 
</p>
        <p>
To switch to UltiDev Cassini, bring up ASP.NET application's properties, select Start
Options of the left, and check "Start External Program" radio-button. Enter "C:\Program
Files\UltiDev\Cassini Web Server for ASP.NET 2.0\UltiDevCassinWebServer2.exe" as the
program to be used for debugging, and specify "/run c:\UltiDevMusicPlayerSample\WebApp
Default.aspx 4125" (no quotes) as command line arguments. If you have unzipped solution
to a folder other than "C:\", then you will need to modify c:\UltiDevMusicPlayerSample\WebApp
part of the command line arguments to point to the actual application location.<br /><img height="450" alt="VS2005DebugSettingsForMP3App.PNG" src="content/binary/VS2005DebugSettingsForMP3App.PNG" width="787" border="0" /></p>
        <h5>
          <br />
Setup Project
</h5>
        <p>
Unlike regular ASP.NET application, this application is using regular (non-web) setup
project for installer implementation. The reason for that is the Visual Studio web
setup project is actually IIS setup project. Since we are using UltiDev Cassini instead
of IIS, regular setup project is required instead.
</p>
        <p>
Setup project packs UltiDev Cassini into Setup.exe bootstrapper and ensures application
is registered with UltiDev Cassini during installation process and gets unregistered
during uninstallation.
</p>
        <p>
Creating a setup project for ASP.NET application bundled with UltiDev Cassini is not
complex, but if you need step-by-step guide, please refer to this <a href="http://ultidev.com/products/Cassini/CassiniRedistirbWithVS2005.htm">walk-through</a>.<br /><br /><strong>IMPORTANT:</strong> When installing the application, don't just click the
.MSI file. You will need to <strong>run Setup.exe</strong> to ensure UltiDev Cassini
web server gets installed on target system. This is especially true on Vista, where <a href="PermaLink,guid,5bbdbe9b-ffe9-491f-bc55-c8f13b371850.aspx">clicking
.MSI and running Setup.exe are not nearly as functionally close</a> as it used to
be on Windows XP.
</p>
        <p>
Build &amp; Enjoy!
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=92fb8609-995a-4c0b-bd7b-48eb8182c366" />
      </body>
      <title>Creating Web-Based MP3 Player using ASP.NET 2.0, UltiDev Cassini Web Server and Macromedia Flash Player</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,92fb8609-995a-4c0b-bd7b-48eb8182c366.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,92fb8609-995a-4c0b-bd7b-48eb8182c366.aspx</link>
      <pubDate>Mon, 05 Mar 2007 23:30:06 GMT</pubDate>
      <description>&lt;h5&gt;Summary
&lt;/h5&gt;
&lt;p&gt;
UPDATE: This sample is an &lt;strong&gt;&lt;a href="http://www.codeplex.com/UltiDevWebBasedMP3Pl"&gt;open-source
project now&lt;/a&gt;&lt;/strong&gt;.
&lt;/p&gt;
&lt;p&gt;
This article describes how to build a redistributable ASP.NET application that allows
users browse remote server's&amp;nbsp;file system&amp;nbsp;and pick folders with MP3 files
to be played by embedded Macromedia Flash-based MP3 player.
&lt;/p&gt;
&lt;h5&gt;
&lt;br&gt;
Article Sources
&lt;/h5&gt;
&lt;p&gt;
&lt;a href="http://www.codeplex.com/UltiDevWebBasedMP3Pl/Release/ProjectReleases.aspx"&gt;Download
article's C# source&lt;/a&gt; in a form of Visual Studio 2005 Solution comprising ASP.NET
application and a Setup Project. Unzip the archive to "C:\".
&lt;/p&gt;
&lt;h5&gt;
&lt;br&gt;
End Result
&lt;/h5&gt;
&lt;p&gt;
&lt;a href="./content/binary/UltiDevMP3Player-2.PNG"&gt;&lt;img height=155 alt=UltiDevMP3Player-2-Thumbnail.PNG src="content/binary/UltiDevMP3Player-2-Thumbnail.PNG" width=177 border=0&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp; &lt;a href="http://vladsnotes.hrybok.com/content/binary/UltiDevMP3Player.JPG"&gt;&lt;img src="content/binary/UltiDevMP3Player-thumbnail.PNG" border=0&gt;&lt;/a&gt;
&lt;br&gt;
&lt;br&gt;
After&amp;nbsp;building the project&amp;nbsp;you will have&amp;nbsp;an MSI-based&amp;nbsp;setup package&amp;nbsp;that
can be installed on virtually any Windows-based PC.&amp;nbsp;Installed application will
be accessible from&amp;nbsp;inside the LAN as an intranet application without having to&amp;nbsp;install
IIS.
&lt;/p&gt;
&lt;h5&gt;
&lt;br&gt;
Prerequisites
&lt;/h5&gt;
&lt;p&gt;
- Visual Studio 2005.&lt;br&gt;
- &lt;a href="http://ultidev.com/download/"&gt;UltiDev Cassini Web Server for ASP.NET 2.0&lt;/a&gt;.
UltiDev Cassini is&amp;nbsp;packaged together with the application into the Setup.exe
so that the final application would not depend on IIS being present on target system.
&lt;/p&gt;
&lt;h5&gt;
&lt;br&gt;
Let's Begin (Getting Ducks in&amp;nbsp;a Row)
&lt;/h5&gt;
&lt;p&gt;
A few weeks ago I stumbled upon a great piece of free software:&lt;a href="http://musicplayer.sourceforge.net/"&gt;Flash-based
XSPF-compatible MP3 player&lt;/a&gt;. When embedded on a page, it can take playlist over
HTTP and play it. Second nice thing was that XSPF play list format has &lt;a href="http://www.xspf.org/validation/xspf-1_0.2.xsd"&gt;XSD
schema available&lt;/a&gt;. .NET Framework&amp;nbsp;&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cptools/html/cpconxmlschemadefinitiontoolxsdexe.asp"&gt;xsd.exe
utility&lt;/a&gt; allows easy conversion of XSD&amp;nbsp;schemas&amp;nbsp;into C# or VB.NET classes
incapsulating the structure of the data defined by&amp;nbsp;the XSD, as well as implementing
XML serialization to and from XML files conforming to the schema. So I had an XSPF-compatible
MP3 player and a free code generating XSPF-compatible XML. That meant I could easily
create XSPF-compatible playlists on a fly. Only if I had free&amp;nbsp;ID3 tag&amp;nbsp;(MP3
file metadata)&amp;nbsp;access&amp;nbsp;API...
&lt;/p&gt;
&lt;p&gt;
Finding ID3v2 library for .NET &lt;a href="PermaLink,guid,7017a381-30b2-4a94-bcd4-ac17c799cf40.aspx"&gt;was
harder than I expected&lt;/a&gt;. However search was ultimately successful. The &lt;a href="http://home.fuse.net/honnert/hundred/UltraID3Lib/"&gt;&lt;font color=#547699&gt;UltraID3Lib&lt;/font&gt;&lt;/a&gt;&amp;nbsp;ended
up being just what I needed. It's a nice library; may be just be a bit over the top
object-oriented.
&lt;/p&gt;
&lt;p&gt;
Final piece is &lt;a href="http://ultidev.com/products/Cassini/"&gt;UltiDev Cassini Web
Server for ASP.NET 2.0&lt;/a&gt;. It's necessary because first, it can be packaged and shipped
along with any ASP.NET application eliminating requirement for IIS. Second, unlike
IIS UltiDev Cassini service works under "Local System" account, which enables access
to any local file and folder on the server.&amp;nbsp;One thing to note, while this is
quite convenient to have a web server running under powerful account, it may pose
a risk if the application is exposed on the web. It's best to work with the application&amp;nbsp;inside
protected local area network.
&lt;/p&gt;
&lt;p&gt;
After you have &lt;a href="http://download.ultidev.com/Products/Samples/UltiDevMusicPlayerSampleSource.zip"&gt;downloaded&amp;nbsp;the
solution&lt;/a&gt;, unzip it on C:\. It will create "C:\UltiDevMusicPlayerSample" folder.
If you want to put it in some other folder - you can do that too -&amp;nbsp;simply adjust
your&amp;nbsp;project debugging settings later to point to the correct application folder
(see below).
&lt;/p&gt;
&lt;h5&gt;
&lt;br&gt;
Application Flow
&lt;/h5&gt;
&lt;p&gt;
- Application&amp;nbsp;has a single page (Default.aspx)&amp;nbsp;containing the player control
and&amp;nbsp;file a system browser (Controls/PlayerControl.ascx and Controls/PlayerControl.ascx.cs). 
&lt;br&gt;
- After user selected a folder with MP3 files, file system browser tree gets hidden
and&amp;nbsp;player control&amp;nbsp;is re-rendered to point to the dynamically-generated
playlist representing selected folder.&lt;br&gt;
- Player control requests dynamic playlist and custom IHttpHandler (AppCode/PlaylistClass.cs
and AppCode/xspf.cs)&amp;nbsp;serves XSPF-encoded playlist containing songs in the selected
folder. Playlist contains song information retrieved from songs' ID3v2 and ID3v1 MP3
tags.&lt;br&gt;
- Player plays songs one by one: requesting each one from the custom IHttpHandler
(Handlers/Song.ashx)&amp;nbsp;serving songs from local file system. After song started
playing player also requests song album artwork (cover art) from custom IHttpHandler
(Handlers/CoverArt.ashx)&amp;nbsp;which serves image extracted from song's ID3v2 tag.&lt;br&gt;
&lt;/p&gt;
&lt;h5&gt;Debugging
&lt;/h5&gt;
&lt;p&gt;
I had troubles&amp;nbsp;getting Visual Studio 2005 internal web server to serve Flash
component. I switched to UltiDev Cassini for debugging and that has solved the problem.
Debugging with UltiDev Cassini is probably a good idea anyway since the application
is eventually going to run&amp;nbsp;under UltiDev Cassini. 
&lt;/p&gt;
&lt;p&gt;
To switch to UltiDev Cassini, bring up ASP.NET application's properties, select Start
Options of the left, and check "Start External Program" radio-button. Enter "C:\Program
Files\UltiDev\Cassini Web Server for ASP.NET 2.0\UltiDevCassinWebServer2.exe" as the
program to be&amp;nbsp;used for debugging, and specify "/run c:\UltiDevMusicPlayerSample\WebApp
Default.aspx 4125" (no quotes) as command line arguments. If you have unzipped solution
to a folder other than "C:\", then you will need to modify c:\UltiDevMusicPlayerSample\WebApp
part of the command line arguments to point to the actual application location.&lt;br&gt;
&lt;img height=450 alt=VS2005DebugSettingsForMP3App.PNG src="content/binary/VS2005DebugSettingsForMP3App.PNG" width=787 border=0&gt;
&lt;/p&gt;
&lt;h5&gt;
&lt;br&gt;
Setup Project
&lt;/h5&gt;
&lt;p&gt;
Unlike regular ASP.NET application, this application is using regular (non-web) setup
project for installer implementation. The reason for that is the Visual Studio web
setup project is actually IIS setup project. Since we are using UltiDev Cassini instead
of IIS, regular setup project is required instead.
&lt;/p&gt;
&lt;p&gt;
Setup project packs UltiDev Cassini into Setup.exe bootstrapper and ensures application
is registered with UltiDev Cassini during installation process and gets unregistered
during uninstallation.
&lt;/p&gt;
&lt;p&gt;
Creating a setup project for ASP.NET application bundled with UltiDev Cassini is not
complex, but if you need step-by-step guide, please refer to this &lt;a href="http://ultidev.com/products/Cassini/CassiniRedistirbWithVS2005.htm"&gt;walk-through&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;
&lt;strong&gt;IMPORTANT:&lt;/strong&gt; When installing the application, don't just click the
.MSI file. You will need to &lt;strong&gt;run Setup.exe&lt;/strong&gt; to ensure UltiDev Cassini
web server gets installed on target system. This is especially true on Vista, where &lt;a href="PermaLink,guid,5bbdbe9b-ffe9-491f-bc55-c8f13b371850.aspx"&gt;clicking
.MSI and running Setup.exe are not nearly as functionally close&lt;/a&gt; as it used to
be on Windows XP.
&lt;/p&gt;
&lt;p&gt;
Build &amp;amp; Enjoy!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=92fb8609-995a-4c0b-bd7b-48eb8182c366" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,92fb8609-995a-4c0b-bd7b-48eb8182c366.aspx</comments>
      <category>ASP.NET;Cassini Web Server;Digital Home;Sofware Development</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=2884fdba-57bb-4c69-b5ff-06b1e4e9c2d8</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,2884fdba-57bb-4c69-b5ff-06b1e4e9c2d8.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,2884fdba-57bb-4c69-b5ff-06b1e4e9c2d8.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=2884fdba-57bb-4c69-b5ff-06b1e4e9c2d8</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Recently I've been working on the small ASP.NET 2.0 app that has a page containing
Macromedia (now Adobe) Flash object. When I tried debugging it with Visual Studio
2005 and its internal web server, the Flash piece has never been loaded by Internet
Explorer - I am not even sure whether it was the Flash player that failed to load
or the .SWF file. I wonder if anyone else had this issue. I could not check which
component was not loaded because WebDev.WebServer2.exe serves only local applications,
and I could not use an http tracer to see which request gets stuck.
</p>
        <p>
I worked around the issue by switching to our own <a href="http://ultidev.com/products/Cassini/index.htm">UltiDev
Cassini for ASP.NET 2.0</a> for <a href="http://ultidev.com/products/Cassini/CassiniDevGuide.htm#Debugging">application
debugging</a>. It served all the bits and pieces required by Flash without
a hitch.
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=2884fdba-57bb-4c69-b5ff-06b1e4e9c2d8" />
      </body>
      <title>Problem with Macromedia (Adobe) Flash Object on the ASP.NET Page Served by Visual Studio 2005 WebDev.WebServer2.exe</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,2884fdba-57bb-4c69-b5ff-06b1e4e9c2d8.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,2884fdba-57bb-4c69-b5ff-06b1e4e9c2d8.aspx</link>
      <pubDate>Mon, 05 Mar 2007 21:22:37 GMT</pubDate>
      <description>&lt;p&gt;
Recently I've been working on the small ASP.NET 2.0 app that has a page containing
Macromedia (now Adobe) Flash object. When I tried debugging it with Visual Studio
2005 and its internal web server, the Flash piece&amp;nbsp;has never been loaded by Internet
Explorer - I am not even sure whether it was the Flash player that failed to load
or the .SWF file. I wonder if anyone else had this issue. I could&amp;nbsp;not check which
component was not loaded because WebDev.WebServer2.exe serves only local applications,
and I could not use&amp;nbsp;an http tracer&amp;nbsp;to see which request gets stuck.
&lt;/p&gt;
&lt;p&gt;
I worked around&amp;nbsp;the issue by&amp;nbsp;switching to&amp;nbsp;our own &lt;a href="http://ultidev.com/products/Cassini/index.htm"&gt;UltiDev
Cassini for ASP.NET 2.0&lt;/a&gt; for &lt;a href="http://ultidev.com/products/Cassini/CassiniDevGuide.htm#Debugging"&gt;application
debugging&lt;/a&gt;. It served all the bits and pieces&amp;nbsp;required by&amp;nbsp;Flash without
a hitch.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=2884fdba-57bb-4c69-b5ff-06b1e4e9c2d8" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,2884fdba-57bb-4c69-b5ff-06b1e4e9c2d8.aspx</comments>
      <category>ASP.NET;Cassini Web Server;IIS7;Sofware Development;Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=7017a381-30b2-4a94-bcd4-ac17c799cf40</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,7017a381-30b2-4a94-bcd4-ac17c799cf40.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,7017a381-30b2-4a94-bcd4-ac17c799cf40.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=7017a381-30b2-4a94-bcd4-ac17c799cf40</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In attempt to create a less dry than your usual "Hello World" ASP.NET application
to showcase <a href="http://ultidev.com/Products/Cassini/">UltiDev Cassini Web
Server</a>, I decided to write a simple web-based MP3 player application using
Maсromedia (now Adobe) Flash. I was very surprised by how long and frustrating
was my search for a free .NET-based API allowing programmatic access to ID3 tags in
MP3 files from C# and VB.NET. I started working with something I found on Codeproject.com,
but that piece turned out to be buggy beyond any degree of practicality. My second
sweep across Internet yielded a much better (if only somewhat over-engineered) solution
- the <a href="http://home.fuse.net/honnert/hundred/UltraID3Lib/">UltraID3Lib</a>.
Its <strong>UltraID3</strong> class is the starting point of the journey. The library
worked out for me very well. Thumbs up.
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=7017a381-30b2-4a94-bcd4-ac17c799cf40" />
      </body>
      <title>.NET API for Programmatic MP3 Tag (ID3v1 and ID3v2) Access and Modifications</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,7017a381-30b2-4a94-bcd4-ac17c799cf40.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,7017a381-30b2-4a94-bcd4-ac17c799cf40.aspx</link>
      <pubDate>Wed, 28 Feb 2007 04:37:38 GMT</pubDate>
      <description>&lt;p&gt;
In attempt&amp;nbsp;to create a less dry than your usual "Hello World" ASP.NET application
to&amp;nbsp;showcase &lt;a href="http://ultidev.com/Products/Cassini/"&gt;UltiDev Cassini Web
Server&lt;/a&gt;, I decided to write a simple web-based&amp;nbsp;MP3 player application using
Maсromedia (now Adobe)&amp;nbsp;Flash. I was very surprised by how long and frustrating
was my search for a free .NET-based API allowing programmatic access to ID3 tags in
MP3 files from C# and VB.NET. I started working with something I found on Codeproject.com,
but that piece turned out to be buggy beyond any degree of practicality. My second
sweep across Internet yielded a much better (if only somewhat over-engineered)&amp;nbsp;solution
- the &lt;a href="http://home.fuse.net/honnert/hundred/UltraID3Lib/"&gt;UltraID3Lib&lt;/a&gt;.
Its &lt;strong&gt;UltraID3&lt;/strong&gt; class is the starting point of the journey. The library
worked out for me very well. Thumbs up.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=7017a381-30b2-4a94-bcd4-ac17c799cf40" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,7017a381-30b2-4a94-bcd4-ac17c799cf40.aspx</comments>
      <category>.NET Programming;ASP.NET 1.1;Cassini Web Server;Sofware Development</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=2f30cf45-e636-471f-bf91-6f5a9d8efcae</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,2f30cf45-e636-471f-bf91-6f5a9d8efcae.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,2f30cf45-e636-471f-bf91-6f5a9d8efcae.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=2f30cf45-e636-471f-bf91-6f5a9d8efcae</wfw:commentRss>
      <title>Software platform evolution: from desktop OSes to World Wide Web to UltiDev HttpVPN</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,2f30cf45-e636-471f-bf91-6f5a9d8efcae.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,2f30cf45-e636-471f-bf91-6f5a9d8efcae.aspx</link>
      <pubDate>Mon, 12 Feb 2007 03:27:32 GMT</pubDate>
      <description>&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;b&gt;&lt;span style="FONT-SIZE: 11pt; COLOR: rgb(31,73,125); FONT-FAMILY: 'Calibri','sans-serif'"&gt;Think
what would happen if Microsoft was giving away Windows for free to everyone, and would
also be giving away Visual Studio to developers, but taking %% of every sale of every
program ever made for MS Windows&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 11pt; COLOR: rgb(31,73,125); FONT-FAMILY: 'Calibri','sans-serif'"&gt;.
Think of how much more money would they would have made? Could Bill Gates&amp;nbsp;have
become &amp;nbsp;a first trillionaire?&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="FONT-SIZE: 11pt; COLOR: rgb(31,73,125); FONT-FAMILY: 'Calibri','sans-serif'"&gt;&lt;?xml:namespace prefix = o /&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="FONT-SIZE: 11pt; COLOR: rgb(31,73,125); FONT-FAMILY: 'Calibri','sans-serif'"&gt;First
of all, no worries, I am not a nut who writes another OS.&amp;nbsp;Creating a new operating
system&amp;nbsp;is WAY too complicated, costly and most importantly financially risky:
OSes are commodity - it's impossible to change the world by creating another OS now.&lt;span&gt;&amp;nbsp; &lt;/span&gt;Instead,
I am creating a new &lt;b&gt;platform&lt;/b&gt;. What is platform? To give a definition, &lt;em&gt;platform
is an operating environment for programs, and a user interface conduit for users&lt;/em&gt;.
To give a few examples: Internet is platform: back-end web server is an operating
environment for programs and browser is a conduit for the UI; every operating system
is a platform: Windows, Linux, MacOS – their APIs and drivers form an operating environment
and OS desktop and windows is a UI conduit; web browser is a platform too, albeit
a limited one&amp;nbsp;– it can run client scripts and therefore it’s an operating environment
and a UI conduit at the same time. You get the idea… &lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="FONT-SIZE: 11pt; COLOR: rgb(31,73,125); FONT-FAMILY: 'Calibri','sans-serif'"&gt;&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="FONT-SIZE: 11pt; COLOR: rgb(31,73,125); FONT-FAMILY: 'Calibri','sans-serif'"&gt;Platforms
differ in reach and complexity. Operating systems make a&amp;nbsp;somewhat mediocre platform:
they have limited reach – contained by the hardware they designed for,&amp;nbsp;by&amp;nbsp;how
incredibly expensive it is to make an OS, and by how hard it's to learn to develop
applications for a new OS. Adoption threshold for a new OS is very high. Web, on&amp;nbsp;the
other hand,&amp;nbsp;is a very good platform: HTTP protocol is insanely simple, web development
is relative simple and mastered by ever-growing legions of developers, web is not
constrained by hardware, and finally web has a virtually unlimited reach. Curiously,
web as a platform is built on top of other platforms - underlying disparate OSes&amp;nbsp;running
web server back-end software and user browsers.&amp;nbsp;it’s a platform layered on top
of other platforms – OSes. &lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="FONT-SIZE: 11pt; COLOR: rgb(31,73,125); FONT-FAMILY: 'Calibri','sans-serif'"&gt;&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="FONT-SIZE: 11pt; COLOR: rgb(31,73,125); FONT-FAMILY: 'Calibri','sans-serif'"&gt;The
drawbacks of the Web as a platform include: &lt;/span&gt;
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;div class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-SIZE: 11pt; COLOR: rgb(31,73,125); FONT-FAMILY: 'Calibri','sans-serif'"&gt;&lt;b&gt;Deploying
and operating web apps is complex and costly&lt;/b&gt;. It is very hard to make an application
accessible on the web: all the routers, firewalls, networking, DNS servers, domain
names leases,&amp;nbsp;IP addresses -&amp;nbsp; everything involved in deployment of a web
application is much more complex from user’s standpoint compared to regular program
with a "pop-in a CD and have it installed" type of deployment; 
&lt;br&gt;
&lt;br&gt;
&lt;/span&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;span style="FONT-SIZE: 11pt; COLOR: rgb(31,73,125); FONT-FAMILY: 'Calibri','sans-serif'"&gt;&lt;b&gt;Web
applications are hard to market&lt;/b&gt;. From developers’ perspective business models
for selling web app&amp;nbsp;is limited to big-ticket sales to businesses who have budget
and skills necessary to run web-facing infrastructure. 
&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="FONT-SIZE: 11pt; COLOR: rgb(31,73,125); FONT-FAMILY: 'Calibri','sans-serif'"&gt;Now,
imagine World Wide Web&amp;nbsp;with above-mentioned&amp;nbsp;problems removed. That is what
I am doing: &lt;b&gt;a new web-based platform that has user reach as wide&amp;nbsp;as current
Internet, but removes application deployment and marketing hurdles&lt;/b&gt; that are limiting
web application usage right now. That’s a unique innovation right there. “But hey,
there’s more!” Another unique innovation is the business model: I am not going to
sell this platform to users, or development tools to developers. All will get it for
free. The catch? All software that uses our platform can only be sold and bought using
channels belonging and controlled by UltiDev, and&amp;nbsp;like eBay we are going to take&amp;nbsp;%%
of every application sale. &lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="FONT-SIZE: 11pt; COLOR: rgb(31,73,125); FONT-FAMILY: 'Calibri','sans-serif'"&gt;
&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="FONT-SIZE: 11pt; COLOR: rgb(31,73,125); FONT-FAMILY: 'Calibri','sans-serif'"&gt;You
may have some concerns, like will developers find this new platform attractive enough
to spend effort learning it and making programs for it? The answer is no, they won’t.
Because they won’t need to. The beauty of it is that application developers can take
their existing skills and even their already-built applications and simply package
them together with our new platform components and ship it to users. Every member
of millions-strong army of web developers worldwide is ready to take advantage of
this new platform. &lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="FONT-SIZE: 11pt; COLOR: rgb(31,73,125); FONT-FAMILY: 'Calibri','sans-serif'"&gt;You
may also wonder how complex is this new platform? Will it take billions of dollars
an decades to create it? Well, it’s complex enough to take two years to develop, but
the good news is that it’s virtually finished and working pre-alpha releases are deployed.&amp;nbsp;&lt;/span&gt;&lt;span style="FONT-SIZE: 11pt; COLOR: rgb(31,73,125); FONT-FAMILY: 'Calibri','sans-serif'"&gt; 
&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11pt; COLOR: rgb(31,73,125); FONT-FAMILY: 'Calibri','sans-serif'"&gt;Small
detail: the platform described above is called &lt;b&gt;HttpVPN™&lt;/b&gt; and some additional
technical information is available at &lt;a href="http://ultidev.com/Products/httpVPN/"&gt;http://ultidev.com/Products/httpVPN/&lt;/a&gt;. &lt;/span&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=2f30cf45-e636-471f-bf91-6f5a9d8efcae" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,2f30cf45-e636-471f-bf91-6f5a9d8efcae.aspx</comments>
      <category>Digital Home;HttpVPN;Rants;Sofware Development</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=33e12a70-d0f9-4a79-9e97-ffbcd60f9d53</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,33e12a70-d0f9-4a79-9e97-ffbcd60f9d53.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,33e12a70-d0f9-4a79-9e97-ffbcd60f9d53.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=33e12a70-d0f9-4a79-9e97-ffbcd60f9d53</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
All! If you use Visual Studio 2003 or 2005 to create MSI-based setup packages, here's
a good one for you: if your installation uses Uninstall and Install/Commit custom
actions implemented as an installer class - you are in trouble. In the process of
upgrading your product MSIEXEC.exe first loads an assembly with Uninstall custom
action implementation - to complete previous version uninstallation. After that
it tries to load installer class of the new version to do Install and/or Commit
custom actions of the new version. At this point things can get really bad. If
your custom action assembly is not signed/strongly named (and in my experience
sometimes even if it is signed) MSIEXEC.EXE will fail to load custom action
assembly from the new version and will run Install/Commit custom steps from the old
one. This means that if you added new code to your Install/Commit steps it simply
won't be executed during upgrade. Even worse: Install/Commit custom actions of the
old version will run instead of the new one!
</p>
        <p>
This happens due to completely bizarre, to put it mildly, logic of .NET Assembly.LoadFrom()
method. .NET Framework has a rule that after assembly is loaded it can't be unloaded
unless it was loaded into a separate AppDomain: appdomains can be unloaded and assemblies
can't. Two assemblies may end up looking the same to LoadFrom() if they have the same
name even if they are located in different folders or have different versions. So
what happens here is this: after MSIEXEC.exe loaded assembly named 'X' to do
Uninstall custom step, the subsequent attempt to load assembly named also 'X' from
another folder to do Install/Commit step does not happen. But get this: one would
expect that if you asked LoadFrom() to load assembly 'X' from folder 'Y' it should
either load it or tell you it can't. Instead due to some truly twisted logic, LoadFrom()
won't fail if it can't load new 'X' assembly - it will simply return the reference
to the one that is already loaded. So much for solving DLL hell problem! 
</p>
        <p>
Microsoft knows about the problem since 2004<br /><a href="http://support.microsoft.com/kb/555184/">http://support.microsoft.com/kb/555184/</a><br /><br />
It didn't, however, fix it yet:<br /><a href="http://support.microsoft.com/kb/906766">http://support.microsoft.com/kb/906766</a></p>
        <p>
They recommend giving unique names to custom action assemblies for
each new release. Alternatively they say signing an assembly will make problem go
away. I tried signing and in my small test project it made problem go away, but not
in the "real" one. I am stuck with having to rename custom action installer assemblies
for each release. All Microsoft needed to do is this: force installer to create new
appdomain and load old version's Uninstall custom steps assembly there and let it
run. After it's done, unload the appdomain and create the new one where
you load new version's custom action assembly with Install step implementation. That
would make it unnecessary to give assemblies unique names - strong or physical. My
understanding is that Visual Studio adds a small shim DLL to the MSI
package that loads .NET installer classes from the custom action assemblies. This
means they don't even need to wait for another MSI API release to fix it - every
new Visual Studio or a even a Service Pack for Visual Studio could have fixed the
issue that is still with us more than three years later.
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=33e12a70-d0f9-4a79-9e97-ffbcd60f9d53" />
      </body>
      <title>MSI-based setup packages custom actions made in Visual Studio may not work correctly in upgrade mode</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,33e12a70-d0f9-4a79-9e97-ffbcd60f9d53.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,33e12a70-d0f9-4a79-9e97-ffbcd60f9d53.aspx</link>
      <pubDate>Fri, 09 Feb 2007 04:42:07 GMT</pubDate>
      <description>&lt;p&gt;
All! If you use Visual Studio 2003 or 2005 to create MSI-based setup packages, here's
a good one for you: if your installation uses Uninstall and Install/Commit custom
actions implemented as an installer class - you are in trouble. In the process of
upgrading your product&amp;nbsp;MSIEXEC.exe first loads an assembly with Uninstall custom
action implementation - to&amp;nbsp;complete previous version uninstallation. After that
it tries to load installer class of&amp;nbsp;the new version to do Install and/or Commit
custom actions of the new version.&amp;nbsp;At this point things can get really bad. If
your custom action&amp;nbsp;assembly is not signed/strongly named (and in my experience
sometimes even if&amp;nbsp;it is&amp;nbsp;signed) MSIEXEC.EXE will fail to load custom action
assembly from the new version and will run Install/Commit custom steps from the old
one. This means that if you added new code to your Install/Commit steps it simply
won't be executed during upgrade. Even worse: Install/Commit custom actions of the
old version will run instead of the new one!
&lt;/p&gt;
&lt;p&gt;
This happens due to completely bizarre, to put it mildly, logic of .NET Assembly.LoadFrom()
method. .NET Framework has a rule that after assembly is loaded it can't be unloaded
unless it was loaded into a separate AppDomain: appdomains can be unloaded and assemblies
can't. Two assemblies may end up looking the same to LoadFrom() if they have the same
name even if they are located in different folders or have different versions. So
what happens here&amp;nbsp;is this: after MSIEXEC.exe loaded assembly named 'X' to do
Uninstall custom step, the subsequent attempt to load assembly named also 'X' from
another folder to do Install/Commit step does not happen. But get this: one would
expect that if you asked LoadFrom() to load assembly 'X' from folder 'Y' it should
either load it or tell you it can't. Instead due to some truly twisted logic, LoadFrom()
won't fail if it can't load new 'X' assembly - it will simply return the reference
to the one that is already loaded. So much for solving DLL hell problem! 
&lt;/p&gt;
&lt;p&gt;
Microsoft knows about the problem since 2004&lt;br&gt;
&lt;a href="http://support.microsoft.com/kb/555184/"&gt;http://support.microsoft.com/kb/555184/&lt;/a&gt;
&lt;br&gt;
&lt;br&gt;
It didn't, however, fix it yet:&lt;br&gt;
&lt;a href="http://support.microsoft.com/kb/906766"&gt;http://support.microsoft.com/kb/906766&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
They recommend&amp;nbsp;giving&amp;nbsp;unique names to&amp;nbsp;custom action assemblies for
each new release. Alternatively they say signing an assembly will make problem go
away. I tried signing and in my small test project it made problem go away, but not
in the "real" one.&amp;nbsp;I am stuck with having to rename custom action installer&amp;nbsp;assemblies
for each release. All Microsoft needed to do is this: force installer to create new
appdomain and load old version's Uninstall custom steps assembly there and let it
run. After it's done, unload the appdomain and create&amp;nbsp;the new&amp;nbsp;one where
you load new version's custom action assembly with Install step implementation. That
would make it unnecessary to give assemblies unique names - strong or physical. My
understanding is that&amp;nbsp;Visual Studio&amp;nbsp;adds a small shim&amp;nbsp;DLL to the MSI
package that loads .NET installer classes from the custom action assemblies. This
means they don't even need to wait for another MSI API release to fix it -&amp;nbsp;every
new Visual Studio or a even a Service Pack for Visual Studio could have fixed the
issue that is still with us more than three years later.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=33e12a70-d0f9-4a79-9e97-ffbcd60f9d53" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,33e12a70-d0f9-4a79-9e97-ffbcd60f9d53.aspx</comments>
      <category>.NET Programming;MSI;Sofware Development;Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=5bbdbe9b-ffe9-491f-bc55-c8f13b371850</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,5bbdbe9b-ffe9-491f-bc55-c8f13b371850.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,5bbdbe9b-ffe9-491f-bc55-c8f13b371850.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=5bbdbe9b-ffe9-491f-bc55-c8f13b371850</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In Windows XP one could just double-click an .MSI (Windows Installer) file to start
package installation: MSIEXEC.exe is associated with the .MSI extension and if
user had administrator rights installation would go forward. Clicking
.MSI file was functionally identical to running Setup.exe bootstrapper, provided
Setup.exe didn't have additional functions other than starting the installation.
</p>
        <p>
In Windows Vista things are different. When Vista's User Account Control (UAC) is
turned on, launching Setup.exe is not quite the same as running MSIEXEC.EXE /i mypackage.msi.
The difference is that when Setup.exe is started, Vista runs it in "elevated" mode,
which gives the process more privileges. MSIEXEC.EXE does not seem to run in
elevated mode and therefore behavior of the installation may be different.
</p>
        <p>
The issue seems to be manifesting itself most often when an MSI setup package
made using Visual Studio executes custom action steps implemented as an Installer
class. I am not sure what exactly happens but I noticed that MSI error 2689, which is
a common result of failed custom action, will go away if installation initiated using
Setup.exe instead of just clicking on .MSI file.
</p>
        <p>
Bottom line: <strong>On Vista always start installations by launching Setup.exe instead
of double-clicking .MSI file.</strong></p>
        <p>
Another possibility to consider: if you were not a victim of computer virus attack
in the last five years (Windows XP lifetime), then you are may want to simply <a href="PermaLink,guid,1848ad7f-a40b-421e-bde0-f106e0bbae10.aspx">turn
Vista UAC off</a>.
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=5bbdbe9b-ffe9-491f-bc55-c8f13b371850" />
      </body>
      <title>Running MSI is not the same as running Setup.exe on Vista with UAC turned on.</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,5bbdbe9b-ffe9-491f-bc55-c8f13b371850.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,5bbdbe9b-ffe9-491f-bc55-c8f13b371850.aspx</link>
      <pubDate>Tue, 06 Feb 2007 05:33:43 GMT</pubDate>
      <description>&lt;p&gt;
In Windows XP one could just double-click an .MSI (Windows Installer) file to start
package installation: MSIEXEC.exe&amp;nbsp;is associated with the .MSI extension and if
user&amp;nbsp;had&amp;nbsp;administrator rights installation would go&amp;nbsp;forward.&amp;nbsp;Clicking
.MSI file&amp;nbsp;was functionally identical to running Setup.exe bootstrapper, provided
Setup.exe didn't have additional functions other than starting the installation.
&lt;/p&gt;
&lt;p&gt;
In Windows Vista things are different. When Vista's User Account Control (UAC) is
turned on, launching Setup.exe is not quite the same as running MSIEXEC.EXE /i mypackage.msi.
The difference is that when Setup.exe is started, Vista runs it in "elevated" mode,
which gives the process&amp;nbsp;more privileges. MSIEXEC.EXE does not seem to run in
elevated mode and therefore behavior of the installation may be different.
&lt;/p&gt;
&lt;p&gt;
The issue seems to be manifesting itself most often when an MSI&amp;nbsp;setup package
made using Visual Studio executes custom action steps implemented as an Installer
class. I am not sure what exactly happens but I noticed that MSI error 2689, which&amp;nbsp;is
a common result of failed custom action, will go away if installation initiated using
Setup.exe instead of just clicking on .MSI file.
&lt;/p&gt;
&lt;p&gt;
Bottom line: &lt;strong&gt;On Vista always start installations by launching Setup.exe instead
of double-clicking .MSI file.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Another possibility to consider: if you were not a victim of computer virus attack
in the last five years (Windows XP lifetime), then you are may want to simply &lt;a href="PermaLink,guid,1848ad7f-a40b-421e-bde0-f106e0bbae10.aspx"&gt;turn
Vista UAC off&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=5bbdbe9b-ffe9-491f-bc55-c8f13b371850" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,5bbdbe9b-ffe9-491f-bc55-c8f13b371850.aspx</comments>
      <category>MSI;Security;Sofware Development;Vista</category>
    </item>
  </channel>
</rss>