<?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 - Visual Studio</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, 28 Jun 2009 21:04:41 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=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=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=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=3a9e12fb-b961-43dd-a719-adbf1d5c3fad</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,3a9e12fb-b961-43dd-a719-adbf1d5c3fad.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,3a9e12fb-b961-43dd-a719-adbf1d5c3fad.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=3a9e12fb-b961-43dd-a719-adbf1d5c3fad</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I went through the exercise of setting up Microsoft Team Foundation Server 2008, and
needed to do group-level-only rights assignment, so that IT folks could manage security
by simply moving people in and out of the Active Directory groups to grant/revoke
TFS access rights, instead of setting up individual user rights in TFS, Windows Sharepoint
Services and Reporting Services. Initially I created some groups for TFS with
the "Domain local" scope, which allowed me to nest other, "Global", groups
in them. But I noticed that with WSS and RS, assigning rights to "Domain local" groups
does nothing - WSS and RS act as users are not members of the group, while TFS services
were working properly. I had to <strong>re-create AD groups and make them of "Global"
scope</strong> to make WSS and RS working properly.
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=3a9e12fb-b961-43dd-a719-adbf1d5c3fad" />
      </body>
      <title>AD Groups Must Have "Global" Scope to be handled properly by WSS and Reporting Services in TFS</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,3a9e12fb-b961-43dd-a719-adbf1d5c3fad.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,3a9e12fb-b961-43dd-a719-adbf1d5c3fad.aspx</link>
      <pubDate>Fri, 11 Jul 2008 21:22:14 GMT</pubDate>
      <description>&lt;p&gt;
I went through the exercise of setting up Microsoft Team Foundation Server 2008, and
needed to do group-level-only rights assignment, so that IT folks could manage security
by simply moving people in and out of the Active Directory groups to grant/revoke
TFS access rights, instead of setting up individual user rights in TFS, Windows Sharepoint
Services and Reporting Services. Initially I created some groups for TFS&amp;nbsp;with
the&amp;nbsp;"Domain local" scope, which allowed me to nest other, "Global",&amp;nbsp;groups
in them. But I noticed that with WSS and RS, assigning rights to "Domain local" groups
does nothing - WSS and RS act as users are not members of the group, while TFS services
were working properly. I had to &lt;strong&gt;re-create AD groups and make them of "Global"
scope&lt;/strong&gt; to make WSS and RS working properly.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=3a9e12fb-b961-43dd-a719-adbf1d5c3fad" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,3a9e12fb-b961-43dd-a719-adbf1d5c3fad.aspx</comments>
      <category>.NET Programming;Security;Visual Studio</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=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=a3362548-9d08-4914-97e0-7f520fea7e76</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,a3362548-9d08-4914-97e0-7f520fea7e76.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,a3362548-9d08-4914-97e0-7f520fea7e76.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=a3362548-9d08-4914-97e0-7f520fea7e76</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
When ASP.NET 2.0 and Visual Studio 2005 came out I hoped that ASP.NET themes will
be developed en masse by third parties and sold like those on <a href="http://TemplateMonster.com">TemplateMonster.com</a>.
Today, tired of ugly GridViews in my apps, I decided to find an ASP.NET theme
for at least a GridView, but to my surprise, the only thing I found was <a href="http://weblogs.asp.net/kevinbrammer/archive/2008/02/24/glassy-black-gridview-theme.aspx">this</a>,
which is not even a skin. There are millions of sites, books and blogs telling
how to make themes in ASP.NET 2.0, but it looks like market for third-party templates
has never materialized. Given how fierce the competition in the graphics &amp;
UI design world is, I wonder why everyone is missing a chance to take this niche.
Microsoft has a few <a href="http://msdn2.microsoft.com/en-us/asp.net/aa336613.aspx">starter
themes</a>, but just a few and without live test-drive sites - one has to download
and install Visual Studio plug-ins and build the site to see it in action. All this
is very strange: it's hard to believe there is no business model in making skinnable
themes for ASP.NET applications.
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=a3362548-9d08-4914-97e0-7f520fea7e76" />
      </body>
      <title>Where Are the Third-Party ASP.NET Theme/Skin Galleries?</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,a3362548-9d08-4914-97e0-7f520fea7e76.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,a3362548-9d08-4914-97e0-7f520fea7e76.aspx</link>
      <pubDate>Tue, 26 Feb 2008 19:33:32 GMT</pubDate>
      <description>&lt;p&gt;
When ASP.NET 2.0 and Visual Studio 2005 came out I hoped that ASP.NET themes will
be developed en masse by third parties and sold like those on &lt;a href="http://TemplateMonster.com"&gt;TemplateMonster.com&lt;/a&gt;.
Today, tired of&amp;nbsp;ugly GridViews in my apps, I decided to find an ASP.NET&amp;nbsp;theme
for at least a&amp;nbsp;GridView, but to my surprise, the only thing I found was &lt;a href="http://weblogs.asp.net/kevinbrammer/archive/2008/02/24/glassy-black-gridview-theme.aspx"&gt;this&lt;/a&gt;,
which is not even a skin. There are millions of sites, books&amp;nbsp;and blogs telling
how to make themes in ASP.NET 2.0, but it looks like market for third-party templates
has never materialized. Given how fierce the competition in the graphics&amp;nbsp;&amp;amp;
UI design world is, I wonder why everyone is missing a chance to take this niche.
Microsoft has a few &lt;a href="http://msdn2.microsoft.com/en-us/asp.net/aa336613.aspx"&gt;starter
themes&lt;/a&gt;, but just a few and without live test-drive sites&amp;nbsp;- one has to download
and install Visual Studio plug-ins and build the site to see it in action. All this
is very strange: it's hard to believe there is no business model in making skinnable
themes for ASP.NET applications.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=a3362548-9d08-4914-97e0-7f520fea7e76" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,a3362548-9d08-4914-97e0-7f520fea7e76.aspx</comments>
      <category>.NET Programming;ASP.NET;Rants;Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://vladsnotes.hrybok.com/Trackback.aspx?guid=c21d581f-9b92-41d8-8196-d8e4c05e7943</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,c21d581f-9b92-41d8-8196-d8e4c05e7943.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,c21d581f-9b92-41d8-8196-d8e4c05e7943.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=c21d581f-9b92-41d8-8196-d8e4c05e7943</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
After downloading and installing just-released Visual Studio 2008 on Vista x64, I
got compilation error while trying to build the "Hello, World" application. The error
was "<strong>fatal error CS0014: Required file 'alink.dll with IAlink3' could not
be found</strong>."<br />
It seemed to be a fairly common error during the Beta cycle of the Visual Studio
2008, but apparently it was not fixed - at least not for the 64-bit version of Vista. Similar
to 32-bit versions, the solution was to install two Windows Update items found
on the Visual Studio 2008 DVD in the "<strong>&lt;dvddrive&gt;:\WCU\dotNetFramework\dotNetMSP\x64</strong>"
folder (for 32-bit version look in the "&lt;dvddrive&gt;:\WCU\dotNetFramework\dotNetMSP\x86"
folder):<br />
1. NetFX2.0-KB110806-v6000-x64.msu. Run it, wait forever, reboot when it's done.<br />
2. NetFX3.0-KB929300-v6000-x64.msu. Run it, wait forever, reboot when it's done.<br /><br />
After those two updates were installed, the problem went away.
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=c21d581f-9b92-41d8-8196-d8e4c05e7943" />
      </body>
      <title>Visual Studio 2008: fixing "'alink.dll with IAlink3' could not be found" error</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,c21d581f-9b92-41d8-8196-d8e4c05e7943.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,c21d581f-9b92-41d8-8196-d8e4c05e7943.aspx</link>
      <pubDate>Thu, 22 Nov 2007 20:19:37 GMT</pubDate>
      <description>&lt;p&gt;
After downloading and installing just-released Visual Studio 2008 on Vista x64, I
got compilation error while trying to build the "Hello, World" application. The error
was "&lt;strong&gt;fatal error CS0014: Required file 'alink.dll with IAlink3' could not
be found&lt;/strong&gt;."&lt;br&gt;
It seemed to be a fairly common error during the Beta&amp;nbsp;cycle of the Visual Studio
2008, but apparently it was not fixed - at least not for the 64-bit version of Vista.&amp;nbsp;Similar
to&amp;nbsp;32-bit versions, the solution was to install two Windows Update items found
on the Visual Studio 2008&amp;nbsp;DVD in the "&lt;strong&gt;&amp;lt;dvddrive&amp;gt;:\WCU\dotNetFramework\dotNetMSP\x64&lt;/strong&gt;"
folder (for 32-bit version look&amp;nbsp;in the&amp;nbsp;"&amp;lt;dvddrive&amp;gt;:\WCU\dotNetFramework\dotNetMSP\x86"
folder):&lt;br&gt;
1. NetFX2.0-KB110806-v6000-x64.msu. Run it, wait forever, reboot when it's done.&lt;br&gt;
2. NetFX3.0-KB929300-v6000-x64.msu. Run it, wait forever, reboot when it's done.&lt;br&gt;
&lt;br&gt;
After those two updates were installed, the problem went away.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=c21d581f-9b92-41d8-8196-d8e4c05e7943" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,c21d581f-9b92-41d8-8196-d8e4c05e7943.aspx</comments>
      <category>Vista;Visual Studio;x64</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=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=80e3b19d-aa13-4dfa-8690-30ef7641cb2e</trackback:ping>
      <pingback:server>http://vladsnotes.hrybok.com/pingback.aspx</pingback:server>
      <pingback:target>http://vladsnotes.hrybok.com/PermaLink,guid,80e3b19d-aa13-4dfa-8690-30ef7641cb2e.aspx</pingback:target>
      <dc:creator>Vlad Hrybok</dc:creator>
      <wfw:comment>http://vladsnotes.hrybok.com/CommentView,guid,80e3b19d-aa13-4dfa-8690-30ef7641cb2e.aspx</wfw:comment>
      <wfw:commentRss>http://vladsnotes.hrybok.com/SyndicationService.asmx/GetEntryCommentsRss?guid=80e3b19d-aa13-4dfa-8690-30ef7641cb2e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Here's how it works: for the last two years we at <a href="http://UltiDev.com">UltiDev
LLC</a> work mainly on <a href="http://UltiDev.com/Products/HttpVPN/">HttpVPN</a> -
our flagship product and the main reason why our company exists. Once upon a
time we've decided that making a simple redistributable web server software would
be a great value-added piece completing HttpVPN offering and allowing us
to probe prospective market for HttpVPN, gather contact information of people who
may by interested in HttpVPN and setup our QA, build and release processes along
the way. The experiment turned out to be as successful and we hoped it would be. We've
got about 15,000 (and counting) installed <a href="http://UltiDev.com/Products/Cassini/">UltiDev
Cassini Web Server</a> runtimes worldwide and we are receiving overwhelmingly positive
feedback from users. All this also means that about every six months we have our Cassini
task tracker full enough to suspend HttpVPN work for a few weeks and do another release
or UltiDev Cassini. This time was no exception.
</p>
        <p>
Although we always hope to keep our Cassini mid-version upgrade development cycle
limited to three weeks, it took us usual five weeks to fix, test, fix again, test
again and release the <a href="http://www.ultidev.com/Products/Cassini/CassiniReleaseNotes.htm">latest
version</a> of UltiDev Cassini Web Server. This release had two main points of focus:
to eliminate all known installation/registration hurdles and to make UltiDev Cassini
compatible with all 64-bit Windows platforms. 64 bit OSes are gaining popularity
very rapidly thanks to the fact that most of the recent (and even not so recent -
think Pentium D) CPUs from AMD and Intel are x64-compatible. Windows Vista comes in
32- and 64-bit versions right from the start, while existing Windows XP Pro x64 and
Windows 2003 Server 64-bit were somewhat obscure because they were released before
64-bit CPUs hit the mainstream. Nowadays it's pretty much impossible to buy a CPU
that does not have x64 compatibility. Hoping to please Vista 32 and 64 bit users we
made sure that our latest version of Cassini runs smoothly on all the latest multicore
32 and 64 bit CPUs and supports entire (reasonable) line of Windows operating systems:
from Windows 2000 to Vista.
</p>
        <p>
Now, whether you own an older version of our tiny but powerful UltiDev Cassini, or
you never tried it - go ahead and <a href="http://www.ultidev.com/download/">download
the latest version</a>. If you owned old version - most of the known issues
will go away (or if you had none you will be less likely to face issues in the future).
If you never saw our Cassini - it's a perfect time to spend 20 minutes on something
you probably will go "wow!" about. Check it out now!
</p>
        <img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=80e3b19d-aa13-4dfa-8690-30ef7641cb2e" />
      </body>
      <title>Next version of UltiDev Cassini ASP.NET Web Server is available for download!</title>
      <guid isPermaLink="false">http://vladsnotes.hrybok.com/PermaLink,guid,80e3b19d-aa13-4dfa-8690-30ef7641cb2e.aspx</guid>
      <link>http://vladsnotes.hrybok.com/PermaLink,guid,80e3b19d-aa13-4dfa-8690-30ef7641cb2e.aspx</link>
      <pubDate>Sat, 10 Feb 2007 20:57:09 GMT</pubDate>
      <description>&lt;p&gt;
Here's how it works: for the last two years we at &lt;a href="http://UltiDev.com"&gt;UltiDev
LLC&lt;/a&gt; work mainly on &lt;a href="http://UltiDev.com/Products/HttpVPN/"&gt;HttpVPN&lt;/a&gt; -
our flagship&amp;nbsp;product and the main reason why our company exists. Once upon a
time we've decided that making a simple redistributable web server software would
be a&amp;nbsp;great value-added piece&amp;nbsp;completing HttpVPN offering and allowing us
to probe prospective market for HttpVPN, gather contact information of people who
may&amp;nbsp;by interested in HttpVPN and setup our QA, build and release processes along
the way. The experiment turned out to be as successful and we hoped it would be. We've
got about 15,000 (and counting) installed &lt;a href="http://UltiDev.com/Products/Cassini/"&gt;UltiDev
Cassini Web Server&lt;/a&gt; runtimes worldwide and we are receiving overwhelmingly positive
feedback from users. All this also means that about every six months we have our Cassini
task tracker full enough to suspend HttpVPN work for a few weeks and do another release
or UltiDev Cassini. This time was no exception.
&lt;/p&gt;
&lt;p&gt;
Although we always hope to keep our Cassini&amp;nbsp;mid-version upgrade development cycle
limited to three&amp;nbsp;weeks, it took us usual five weeks to fix, test, fix again,&amp;nbsp;test
again and release the &lt;a href="http://www.ultidev.com/Products/Cassini/CassiniReleaseNotes.htm"&gt;latest
version&lt;/a&gt; of UltiDev Cassini Web Server. This release had two main points of focus:
to eliminate all known installation/registration hurdles and to make UltiDev Cassini
compatible with all 64-bit Windows platforms. 64 bit&amp;nbsp;OSes&amp;nbsp;are gaining popularity
very rapidly thanks to the fact that most of the recent (and even not so recent -
think Pentium D) CPUs from AMD and Intel are x64-compatible. Windows Vista comes in
32- and 64-bit versions right from the start, while existing Windows XP Pro x64 and
Windows 2003 Server 64-bit were somewhat obscure because they were released before
64-bit CPUs hit the mainstream. Nowadays it's pretty much impossible to buy a CPU
that does not have x64 compatibility. Hoping to please Vista 32 and 64 bit users we
made sure that our latest version of Cassini runs smoothly on all the latest multicore
32 and 64 bit CPUs and supports entire (reasonable) line of Windows operating systems:
from Windows 2000 to Vista.
&lt;/p&gt;
&lt;p&gt;
Now, whether you own an older version of our tiny but powerful UltiDev Cassini, or
you never tried it - go ahead and &lt;a href="http://www.ultidev.com/download/"&gt;download
the latest version&lt;/a&gt;. If you owned old&amp;nbsp;version -&amp;nbsp;most of the known issues
will go away (or if you had none you will be less likely to face issues in the future).
If you never saw our Cassini - it's a perfect time to spend 20 minutes on something
you probably will go "wow!" about. Check it out now!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://vladsnotes.hrybok.com/aggbug.ashx?id=80e3b19d-aa13-4dfa-8690-30ef7641cb2e" /&gt;</description>
      <comments>http://vladsnotes.hrybok.com/CommentView,guid,80e3b19d-aa13-4dfa-8690-30ef7641cb2e.aspx</comments>
      <category>ASP.NET;Cassini Web Server;Digital Home;Visual Studio</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>
  </channel>
</rss>