<?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>Mark Michaelis' Weblog - Computer Related</title>
    <link>http://mark.michaelis.net/Blog/</link>
    <description>A cacophony of ramblings from my potpourri of notes</description>
    <copyright>Mark Michaelis</copyright>
    <lastBuildDate>Fri, 23 Jan 2009 15:23:22 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.0.7226.0</generator>
    <managingEditor>mark@michaelis.net</managingEditor>
    <webMaster>mark@michaelis.net</webMaster>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=a059950c-7840-4479-bf9f-daee8303f74b</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=a059950c-7840-4479-bf9f-daee8303f74b</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=a059950c-7840-4479-bf9f-daee8303f74b</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=a059950c-7840-4479-bf9f-daee8303f74b</wfw:commentRss>
      <slash:comments>7</slash:comments>
      <title>Visual Studio Keyboard Shortcuts Wrap-up (MSDN Flash - Feb. 2, 2009)</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=a059950c-7840-4479-bf9f-daee8303f74b</guid>
      <link>http://mark.michaelis.net/Blog/VisualStudioKeyboardShortcutsWrapupMSDNFlashFeb22009.aspx</link>
      <pubDate>Fri, 23 Jan 2009 15:23:22 GMT</pubDate>
      <description>&lt;p&gt;
In this edition, I am going to wrap up a few loose ends with a selection of miscellaneous
keyboard shortcuts and links to a summary keyboard shortcut poster.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Debugging:&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
I realize that none of you would write bugs, but in case you meet someone that does
or perhaps on occasion you need to debug some code in order to explain a complex algorithm,
here are some invaluable debugging keyboard shortcuts.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
F9 and CTRL+F9&lt;br&gt;
F9 creates or removes a breakpoint based on the cursor's current location. CTRL+F9
toggles whether a breakpoint is enabled or not.&lt;/li&gt;
&lt;li&gt;
F5, CTRL+F5 and SHIFT+F5&lt;br&gt;
CTRL+F5 launches the application or begins running the tests.&amp;nbsp; If there are multiple
projects in the solution, which project is launched depends on the solution's configured
startup project.&amp;nbsp; Using F5 will launch the application in debug mode.&amp;nbsp; After
encountering a breakpoint, F5 will continue execution until the next break point.&amp;nbsp;
SHIFT+F5 will stop the application from debugging all together.&lt;/li&gt;
&lt;li&gt;
F10, F11 and SHIFT+F11&lt;br&gt;
Executes the next statement one method at a time.&amp;nbsp; If not currently at a breakpoint,
debugging will start at the first statement.&amp;nbsp; F10 will execute the method without
following execution into the method.&amp;nbsp; In contrast, F11 will step into the method,
allowing you to debug it line by line (assuming you have the source code).&amp;nbsp; SHIFT+F11
executes all remaining statements within the currently executing method, allowing
you to jump out of a particular call rather than stepping over each line.&lt;/li&gt;
&lt;li&gt;
CTRL+ALT+I&lt;br&gt;
Displays the Immediate Window.&amp;nbsp; Used when debugging a method, this window allows
you to write code (frequently with intellisense) and evaluate/evaluate the code line
by line as though it was inline within the method you are debugging.&amp;nbsp; I find
it extremely helpful when learning about a new .NET API.&amp;nbsp; After instantiating
a particular type, I can examine various members on the type and learn more about
their behavior.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;strong&gt;Adding files to Project&lt;/strong&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
SHIFT+ALT+C&lt;br&gt;
Displays the Add New Item dialog with the Class template selected.&amp;nbsp; Initially
I wanted this to work without the dialog but I need to supply the class/file name
and there are no additional keystrokes to placing it in the dialog.&lt;/li&gt;
&lt;li&gt;
SHIFT+ALT+A&lt;br&gt;
Displays the dialog for adding an existing item to the project.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;strong&gt;Summary&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
As I wrote this series, I was amazed at how frequently I still found myself forgetting
some of the new keyboard shortcuts I learned while writing (CTRL+Break to stop a build).&amp;nbsp;
Fortunately, there are posters available with many of the top shortcuts listed.&amp;nbsp;
I recommend using one as a mouse pad for a few months so that you can get them down.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=a059950c-7840-4479-bf9f-daee8303f74b&amp;amp;url=http%3a%2f%2fwww.microsoft.com%2fdownloads%2fdetails.aspx%3fFamilyID%3de5f902a8-5bb5-4cc6-907e-472809749973%26displaylang%3den"" target="_blank"&gt;Visual
C# 2008 Keybinding Reference Poster&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=a059950c-7840-4479-bf9f-daee8303f74b&amp;amp;url=http%3a%2f%2fwww.microsoft.com%2fdownloads%2fdetails.aspx%3ffamilyid%3d255b8cf1-f6bd-4b55-bb42-dd1a69315833%26displaylang%3den"" target="_blank"&gt;Visual
Basic 2008 Keybinding Reference Poster&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
This ends the series on Visual Studio Keyboard Shortcuts.&amp;nbsp; Next I plan to start
a series on the Entity Framework.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=a059950c-7840-4479-bf9f-daee8303f74b" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=a059950c-7840-4479-bf9f-daee8303f74b</comments>
      <category>Computer Related</category>
      <category>Computer Related/.Net</category>
      <category>Headlines</category>
    </item>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=ad3c2858-0ea4-4c79-b26f-2df6cb55457c</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=ad3c2858-0ea4-4c79-b26f-2df6cb55457c</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=ad3c2858-0ea4-4c79-b26f-2df6cb55457c</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=ad3c2858-0ea4-4c79-b26f-2df6cb55457c</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <title>Guilty as Charged</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=ad3c2858-0ea4-4c79-b26f-2df6cb55457c</guid>
      <link>http://mark.michaelis.net/Blog/GuiltyAsCharged.aspx</link>
      <pubDate>Sat, 17 Jan 2009 06:05:35 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=ad3c2858-0ea4-4c79-b26f-2df6cb55457c&amp;amp;url=http%3a%2f%2fimgs.xkcd.com%2fcomics%2fim_an_idiot.png"" target="_blank"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="391" alt="image" src="http://mark.michaelis.net/Blog/content/binary/GuiltyasCharged_136A0/image.png" width="658" border="0"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=ad3c2858-0ea4-4c79-b26f-2df6cb55457c" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=ad3c2858-0ea4-4c79-b26f-2df6cb55457c</comments>
      <category>Computer Related</category>
    </item>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=580f8ccd-3235-45ee-92cc-05d2606c551f</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=580f8ccd-3235-45ee-92cc-05d2606c551f</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=580f8ccd-3235-45ee-92cc-05d2606c551f</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=580f8ccd-3235-45ee-92cc-05d2606c551f</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <title>Unattended Installation of Team Foundation Server 2008 on Windows 2008 with SQL Server 2008</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=580f8ccd-3235-45ee-92cc-05d2606c551f</guid>
      <link>http://mark.michaelis.net/Blog/UnattendedInstallationOfTeamFoundationServer2008OnWindows2008WithSQLServer2008.aspx</link>
      <pubDate>Mon, 15 Dec 2008 12:31:04 GMT</pubDate>
      <description>&lt;p&gt;
The following are my instructions for installing a new &lt;strong&gt;Team Foundation Server
2008 with SP1&lt;/strong&gt; onto &lt;strong&gt;Windows 2008&lt;/strong&gt; with &lt;strong&gt;SQL Server
2008&lt;/strong&gt;.
&lt;/p&gt;
&lt;p&gt;
Throughout, I followed the &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=580f8ccd-3235-45ee-92cc-05d2606c551f&amp;amp;url=http%3a%2f%2fwww.microsoft.com%2fdownloads%2fdetails.aspx%3fFamilyID%3dff12844f-398c-4fe9-8b0d-9e84181d9923%26displaylang%3den"&gt;TFS
install guide&lt;/a&gt; and tried to automate where it didn't distract me too much from
the task at hand.&amp;nbsp; I followed the Single-Server Team Foundation Server Installation.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Folder Layout&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
For the scripts to work successfully, you need the following placed into a local directory
(probably without spaces in the name):
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
.\&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=580f8ccd-3235-45ee-92cc-05d2606c551f&amp;amp;url=http%3a%2f%2fwww.microsoft.com%2fdownloads%2fdetails.aspx%3fFamilyId%3dAB99342F-5D1A-413D-8319-81DA479AB0D7%26displaylang%3den"" target="_blank"&gt;dotnetfx35.exe&lt;/a&gt;
&lt;br&gt;
.\SQLServer2008\&amp;nbsp;&amp;nbsp; (SQL Server 2008 install)&lt;br&gt;
.\TFS2008\&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
(TFS 2008 install)&lt;br&gt;
.\&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=580f8ccd-3235-45ee-92cc-05d2606c551f&amp;amp;url=http%3a%2f%2fwww.microsoft.com%2fdownloads%2fdetails.aspx%3ffamilyid%3d9E40A5B6-DA41-43A2-A06D-3CEE196BFE3D%26displaylang%3den"" target="_blank"&gt;TFS90sp1-KB949786-ENU.exe&lt;/a&gt;
&lt;br&gt;
.\&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=580f8ccd-3235-45ee-92cc-05d2606c551f&amp;amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fcontent%2fbinary%2fInstallingTeamFoundationServer2008onWind_7484%2fTFSSetup.zip"" target="_blank"&gt;TFSSetup.exe&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
(A custom TFS 2008 Setup utility I created for unattended installation)&lt;br&gt;
.\&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=580f8ccd-3235-45ee-92cc-05d2606c551f&amp;amp;url=http%3a%2f%2fwww.microsoft.com%2fdownloads%2fdetails.aspx%3fFamilyID%3defdc7227-549c-4de1-a063-783f71a8bb2b%26DisplayLang%3den"" target="_blank"&gt;WSS3wSP1.x86.exe&lt;/a&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;Prerequisites&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Start with a mostly virgin Windows 2008 server.&amp;nbsp; I say mostly because I joined
the machine to the domain and installed all Windows Updates.&amp;nbsp; In addition,&amp;nbsp;
I created a single TFSSERVICE domain account.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Installation&lt;/strong&gt;
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Turn on remote administration. [Optional] 
&lt;ol&gt;
&lt;pre class="csharpcode"&gt;REG ADD &lt;span class="str"&gt;"hklm\system\currentcontrolset\control\terminal
server"&lt;/span&gt; /f /v fDenyTSConnections /t REG_DWORD /d 0&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/ol&gt;
&lt;li&gt;
Install IIS 7.0 
&lt;ol&gt;
&lt;pre class="csharpcode"&gt;ServerManagerCmd -install Web-Server
ServerManagerCmd -install Web-Http-Redirect
ServerManagerCmd -install Web-Asp-Net
ServerManagerCmd -install Web-Windows-Auth
ServerManagerCmd -install Web-Mgmt-Compat&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&gt;
&lt;li&gt;
Installed the &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=580f8ccd-3235-45ee-92cc-05d2606c551f&amp;amp;url=http%3a%2f%2fdownload.microsoft.com%2fdownload%2f2%2f0%2fe%2f20e90413-712f-438c-988e-fdaa79a8ac3d%2fdotnetfx35.exe"&gt;.NET
Framework 3.5 Service Pack 1 (Full Package)&lt;/a&gt;&amp;nbsp; 
&lt;ol&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// use /norestart to prevent autorestart&lt;/span&gt; .\dotnetfx35.exe
/qb&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;li&gt;
Installed SQL Server 2008. 
&lt;ol&gt;
&lt;pre class="csharpcode"&gt;.\SQLServer2008\Setup.exe /ACTION=Install /FEATURES=SQLENGINE,FULLTEXT,AS,RS,SSMS,ADV_SSMS /INDICATEPROGRESS 
&lt;br&gt;
/QUIETSIMPLE /ERRORREPORTING=1 /INSTANCEDIR=&lt;span class="str"&gt;"%ProgramData%\Microsoft
SQL Server"&lt;/span&gt; /SQMREPORTING=True 
&lt;br&gt;
/INSTANCENAME=&lt;span class="str"&gt;"MSSQLSERVER"&lt;/span&gt; /AGTSVCACCOUNT=&lt;span class="str"&gt;"NT
AUTHORITY\NETWORK SERVICE"&lt;/span&gt; /AGTSVCSTARTUPTYPE=&lt;span class="str"&gt;"Automatic"&lt;/span&gt; 
&lt;br&gt;
/ISSVCSTARTUPTYPE=&lt;span class="str"&gt;"Automatic"&lt;/span&gt; /ISSVCACCOUNT=&lt;span class="str"&gt;"NT
AUTHORITY\NetworkService"&lt;/span&gt; /ASSVCACCOUNT=&lt;span class="str"&gt;"NT AUTHORITY\NETWORK
SERVICE"&lt;/span&gt; 
&lt;br&gt;
/ASSVCSTARTUPTYPE=&lt;span class="str"&gt;"Automatic"&lt;/span&gt; /ASDATADIR=&lt;span class="str"&gt;"C:\ProgramData\Microsoft
SQL Server\MSAS10.MSSQLSERVER\OLAP\Data"&lt;/span&gt; 
&lt;br&gt;
/ASLOGDIR=&lt;span class="str"&gt;"%ProgramData%\Microsoft SQL Server\MSAS10.MSSQLSERVER\OLAP\Log"&lt;/span&gt; 
&lt;br&gt;
/ASBACKUPDIR=&lt;span class="str"&gt;"%ProgramData%\Microsoft SQL Server\MSAS10.MSSQLSERVER\OLAP\Backup"&lt;/span&gt; 
&lt;br&gt;
/ASTEMPDIR=&lt;span class="str"&gt;"%ProgramData%\Microsoft SQL Server\MSAS10.MSSQLSERVER\OLAP\Temp"&lt;/span&gt; 
&lt;br&gt;
/ASCONFIGDIR=&lt;span class="str"&gt;"%ProgramData%\Microsoft SQL Server\MSAS10.MSSQLSERVER\OLAP\Config"&lt;/span&gt; 
&lt;br&gt;
/ASPROVIDERMSOLAP=&lt;span class="str"&gt;"1"&lt;/span&gt; /ASSYSADMINACCOUNTS=&lt;span class="str"&gt;"BUILTIN\Administrators"&lt;/span&gt; /SQLSVCSTARTUPTYPE=&lt;span class="str"&gt;"Automatic"&lt;/span&gt; 
&lt;br&gt;
/SQLSVCACCOUNT=&lt;span class="str"&gt;"NT AUTHORITY\NETWORK SERVICE"&lt;/span&gt; /SQLSYSADMINACCOUNTS=&lt;span class="str"&gt;"BUILTIN\Administrators"&lt;/span&gt; 
&lt;br&gt;
/BROWSERSVCSTARTUPTYPE=&lt;span class="str"&gt;"Automatic"&lt;/span&gt; /RSSVCACCOUNT=&lt;span class="str"&gt;"NT
AUTHORITY\NETWORK SERVICE"&lt;/span&gt; 
&lt;br&gt;
/RSSVCSTARTUPTYPE=&lt;span class="str"&gt;"Automatic"&lt;/span&gt; /RSINSTALLMODE=&lt;span class="str"&gt;"FilesOnlyMode"&lt;/span&gt; /FTSVCACCOUNT=&lt;span class="str"&gt;"NT
AUTHORITY\LOCAL SERVICE"&lt;/span&gt;&lt;/pre&gt;
&gt;
&lt;div&gt;The only customization I made was to move the data storage to &lt;font face="consolas"&gt;C:\ProgramData\...&lt;/font&gt; rather
than the default &lt;font face="consolas"&gt;C:\Program Files\...&lt;/font&gt;.&amp;nbsp; I prefer
this because I like to keep all data separate from the program executables themselves.&amp;nbsp;
One other thing to note is that my log files are on the same disk as the databases
- consider improving for your scenario.&lt;br&gt;
NOTE: The first phase of the SQL Server 2008 install is to install Windows Installer
4.5 if it isn't already installed.&amp;nbsp; Unfortunately, this requires a reboot after
which you need to re-run the SQL Server 2008 setup.&amp;nbsp; Consider running an &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=580f8ccd-3235-45ee-92cc-05d2606c551f&amp;amp;url=http%3a%2f%2fshellrevealed.com%2ffiles%2ffolders%2fcode%2fentry4411.aspx"" target="_blank"&gt;autologon.exe&lt;/a&gt; utility
at the beginning of your installation (so that the password prompt occurs before you
leave the computer to do the install) in order to set the computer to automatically
logon after rebooting.&amp;nbsp; You will also want to use the &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=580f8ccd-3235-45ee-92cc-05d2606c551f&amp;amp;url=http%3a%2f%2fsupport.microsoft.com%2fdefault.aspx%2fkb%2f137367"" target="_blank"&gt;Runonce
registry setting&lt;/a&gt; to re-run the SQL Server 2008 install.&lt;br&gt;
&lt;/div&gt;
&lt;li&gt;
Installed &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=580f8ccd-3235-45ee-92cc-05d2606c551f&amp;amp;url=http%3a%2f%2fwww.microsoft.com%2fdownloads%2fdetails.aspx%3fFamilyID%3defdc7227-549c-4de1-a063-783f71a8bb2b%26DisplayLang%3den"" target="_blank"&gt;Windows
SharePoint Services 3.0 with SP1&lt;/a&gt; 
&lt;ol&gt;
&lt;pre class="csharpcode"&gt;IF NOT DEFINED TFSSERVICEPASSWORD ( SET /P TFSSERVICEPASSWORD=Enter the TFS Service password: ) 

WSS3wSP1.x86.exe /Extract:"%TEMP%\WSS3wSP1" /passive /quiet
"%TEMP%\WSS3wSP1\setup.exe" /config "%~dp0Wss4TfsSingleServerConfig.xml" 
CHOICE /T 1 /D Y /M Waiting...
RD /Q /S "%TEMP%\WSS3wSP1

SET PSCONFIG="%COMMONPROGRAMFILES%\Microsoft Shared\web server extensions\12\bin\psconfig.exe"
%PSCONFIG% -cmd configdb -create -server localhost -database SharePoint_Config -user %USERDOMAIN%\TFSSERVICE -password %TFSSERVICEPASSWORD% -admincontentdatabase SharePoint_Admin_Content 
%PSCONFIG% -cmd adminvs -provision -port 2500 -windowsauthprovider onlyusentlm 

SET STSADM="%COMMONPROGRAMFILES%\Microsoft Shared\web server extensions\12\bin\stsadm.exe" 
%STSADM% -o extendvs -exclusivelyusentlm -url http://%COMPUTERNAME%.%USERDNSDOMAIN% -ownerlogin %USERDOMAIN%\tfsservice -owneremail "tfs@%USERDNSDOMAIN%" -sitetemplate sts -description "Team Foundation Server" 
%STSADM% -o siteowner -url "http://%COMPUTERNAME%.%USERDNSDOMAIN%" -secondarylogin %USERDOMAIN%\%USERNAME% 

%PSCONFIG% -cmd adminvs -provision -port 2500 -windowsauthprovider onlyusentlm&lt;font face="Consolas"&gt;
&lt;br&gt;
&lt;/font&gt;&lt;/pre&gt;
&gt;
&lt;div&gt;This script extracts WSSwSP1 to a temp directory and then executes the setup
unattended using the &lt;font face="Consolas" size="2"&gt;Wss4TfsSingleServerConfig.xml&lt;/font&gt; file
with ServerRole Web Frond End (WFE).&amp;nbsp; The WSS setup doesn't perform any configuration.&amp;nbsp;
Instead, the &lt;font face="Consolas"&gt;psconfig.exe&lt;/font&gt; and &lt;font face="Consolas"&gt;stsadm.exe&lt;/font&gt; configure
the server following the install.&amp;nbsp; Note that I use port 2500 as my SharePoint
central administration port (something I have standardized on).&amp;nbsp; In addition,
I use a fully qualified name for the WSS url.&lt;br&gt;
The &lt;font face="Consolas" size="2"&gt;Wss4TfsSingleServerConfig.xml&lt;/font&gt; contains the
following: 
&lt;/div&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&amp;lt;Configuration&amp;gt;
    &amp;lt;Package Id=&lt;span class="str"&gt;"sts"&lt;/span&gt;&amp;gt;
&amp;lt;Setting Id=&lt;span class="str"&gt;"REBOOT"&lt;/span&gt; Value=&lt;span class="str"&gt;"ReallySuppress"&lt;/span&gt;/&amp;gt;
&amp;lt;Setting Id=&lt;span class="str"&gt;"SETUPTYPE"&lt;/span&gt; Value=&lt;span class="str"&gt;"CLEAN_INSTALL"&lt;/span&gt;/&amp;gt;
&amp;lt;/Package&amp;gt; &amp;lt;DATADIR Value=&lt;span class="str"&gt;"%ProgramData%\Microsoft SQL
Server\MSSQL$SHAREPOINT\Data"&lt;/span&gt; /&amp;gt; &amp;lt;Logging Type=&lt;span class="str"&gt;"verbose"&lt;/span&gt; Path=&lt;span class="str"&gt;"%temp%"&lt;/span&gt; Template=&lt;span class="str"&gt;"Microsoft
Windows SharePoint Services 3.0 Setup(*).log"&lt;/span&gt;/&amp;gt; &amp;lt;Setting Id=&lt;span class="str"&gt;"SERVERROLE"&lt;/span&gt; Value=&lt;span class="str"&gt;"WFE"&lt;/span&gt;/&amp;gt;
&amp;lt;Setting Id=&lt;span class="str"&gt;"UsingUIInstallMode"&lt;/span&gt; Value=&lt;span class="str"&gt;"0"&lt;/span&gt;/&amp;gt;
&amp;lt;Display Level=&lt;span class="str"&gt;"none"&lt;/span&gt; CompletionNotice=&lt;span class="str"&gt;"no"&lt;/span&gt; AcceptEULA=&lt;span class="str"&gt;"Yes"&lt;/span&gt; /&amp;gt;
&amp;lt;/Configuration&amp;gt; &lt;/pre&gt;
&lt;/blockquote&gt; &lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;li&gt;
&lt;div&gt;Slipstreamed Team Foundation Server SP 1 into the &lt;font face="Consolas" size="2"&gt;.\TFS2008wSP1&lt;/font&gt; directory.
&lt;/div&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;.\TFS90sp1-KB949786-ENU.exe /extract:"%TEMP%\TFS2008SP1"&lt;br&gt;
msiexec /a .\TFS2008\at\vs_setup.msi /p "%TEMP%\TFS2008SP1\TFS90sp1-KB949786.msp"
TARGETDIR="%CD%\TFS2008wSP1\AT" /L*vx c:\temp\install.log&lt;br&gt;
CHOICE /T 1 /D Y /M Waiting... 
&lt;br&gt;
RD /Q /S "%TEMP%\TFS2008SP1"&lt;br&gt;
&lt;/pre&gt;
&lt;/blockquote&gt; &lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;li&gt;
&lt;div&gt;Since there are no unattended command line switches for the Team Foundation Server
install, I created a custom executable called &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=580f8ccd-3235-45ee-92cc-05d2606c551f&amp;amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fcontent%2fbinary%2fInstallingTeamFoundationServer2008onWind_7484%2fTFSSetup.zip"" target="_blank"&gt;TFSSetup.exe&lt;/a&gt; that
I created to automate an unattended install of Team Foundation Server SP1.&amp;nbsp; A
few things to note about the custom executable:
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div&gt;It accepts the license terms and assumes the product key is defaulted.
&lt;/div&gt;
&lt;li&gt;
&lt;div&gt;The deployment directory is the default directory for the TFS setup.
&lt;/div&gt;
&lt;li&gt;
&lt;div&gt;It assumes a Single Server TFS deployment and uses the default database server
name (%COMPUTERNAME%)
&lt;/div&gt;
&lt;li&gt;
&lt;div&gt;It assumes the TFS Service name is %USERDOMAIN%\TFSSERVICE and that the password
is stored in the environment variable TFSSERVICEPASSWORD (if it is not, the program
will prompt for the password).
&lt;/div&gt;
&lt;li&gt;
&lt;div&gt;The SharePoint settings are http:\\%COMPUTERNAME%:2500 for the admin site and
http:\\%COMPUTERNAME%.%USERDNSDOMAIN%/Sites for the Sites URL.
&lt;/div&gt;
&lt;li&gt;
&lt;div&gt;Alerts are not enabled.
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;&gt;
&lt;p&gt;
&lt;strong&gt;Possible Errors:&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Error&lt;/strong&gt;: This installation package could not be opened.&amp;nbsp; Contact
the application vendor to verify that this is a valid Windows Installer package.
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Verify that the source directory (with the RTM version of TFS) is pointing to the
AT directory.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;Error&lt;/strong&gt;: The installer has encountered an unexpected error installing
this package. This may indicate a problem with this package. The error code is 2203. 
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
This is caused because some of the files are read-only.&amp;nbsp; Run &lt;font face="Consolas"&gt;Attrib
-R .\* /S /D&lt;/font&gt; on both the &lt;font face="Consolas"&gt;SP1&lt;/font&gt; and &lt;font face="consolas"&gt;TFSRTM&lt;/font&gt; directories.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;Error&lt;/strong&gt;: The upgrade patch cannot be installed by the Windows Installer
service because the program to be upgraded may be missing, or the upgrade patch may
update a different version of the program. Verify that the program to be upgraded
exists on your computer and that you have the correct upgrade patch.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Error&lt;/strong&gt;: The server parameter specified with the configdb command is
invalid. Failed to connect to the database server or the database name does not exist.&amp;nbsp;
Ensure the database server exists, is a Sql server, and that you have the appropriate
permissions to access the database server.&amp;nbsp; To diagnose the problem, review the
extended error information located at &lt;font face="Consolas" size="2"&gt;C:\Program Files\Common
Files\Microsoft Shared\Web Server Extensions\12LOGS\PSCDiagnostics_12_14_2008_18_24_58_443_440016503.log&lt;/font&gt;.&amp;nbsp;
Please consult the SharePoint Products and Technologies Configuration Wizard help
for additional information regarding database server security configuration and network
access.
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
This error occurred because I included both the dbuser and dppassword when executing
psconfig.exe configdb.&amp;nbsp; Upon removing both those parameters, the error was avoided. 
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;Error&lt;/strong&gt;: The SQL Server Browser service is stopped.&lt;br&gt;
&lt;strong&gt;Error&lt;/strong&gt;: The SQL Server Browser service is not set to start automatically.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Error&lt;/strong&gt;: TF220041: The specified Windows SharePoint Services site URL
(&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=580f8ccd-3235-45ee-92cc-05d2606c551f&amp;amp;url=http%3a%2f%2f%3cDefaultSiteURL%3e%2fSites)"&gt;http://&amp;lt;DefaultSiteURL&amp;gt;/Sites)&lt;/a&gt; is
not the default site collection site: (Sites).&lt;br&gt;
The default site collection site might have been renamed or removed. Make sure that
the site exists and verify the correct URL,&lt;br&gt;
and then attempt installation. If the problem persists, you can choose to install
and configure Windows SharePoint Services as&lt;br&gt;
part of the Team Foundation Server installation process.
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
This error occurs when you specify the Windows SharePoint Server URL without the "/Sites"
suffix.&amp;nbsp; Team Foundation Server 2008 does not work correctly against the root.&amp;nbsp;
You must specify includes the "/Sites" suffix to avoid this error.
&lt;/p&gt;
&lt;/blockquote&gt;&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=580f8ccd-3235-45ee-92cc-05d2606c551f" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=580f8ccd-3235-45ee-92cc-05d2606c551f</comments>
      <category>Computer Related</category>
      <category>Computer Related/.Net</category>
    </item>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=e0b70f97-72df-4bc6-8775-8523483c38a2</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=e0b70f97-72df-4bc6-8775-8523483c38a2</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=e0b70f97-72df-4bc6-8775-8523483c38a2</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=e0b70f97-72df-4bc6-8775-8523483c38a2</wfw:commentRss>
      <slash:comments>25</slash:comments>
      <title>SQL Server 2008 Install Nightmare</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=e0b70f97-72df-4bc6-8775-8523483c38a2</guid>
      <link>http://mark.michaelis.net/Blog/SQLServer2008InstallNightmare.aspx</link>
      <pubDate>Tue, 09 Dec 2008 04:56:10 GMT</pubDate>
      <description>&lt;p&gt;
It all started with an installation of Visual Studio 2008 SP1, which included SQL
Server Express 2005.&amp;nbsp; From there I wished to install SQL Server 2008 Standard
on the default port and upgrade SQL Server 2005 Express to SQL Server 2008 express.&amp;nbsp;
Unfortunately, this proved to be a troublesome desire.&amp;nbsp; I have no idea what the
cause is exactly, except that I was not the only one on my team to have issues.
&lt;/p&gt;
&lt;p&gt;
At this point, I am not sure the order that things occurred exactly, but I have a
host of error messages and ways to handle them.&amp;nbsp; I can't say it will work for
you - I sure hope you didn't have to go through all these to install SQL Server 2008
- but I did so I decided to share the experience.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;a name="Uninstall"&gt;Uninstall procedure:&lt;/a&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
The most important step with any failed SQL Server 2008 installation is uninstalling
the failed attempt - yes, SQL Server 2008 needs to be uninstalled if an installation
fails as it doesn't automatically roll back.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
At the moment there is no complete knowledge base article on how to manually uninstall
SQL Server 2008.&amp;nbsp; However, there are instructions for &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e0b70f97-72df-4bc6-8775-8523483c38a2&amp;amp;url=http%3a%2f%2fsupport.microsoft.com%2fkb%2f909967"" target="_blank"&gt;how
to uninstall an instance of SQL Server 2005 manually&lt;/a&gt; and there is a lot of similarity
with SQL Server 2008, so review and follow those instructions were it makes sense.&amp;nbsp;
Below is a list of the steps I followed:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Uninstall the the installation from &lt;strong&gt;Programs and Features&lt;/strong&gt;/&lt;strong&gt;Add
Remove Programs&lt;/strong&gt;, selecting &lt;strong&gt;Microsoft SQL Server 2008&lt;/strong&gt; and
double clicking to run the uninstaller. (You always need to begin with this step or
the command line equivalent.)&amp;nbsp; Do not use the Windows Installer Cleanup Tool
to remove SQL Server 2008 without first trying to do so from &lt;strong&gt;Programs and
Features&lt;/strong&gt;/&lt;strong&gt;Add Remove Programs&lt;/strong&gt;. During the uninstall, you
can choose (via series of check boxes), which components of SQL Server 2008 to uninstall
- including any shared components for when you have multiple instances.&amp;nbsp; In the
case of multiple instances, each instance needs to be uninstalled independently. 
&lt;li&gt;
Run&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Consolas"&gt;SC.EXE query | find /i "SERVICE_NAME:
MSSQL"&lt;/font&gt;&amp;nbsp;&lt;br&gt;
to verify that there are no services instances for SQL Server that should have been
deleted but weren't.&amp;nbsp; Any items that appear unexpectedly, should be removed with
the command 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="Consolas"&gt;&lt;font face="Consolas"&gt;SC.EXE&lt;/font&gt; delete
&amp;lt;service name&amp;gt;&lt;/font&gt;&amp;nbsp;&lt;br&gt;
Where service name is the name of the service returned by &lt;font face="Consolas"&gt;sc.exe
query.&lt;/font&gt; 
&lt;br&gt;
If &lt;font face="consolas"&gt;SC.EXE&lt;/font&gt; fails to uninstall the services and there are
no other instances of SQL Server installed, delete registry keys &lt;font face="consolas"&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer&lt;/font&gt;, &lt;font face="consolas"&gt;HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSSQLSERVER&lt;/font&gt; and &lt;font face="consolas"&gt;HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SQLAgent&lt;/font&gt; 
&lt;li&gt;
Search for &lt;font face="consolas"&gt;&amp;lt;Instance Name&amp;gt;&lt;/font&gt; in &lt;font face="consolas"&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall&lt;/font&gt;.&amp;nbsp;
If you find any, usually on a value called &lt;font face="consolas"&gt;InstanceId&lt;/font&gt;,
run 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="consolas"&gt;MSIEXEC /X &amp;lt;GUID&amp;gt;&lt;/font&gt; 
&lt;br&gt;
where the &lt;font face="consolas"&gt;&amp;lt;GUID&amp;gt;&lt;/font&gt; is the key name containing the &lt;font face="consolas"&gt;InstanceId&lt;/font&gt; value. 
&lt;li&gt;
Delete the following registry keys/values if they exist 
&lt;ul&gt;
&lt;li&gt;
&lt;font face="consolas"&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\&amp;lt;Feature&amp;gt;.&amp;lt;Instance
Name&amp;gt; &lt;/font&gt; 
&lt;li&gt;
&lt;font face="consolas"&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\&amp;lt;Instance
Name&amp;gt;&lt;/font&gt; 
&lt;li&gt;
&lt;font face="consolas"&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\Instance
Names\SQL\&amp;lt;Instance Name&amp;gt;&lt;/font&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;
Delete &lt;font face="consolas"&gt;%ProgramFiles%\Microsoft SQL Server\&amp;lt;Feature&amp;gt;.&amp;lt;Instance
Name&amp;gt;&lt;/font&gt; if it exists. 
&lt;li&gt;
Finally, search for the &lt;font face="consolas"&gt;&amp;lt;Feature&amp;gt;.&amp;lt;Instance Name&amp;gt;&lt;/font&gt; in
the registry and consider deleting any remaining items. In some cases this involves
deleting the value because the other values within the same key are for a different
instance.&amp;nbsp; In other cases, the entire key will need to be deleted because there
is no other instance data within the key.&amp;nbsp; Hopefully, you won't encounter anything
significant, but this is a good final step.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&lt;font face="consolas"&gt;&amp;lt;Feature&amp;gt;&lt;/font&gt; has a value like &lt;font face="consolas"&gt;MSSQL10&lt;/font&gt; or &lt;font face="consolas"&gt;MSAS10&lt;br&gt;
&amp;lt;Instance Name&amp;gt;&lt;/font&gt; is the name of the SQL Server instance you are trying
to uninstall.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Pheww, now that we have completely uninstalled, lets review potential errors you might
encounter:
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Error&lt;/strong&gt;: A later version of Microsoft SQL Server Compact is already
installed.
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Strange, since all I wanted was to install the SQL Server 2008 Tools.&amp;nbsp; Here are
the steps to correct:
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;ol&gt;
&lt;ol&gt;
&lt;li&gt;
Uninstall all parts of the SQL Server Compact Framework 3.5 SP1.&amp;nbsp; 
&lt;li&gt;
Rerun SQL Server 2008 install.&amp;nbsp; 
&lt;li&gt;
After installing SQL Server 2008 Tools, downloaded and reinstalled the SQL Server
Compact Framework SP1.&amp;nbsp; The tools are located here:&lt;/li&gt;
&lt;/ol&gt;
&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e0b70f97-72df-4bc6-8775-8523483c38a2&amp;amp;url=http%3a%2f%2fwww.microsoft.com%2fdownloads%2fdetails.aspx%3fFamilyID%3ddc614aee-7e1c-4881-9c32-3a6ce53384d9"&gt;SQL
Server Compact 3.5 SP1 for desktop&lt;/a&gt; 
&lt;li&gt;
&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e0b70f97-72df-4bc6-8775-8523483c38a2&amp;amp;url=http%3a%2f%2fwww.microsoft.com%2fdownloads%2fdetails.aspx%3fFamilyID%3dfce9abbf-f807-45d6-a457-ab5615001c8f%26DisplayLang%3den"&gt;SQL
Server Compact 3.5 SP1 for Devices&lt;/a&gt; 
&lt;li&gt;
&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e0b70f97-72df-4bc6-8775-8523483c38a2&amp;amp;url=http%3a%2f%2fwww.microsoft.com%2fdownloads%2fdetails.aspx%3fFamilyID%3dfa751db3-7685-471b-ac31-f1b150422462%26DisplayLang%3den"&gt;SQL
Server Compact 3.5 SP1 Server Tools (Merge Replication Serve2r Side Config)&lt;/a&gt; 
&lt;li&gt;
&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e0b70f97-72df-4bc6-8775-8523483c38a2&amp;amp;url=http%3a%2f%2fwww.microsoft.com%2fdownloads%2fdetails.aspx%3fFamilyId%3d07829770-73A7-41E4-880D-E74B1A353623%26displaylang%3den"&gt;SQL
Server Compact 3.5 SP1 Books Online and Samples&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;p align="left"&gt;
&lt;strong&gt;Error:&lt;/strong&gt; The following error has occurred: Could not open key: &lt;font face="Courier New"&gt;UNKNOWN\Components\CBFF54E0ED12B0946A1C52E5E82ABC38\E7BEEF5F746F8AB9076051A5574&lt;/font&gt;.&amp;nbsp;
Verify that you have sufficient access to that key, or contact your support personnel.
(Errors could be for other GUIDs as well)
&lt;/p&gt;
&lt;p align="center"&gt;
&lt;strong&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="177" alt="The following error has occurred: Could not open key: UNKNOWN\Components\CBFF54E0ED12B0946A1C52E5E82ABC38\E7BEEF5F746F8AB9076051A5574.  Verify that you have sufficient access to that key, or contact your support personnel." src="http://mark.michaelis.net/Blog/content/binary/SQLServer2008InstallNightmare_F264/image23.png" width="616" border="0"&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Errors could be for other GUIDs as well including &lt;font face="Courier New"&gt;UNKNOWN\Components\493032C95B52CBD448DD2B5A52C50E9A\3EC761FD7E06AE4499CE52705CF173EA&lt;/font&gt;.
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
This error is a permissions error in the registry.&amp;nbsp; If you search the registry
for the first GUID you will find the key is likely mapped to &lt;font face="Courier New"&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\&amp;lt;user
SID&amp;gt;\Components\&amp;lt;GUID&amp;gt;&lt;/font&gt;.&amp;nbsp; Beneath this key is a sub key for the
second GUID.&amp;nbsp; However, selecting the subkey will result in an access denied message.
&lt;/p&gt;
&lt;p&gt;
To correct the problem:
&lt;/p&gt;
&lt;p&gt;
1. Verify that you are running RegEdit as administrator (to avoid UAC issues with
Windows Vista and Windows 3008+).
&lt;/p&gt;
&lt;p&gt;
2. Edit the permission of the parent key(&lt;font face="Courier New"&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\&amp;lt;user
SID&amp;gt;\Components&lt;/font&gt;) and click the &lt;strong&gt;Advanced&lt;/strong&gt; button. (Optionally,
you could edit the permissions on the parent GUID (&lt;font face="Courier New"&gt;CBFF54E0ED12B0946A1C52E5E82ABC38&lt;/font&gt; in
my example) but the same problem is likely to exist with other keys so you may as
well deal with this in mass.)
&lt;/p&gt;
&lt;p align="center"&gt;
&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e0b70f97-72df-4bc6-8775-8523483c38a2&amp;amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fcontent%2fbinary%2fSQLServer2008InstallNightmare_F264%2fimage.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="252" alt="image" src="http://mark.michaelis.net/Blog/content/binary/SQLServer2008InstallNightmare_F264/image_thumb.png" width="473" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p align="left"&gt;
3.&amp;nbsp; From the Advanced dialog, select the &lt;strong&gt;Owner&lt;/strong&gt; tab and check
the &lt;strong&gt;Replace owner on subcontainers and objects&lt;/strong&gt; check box.&amp;nbsp; Also,
verify that System is the owner (else add System and be sure to select it so it will
become the owner).&amp;nbsp; 
&lt;/p&gt;
&lt;p align="left"&gt;
4. Next click &lt;strong&gt;Apply&lt;/strong&gt;.
&lt;/p&gt;
&lt;p align="left"&gt;
4.&amp;nbsp; You may be presented with an error dialog, "Registry Editor could not set
owner on the key currently selected, or some of its subkeys."&amp;nbsp; You can safely
ignore this warning as long as you are then able to view the subkey.&amp;nbsp; If not
:(, you may have to follow the same process but in safe mode or download &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e0b70f97-72df-4bc6-8775-8523483c38a2&amp;amp;url=http%3a%2f%2ftechnet.microsoft.com%2fen-us%2fsysinternals%2fbb896653.aspx"" target="_blank"&gt;Process
Explorer&lt;/a&gt; and search for any process that is holding onto the key so that you can
shut it down.&amp;nbsp; (The idea that a process is preventing you from viewing the key
is a stretch in my mind but I have had heard the Platform team of Microsoft's product
support group suggest this.)
&lt;/p&gt;
&lt;p align="left"&gt;
5.&amp;nbsp; Lastly, select the "Effective Permissions" tab and verify that both your
own User Id and the System user have &lt;strong&gt;Full Control&lt;/strong&gt;.&amp;nbsp; If not,
add both users via the &lt;strong&gt;Permissions&lt;/strong&gt; tab.
&lt;/p&gt;
&lt;p align="left"&gt;
If this still fails, consider resetting registry permissions back to the default settings
using the following command:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;    Registry security: secedit /configure /cfg %windir%\inf\defltbase.inf /db defltbase.sdb /verbose /areas REGKEYS&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;Error:&lt;/strong&gt; SQL Server setup has encountered the following error. sku &lt;blockquote&gt; 
&lt;p&gt;
&lt;a href="#uninstall"&gt;Manually uninstall&lt;/a&gt; SQL Server 2008 installation and try installing
again.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;Error:&lt;/strong&gt; Error 1316.A network error occurred while attempting to read
file &lt;font face="Courier New"&gt;ssceruntime-enu.msi&lt;/font&gt;.
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e0b70f97-72df-4bc6-8775-8523483c38a2&amp;amp;url=http%3a%2f%2fconnect.microsoft.com%2fSQLServer%2ffeedback%2fViewFeedback.aspx%3fFeedbackID%3d363055"" target="_blank"&gt;Connect
mentions this error&lt;/a&gt;.&amp;nbsp; I followed a similar procedure.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Extract the &lt;font face="Courier New"&gt;ISO&lt;/font&gt; file or copy the SQL Server CD onto
the local drive.&amp;nbsp; 
&lt;li&gt;
Copy the .\&lt;font face="Courier New"&gt;&amp;lt;platform&amp;gt;\Setup\SSCERuntime.msi&lt;/font&gt; file
to &lt;font face="Courier New"&gt;SSCERuntime-enu.msi&lt;/font&gt; within the same directory.&amp;nbsp;
This seemed appears to work around the error.&amp;nbsp; I haven't tested this exhaustively,
but I suspect this is a 64-bit problem only so the &amp;lt;platform&amp;gt; directory is most
likely &lt;font face="Courier New"&gt;x64&lt;/font&gt;. (Please comment and let me know if you
see this on other platforms.)&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;Error&lt;/strong&gt;: Error result: -2068578301
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;a href="#uninstall"&gt;Manually uninstall&lt;/a&gt; SQL Server 2008 installation and try installing
again
&lt;/p&gt;
&lt;/blockquote&gt; &lt;blockquote&gt;&lt;/blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;Error&lt;/strong&gt;: SQL Server installation failed. To continue, investigate the
reason for the failure, correct the problem, uninstall SQL Server, and then rerun
SQL Server Setup.
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Sometimes, the error log points to a &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e0b70f97-72df-4bc6-8775-8523483c38a2&amp;amp;url=http%3a%2f%2fwww.microsoft.com%2fproducts%2fee%2ftransform.aspx%3fProdName%3dMicrosoft%2bSQL%2bServer%26EvtSrc%3dsetup.rll%26EvtID%3d50000%26ProdVer%3d10.0.1600.2"" target="_blank"&gt;message
indicating there was a network error&lt;/a&gt;.&amp;nbsp; During the occasions that I encountered
this error message within the log, my installation failed with two red X icons in
the concluding dialog, only one of which had a corresponding message (I wish I had
taken a screen shot.)&amp;nbsp; The solution for me was to &lt;a href="#uninstall"&gt;manually
uninstall&lt;/a&gt;. 
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;Error&lt;/strong&gt;: Could not find the Database Engine startup handle.
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
This error appears after an installation completes unsuccessfully and a different
error dialog appeared earlier in the installation.&amp;nbsp; &lt;a href="#uninstall"&gt;Manually
uninstall&lt;/a&gt; all the instance related installations items, address the previous dialog,
and re-attempt the install.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;Error (during repair):&lt;/strong&gt; The SQL Server feature 'SQL_Engine_Core_Inst'
is not in a supported state for repair, as it was never successfully configured. Only
features from successful installations can be repaired. To continue, remove the specified
SQL Server feature.
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
This error appears if you attempt a repair of a failed installation.&amp;nbsp; The work
around it to &lt;a href="#uninstall"&gt;manually uninstall&lt;/a&gt; the all items related to
the instance, and re-attempt the install by addressing the original error.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;Error:&lt;/strong&gt; A MOF syntax error occurred. 
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;a href="#uninstall"&gt;Manually uninstall&lt;/a&gt; and then re-attempt the install.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;Error&lt;/strong&gt;: SQL Express 2008 ERROR: Failed to generate a user instance
of SQL Server and&lt;br&gt;
&lt;strong&gt;Error:&lt;/strong&gt; Failed to generate a user instance of SQL Server due to a
failure in starting the process for the user instance. The connection will be closed."
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Okay, admittedly this error doesn't appear during install, but it is an install related
error none the less.
&lt;/p&gt;
&lt;p&gt;
Recently I upgraded my SQL Express 2005 instance (installed by Visual Studio 2008)
to SQL Server Express 2008.&amp;nbsp; (Visual Studio 2008 Express editions will automatically
be upgraded when installing Service Pack 1, but not so with all other instances.)&amp;nbsp;
After upgrading, none of my data driven unit tests were successfully passing.&amp;nbsp;
Instead, they were failing with the message:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
The unit test adapter failed to connect to the data source or to read the data. For
more information on troubleshooting this error, see "&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e0b70f97-72df-4bc6-8775-8523483c38a2&amp;amp;url=http%3a%2f%2fgo.microsoft.com%2ffwlink%2f%3fLinkId%3d62412"" target="_blank"&gt;Troubleshooting
Data-Driven Unit Tests&lt;/a&gt;" in the MSDN Library.&lt;br&gt;
Error details: Failed to generate a user instance of SQL Server due to a failure in
starting the process for the user instance. The connection will be closed."
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
It took some sleuthing to determine the solution.&amp;nbsp; Firstly, I checked the error
files located in my &lt;font face="Courier New"&gt;%USERPROFILE%\Local Settings\Application
Data\Microsoft\Microsoft SQL Server Data\SQLEXPRESS&lt;/font&gt; (the connecting user's
SQL Express data directory) directory.&amp;nbsp; That indicated errors were in loading
the &lt;font face="consolas"&gt;modal.mdf&lt;/font&gt; and corresponding log file within afore
mentioned directory.&amp;nbsp; However, when connecting to the SQL Express instance from
SQL Server Management Studio, there were no such issues.&amp;nbsp; This was because the
instances connected to by SQL Server Management Studio were in the &lt;font face="Courier New"&gt;%PROGRAMFILES%\Microsoft
SQL Server&lt;/font&gt; directory.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Generally, when a new MDF file is connected to by SQL Express, it copies the master,
model, MSDB, and tempdb databases (mdf and log files) into the connecting user's SQL
Express data directory.&amp;nbsp; (This is frequently why the first time connecting for
each user takes longer.)&amp;nbsp; Such a copy was unnecessary in my case because the
databases already existed.&amp;nbsp; Unfortunately, the databases were from the SQL Server
Express 2005 instance, and not the upgraded database from SQL Server 2008 Express.
&lt;/p&gt;
&lt;p&gt;
To correct the problem, I
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Shut down SQL Server Express 
&lt;li&gt;
Deleted the users SQL Express directory "%USERPROFILE%\Local Settings\Application
Data\Microsoft\Microsoft SQL Server Data\SQLEXPRESS" 
&lt;li&gt;
Restarted SQL Server Express:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Here's a cmd script for what is needed:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
SC.EXE stop "MSSQL$SQLEXPRESS"&lt;br&gt;
CHOICE /C:N /D:N /N /T:5&lt;br&gt;
&lt;font face="Courier New"&gt;RD /S /Q "%USERPROFILE%\Local Settings\Application Data\Microsoft\Microsoft
SQL Server Data\SQLEXPRESS"&lt;br&gt;
&lt;/font&gt;SC.EXE start "MSSQL$SQLEXPRESS"
&lt;/p&gt;
&lt;/blockquote&gt;&lt;/blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;More Errors&lt;/strong&gt;:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Unfortunately, this is not anything even close to an exhaustive list of errors.&amp;nbsp;
If you have other messages I have not covered, the key place to check is &lt;font face="Consolas"&gt;%Programfiles%\Microsoft
sql server\100\Setup bootstrap\Log\&amp;lt;&lt;/font&gt;&lt;var&gt;&lt;font face="Consolas"&gt;DateTime&amp;gt;&lt;/font&gt;.&lt;/var&gt;&amp;nbsp;
To begin, open the &lt;font face="Consolas"&gt;Summary_&amp;lt;computername&amp;gt;_&amp;lt;DateTime&amp;gt;.txt&lt;/font&gt; file
to see an overview of the results.&amp;nbsp; If that doesn't help, consider reviewing
one of the &lt;font face="consolas"&gt;Detail*.txt&lt;/font&gt; files.&amp;nbsp; These errors are
all addressed in &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e0b70f97-72df-4bc6-8775-8523483c38a2&amp;amp;url=http%3a%2f%2fsupport.microsoft.com%2fkb%2f909967"" target="_blank"&gt;KB909967
- How to troubleshoot SQL Server 2008 Setup issues&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Another item that seemed to cause instability in my SQL Server 2008 installation was
mounting the SQL Server 2008 iso file (especially mounting it over the network).&amp;nbsp;
I recommend that you extract the ISO into a local directory and then installing from
the local directory.
&lt;/p&gt;
&lt;p&gt;
Overwhelmingly, the correction is to &lt;a href="#uninstall"&gt;manually uninstall&lt;/a&gt; the
attempted install instance.
&lt;/p&gt;
&lt;/blockquote&gt;&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=e0b70f97-72df-4bc6-8775-8523483c38a2" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=e0b70f97-72df-4bc6-8775-8523483c38a2</comments>
      <category>Computer Related</category>
      <category>.Net</category>
    </item>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=ddac7f13-ed68-4a32-9ba9-6f0b2906f408</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=ddac7f13-ed68-4a32-9ba9-6f0b2906f408</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=ddac7f13-ed68-4a32-9ba9-6f0b2906f408</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=ddac7f13-ed68-4a32-9ba9-6f0b2906f408</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Originally, I was going to focus on shortcuts for the various build/compilation options
within Visual Studio 2008.  However, things become a little more complicated
in terms of which keyboard shortcut to use because it depends on your keyboard mapping
scheme.  In this edition, therefore, I am going to discuss the Keyboard Options
dialog - where different keyboard schemes are available for selection.  
</p>
        <p>
During the first launch of Visual Studio 2008, you are prompted with which keyboard
scheme to use.  The typical options are (Default), Visual C# 2005, and Visual
Basic 6. Fortunately, you can change your selection via the <strong>Tools-&gt;Customize...</strong> menu
and the <strong>Keyboard...</strong> button on the ensuing dialog (Alt+T, Alt+C, Alt+K).
The same dialog is available from <strong>Tools-&gt;Options...</strong> and the <strong>Keyboard</strong> node
of the environment. 
</p>
        <p align="center">
          <a href="http://mark.michaelis.net/Blog/ct.ashx?id=ddac7f13-ed68-4a32-9ba9-6f0b2906f408&amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fcontent%2fbinary%2fWindowsLiveWriter%2fMSDNFlashKeyboardVisualStudioTipsTr.2008_BEEB%2fimage_2.png">
            <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="442" alt="image" src="http://mark.michaelis.net/Blog/content/binary/WindowsLiveWriter/MSDNFlashKeyboardVisualStudioTipsTr.2008_BEEB/image_thumb.png" width="761" border="0" />
          </a>
        </p>
        <p>
The first dropdown on the right hand side of the dialog is where you can change your
keyboard mapping scheme.  (In this write-up, we will ignore the left hand tree
of the dialog except to say the same dialog is used for the rest of Visual Studio's
options as well.)  After selecting which scheme you want, push <strong>Reset</strong> (Alt+E)
to have all the keyboard settings for the selected scheme mapped.  
</p>
        <p>
Once you have the scheme you want, type within the <strong>Show commands containing</strong> text
box.  Notice that the commands list automatically filters down to those which
contain the value entered anywhere within the name.  In the screen shot above,
"build" is used to filter the commands to those that have "build" in them.  There
are numerous functions within Visual Studio that do not map to menu options and, therefore,
there is no intuitive way to know of their existence except from the <strong>Keyboard
Options</strong> or the <strong>Customize... options</strong> dialog.  The <strong>Show
commands containing</strong> text box makes finding commands relatively easy, however.
Consider, for example, determining the keyboard shortcut for deleting the current
line.  In the <strong>Show commands containing</strong> text box, type "delete"
or "line" and then browse through the available commands to discover that such a command
exists (<strong>Edit.LineDelete</strong>) and that by default Ctrl+Shift+L will invoke
it. 
</p>
        <p>
Within the list of commands, you can select one of the commands and view the shortcut
it is mapped to, if any.  <strong>Build.BuildSelection</strong> is shown here
to map to <strong>Shift+F6 (Global)</strong>, where "Global" here means that this
keystroke will work regardless of the context within Visual Studio (such as whether
the Text Editor or Class Designer windows are active).  It is helpful to browse
through the various commands and see what they are mapped to.  Furthermore, if
you wish to map a new or different keystroke, you can type it in the <strong>Press
shortcut keys</strong> text box.  What is helpful, is that if the key typed already
has a mapping, the existing mapping will show up in the <strong>Shortcut currently
used by</strong> text box, allowing visibility as to whether you want to change the
mapping or perhaps select a different keyboard shortcut. 
</p>
        <p>
In summary, the <strong>Keyboard Options</strong> dialog is a great technique within
Visual Studio for determining what commands are available, what commands are mapped
to which keyboard shortcuts, and for mapping new keyboard shortcuts to the commands.
</p>
        <img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=ddac7f13-ed68-4a32-9ba9-6f0b2906f408" />
        <br />
        <hr />
© Copyright 2005-2008 Mark Michaelis</body>
      <title>MSDN Flash: Keyboard Visual Studio Tips &amp;amp; Tricks for Dec 15. 2008</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=ddac7f13-ed68-4a32-9ba9-6f0b2906f408</guid>
      <link>http://mark.michaelis.net/Blog/MSDNFlashKeyboardVisualStudioTipsAmpTricksForDec152008.aspx</link>
      <pubDate>Fri, 05 Dec 2008 21:44:03 GMT</pubDate>
      <description>&lt;p&gt;
Originally, I was going to focus on shortcuts for the various build/compilation options
within Visual Studio 2008.&amp;nbsp; However, things become a little more complicated
in terms of which keyboard shortcut to use because it depends on your keyboard mapping
scheme.&amp;nbsp; In this edition, therefore, I am going to discuss the Keyboard Options
dialog - where different keyboard schemes are available for selection.&amp;nbsp; 
&lt;p&gt;
During the first launch of Visual Studio 2008, you are prompted with which keyboard
scheme to use.&amp;nbsp; The typical options are (Default), Visual C# 2005, and Visual
Basic 6. Fortunately, you can change your selection via the &lt;strong&gt;Tools-&amp;gt;Customize...&lt;/strong&gt; menu
and the &lt;strong&gt;Keyboard...&lt;/strong&gt; button on the ensuing dialog (Alt+T, Alt+C, Alt+K).
The same dialog is available from &lt;strong&gt;Tools-&amp;gt;Options...&lt;/strong&gt; and the &lt;strong&gt;Keyboard&lt;/strong&gt; node
of the environment. 
&lt;p align="center"&gt;
&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=ddac7f13-ed68-4a32-9ba9-6f0b2906f408&amp;amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fcontent%2fbinary%2fWindowsLiveWriter%2fMSDNFlashKeyboardVisualStudioTipsTr.2008_BEEB%2fimage_2.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="442" alt="image" src="http://mark.michaelis.net/Blog/content/binary/WindowsLiveWriter/MSDNFlashKeyboardVisualStudioTipsTr.2008_BEEB/image_thumb.png" width="761" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
The first dropdown on the right hand side of the dialog is where you can change your
keyboard mapping scheme.&amp;nbsp; (In this write-up, we will ignore the left hand tree
of the dialog except to say the same dialog is used for the rest of Visual Studio's
options as well.)&amp;nbsp; After selecting which scheme you want, push &lt;strong&gt;Reset&lt;/strong&gt; (Alt+E)
to have all the keyboard settings for the selected scheme mapped.&amp;nbsp; 
&lt;p&gt;
Once you have the scheme you want, type within the &lt;strong&gt;Show commands containing&lt;/strong&gt; text
box.&amp;nbsp; Notice that the commands list automatically filters down to those which
contain the value entered anywhere within the name.&amp;nbsp; In the screen shot above,
"build" is used to filter the commands to those that have "build" in them.&amp;nbsp; There
are numerous functions within Visual Studio that do not map to menu options and, therefore,
there is no intuitive way to know of their existence except from the &lt;strong&gt;Keyboard
Options&lt;/strong&gt; or the &lt;strong&gt;Customize... options&lt;/strong&gt; dialog.&amp;nbsp; The &lt;strong&gt;Show
commands containing&lt;/strong&gt; text box makes finding commands relatively easy, however.
Consider, for example, determining the keyboard shortcut for deleting the current
line.&amp;nbsp; In the &lt;strong&gt;Show commands containing&lt;/strong&gt; text box, type "delete"
or "line" and then browse through the available commands to discover that such a command
exists (&lt;strong&gt;Edit.LineDelete&lt;/strong&gt;) and that by default Ctrl+Shift+L will invoke
it. 
&lt;p&gt;
Within the list of commands, you can select one of the commands and view the shortcut
it is mapped to, if any.&amp;nbsp; &lt;strong&gt;Build.BuildSelection&lt;/strong&gt; is shown here
to map to &lt;strong&gt;Shift+F6 (Global)&lt;/strong&gt;, where "Global" here means that this
keystroke will work regardless of the context within Visual Studio (such as whether
the Text Editor or Class Designer windows are active).&amp;nbsp; It is helpful to browse
through the various commands and see what they are mapped to.&amp;nbsp; Furthermore, if
you wish to map a new or different keystroke, you can type it in the &lt;strong&gt;Press
shortcut keys&lt;/strong&gt; text box.&amp;nbsp; What is helpful, is that if the key typed already
has a mapping, the existing mapping will show up in the &lt;strong&gt;Shortcut currently
used by&lt;/strong&gt; text box, allowing visibility as to whether you want to change the
mapping or perhaps select a different keyboard shortcut. 
&lt;p&gt;
In summary, the &lt;strong&gt;Keyboard Options&lt;/strong&gt; dialog is a great technique within
Visual Studio for determining what commands are available, what commands are mapped
to which keyboard shortcuts, and for mapping new keyboard shortcuts to the commands.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=ddac7f13-ed68-4a32-9ba9-6f0b2906f408" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=ddac7f13-ed68-4a32-9ba9-6f0b2906f408</comments>
      <category>Computer Related</category>
      <category>Computer Related/.Net</category>
    </item>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=b59b2ba2-7f90-4755-81c3-007987cbc54c</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=b59b2ba2-7f90-4755-81c3-007987cbc54c</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=b59b2ba2-7f90-4755-81c3-007987cbc54c</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=b59b2ba2-7f90-4755-81c3-007987cbc54c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Frequently, while browsing code, we want to drill down into a method to see the implementation
and then jump back out again to continue browsing code at the caller. One invaluable
keystroke for doing this is F12. Placing your cursor on any identifier, you can use
F12 to drill into its declaration. This works both for types as well as their members.
In fact, you can use the same keystroke to jump to the definition of types in the
.NET Framework. This is a great way to browse through the type's members to see header
information, including the documentation of the parameters. To jump back, you can
use Ctrl+-. In this way you can navigate back and forth through your code.
</p>
        <p align="center">
          <a href="http://mark.michaelis.net/Blog/ct.ashx?id=b59b2ba2-7f90-4755-81c3-007987cbc54c&amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fcontent%2fbinary%2fMSDNFlashVisualStudioTipsTricks_13DB7%2fimage.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="272" alt="image" src="http://mark.michaelis.net/Blog/content/binary/MSDNFlashVisualStudioTipsTricks_13DB7/image_thumb.png" width="571" border="0" />
          </a>  
</p>
        <p align="center">
 <a href="http://mark.michaelis.net/Blog/ct.ashx?id=b59b2ba2-7f90-4755-81c3-007987cbc54c&amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fcontent%2fbinary%2fMSDNFlashVisualStudioTipsTricks_13DB7%2fimage_3.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="110" alt="image" src="http://mark.michaelis.net/Blog/content/binary/MSDNFlashVisualStudioTipsTricks_13DB7/image_thumb_3.png" width="95" border="0" /></a></p>
        <p align="center">
          <a href="http://mark.michaelis.net/Blog/ct.ashx?id=b59b2ba2-7f90-4755-81c3-007987cbc54c&amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fcontent%2fbinary%2fMSDNFlashVisualStudioTipsTricks_13DB7%2fimage_4.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="272" alt="image" src="http://mark.michaelis.net/Blog/content/binary/MSDNFlashVisualStudioTipsTricks_13DB7/image_thumb_4.png" width="571" border="0" />
          </a>
        </p>
        <p align="center">
 <a href="http://mark.michaelis.net/Blog/ct.ashx?id=b59b2ba2-7f90-4755-81c3-007987cbc54c&amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fcontent%2fbinary%2fMSDNFlashVisualStudioTipsTricks_13DB7%2fimage_5.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="107" alt="image" src="http://mark.michaelis.net/Blog/content/binary/MSDNFlashVisualStudioTipsTricks_13DB7/image_thumb_5.png" width="101" border="0" /></a></p>
        <p align="center">
          <a href="http://mark.michaelis.net/Blog/ct.ashx?id=b59b2ba2-7f90-4755-81c3-007987cbc54c&amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fcontent%2fbinary%2fMSDNFlashVisualStudioTipsTricks_13DB7%2fimage.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="272" alt="image" src="http://mark.michaelis.net/Blog/content/binary/MSDNFlashVisualStudioTipsTricks_13DB7/image_thumb.png" width="571" border="0" />
          </a>  
</p>
        <p>
As quoted from a post by me on MSDN Flash, Nov 17, 2007.
</p>
        <img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=b59b2ba2-7f90-4755-81c3-007987cbc54c" />
        <br />
        <hr />
© Copyright 2005-2008 Mark Michaelis</body>
      <title>MSDN Flash: Keyboard Visual Studio Tips &amp;amp; Tricks for Nov 17. 2007</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=b59b2ba2-7f90-4755-81c3-007987cbc54c</guid>
      <link>http://mark.michaelis.net/Blog/MSDNFlashKeyboardVisualStudioTipsAmpTricksForNov172007.aspx</link>
      <pubDate>Tue, 18 Nov 2008 02:49:32 GMT</pubDate>
      <description>&lt;p&gt;
Frequently, while browsing code, we want to drill down into a method to see the implementation
and then jump back out again to continue browsing code at the caller. One invaluable
keystroke for doing this is F12. Placing your cursor on any identifier, you can use
F12 to drill into its declaration. This works both for types as well as their members.
In fact, you can use the same keystroke to jump to the definition of types in the
.NET Framework. This is a great way to browse through the type's members to see header
information, including the documentation of the parameters. To jump back, you can
use Ctrl+-. In this way you can navigate back and forth through your code.
&lt;/p&gt;
&lt;p align="center"&gt;
&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=b59b2ba2-7f90-4755-81c3-007987cbc54c&amp;amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fcontent%2fbinary%2fMSDNFlashVisualStudioTipsTricks_13DB7%2fimage.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="272" alt="image" src="http://mark.michaelis.net/Blog/content/binary/MSDNFlashVisualStudioTipsTricks_13DB7/image_thumb.png" width="571" border="0"&gt;&lt;/a&gt;&amp;nbsp; 
&lt;/p&gt;
&lt;p align="center"&gt;
&amp;nbsp;&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=b59b2ba2-7f90-4755-81c3-007987cbc54c&amp;amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fcontent%2fbinary%2fMSDNFlashVisualStudioTipsTricks_13DB7%2fimage_3.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="110" alt="image" src="http://mark.michaelis.net/Blog/content/binary/MSDNFlashVisualStudioTipsTricks_13DB7/image_thumb_3.png" width="95" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p align="center"&gt;
&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=b59b2ba2-7f90-4755-81c3-007987cbc54c&amp;amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fcontent%2fbinary%2fMSDNFlashVisualStudioTipsTricks_13DB7%2fimage_4.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="272" alt="image" src="http://mark.michaelis.net/Blog/content/binary/MSDNFlashVisualStudioTipsTricks_13DB7/image_thumb_4.png" width="571" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p align="center"&gt;
&amp;nbsp;&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=b59b2ba2-7f90-4755-81c3-007987cbc54c&amp;amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fcontent%2fbinary%2fMSDNFlashVisualStudioTipsTricks_13DB7%2fimage_5.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="107" alt="image" src="http://mark.michaelis.net/Blog/content/binary/MSDNFlashVisualStudioTipsTricks_13DB7/image_thumb_5.png" width="101" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p align="center"&gt;
&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=b59b2ba2-7f90-4755-81c3-007987cbc54c&amp;amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fcontent%2fbinary%2fMSDNFlashVisualStudioTipsTricks_13DB7%2fimage.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="272" alt="image" src="http://mark.michaelis.net/Blog/content/binary/MSDNFlashVisualStudioTipsTricks_13DB7/image_thumb.png" width="571" border="0"&gt;&lt;/a&gt;&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
As quoted from a post by me on MSDN Flash, Nov 17, 2007.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=b59b2ba2-7f90-4755-81c3-007987cbc54c" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=b59b2ba2-7f90-4755-81c3-007987cbc54c</comments>
      <category>Computer Related</category>
      <category>Computer Related/.Net</category>
    </item>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=d3e7ee22-8581-4884-a117-785aa80e4e01</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=d3e7ee22-8581-4884-a117-785aa80e4e01</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=d3e7ee22-8581-4884-a117-785aa80e4e01</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=d3e7ee22-8581-4884-a117-785aa80e4e01</wfw:commentRss>
      <slash:comments>8</slash:comments>
      <title>Dynamically Typed Objects with C# 4.0</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=d3e7ee22-8581-4884-a117-785aa80e4e01</guid>
      <link>http://mark.michaelis.net/Blog/DynamicallyTypedObjectsWithC40.aspx</link>
      <pubDate>Tue, 04 Nov 2008 07:14:16 GMT</pubDate>
      <description>&lt;p&gt;
One of the announcements that emerged from the PDC is C# 4.0's support for dynamically
typed objects.&amp;nbsp; These are objects whose type is not determined until runtime.&amp;nbsp;
Variables that point to such types are declared with a new contextual keyword, &lt;font face="Courier New"&gt;dynamic&lt;/font&gt;.&amp;nbsp;
Support was added so that API calls into dynamically type languages (such as scripting
languages) could be supported.&amp;nbsp; Another example where dynamically typed object
support is useful is calling into &lt;font face="Courier New"&gt;IDispatch&lt;/font&gt; objects
(something supported by VB but not C# until now).
&lt;/p&gt;
&lt;p&gt;
In order to investigate how dynamic objects worked I decided to create a working sample
that dynamically went against an XML element. Working with &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=d3e7ee22-8581-4884-a117-785aa80e4e01&amp;amp;url=http%3a%2f%2fwww.breaman.net"" target="_blank"&gt;Michael
Stokesbary&lt;/a&gt;, I was able to put together the following sample:
&lt;/p&gt;
&lt;p&gt;
Consider the following XElement:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;XElement element = XElement.Parse(
    &lt;span class="str"&gt;@"&amp;lt;Person&amp;gt;
&amp;lt;FirstName&amp;gt;Inigo&amp;lt;/FirstName&amp;gt; &amp;lt;LastName&amp;gt;Montoya&amp;lt;/LastName&amp;gt;
&amp;lt;/Person&amp;gt;"&lt;/span&gt;);&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
From here we can assign it to a dynamic variable and read out the data as follows:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;dynamic&lt;/span&gt; personXml = &lt;span class="kwrd"&gt;new&lt;/span&gt; DynamicXml(element);
Console.WriteLine(&lt;span class="str"&gt;"Hello, my name is {0} {1}"&lt;/span&gt;, personXml.FirstName,
personXml.LastName);&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
and
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;personXml.FirstName = &lt;span class="str"&gt;"Bob"&lt;/span&gt;;&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
As this code shows, with a dynamic type over XML, you can use XML element names as
the property names to retrieve data from the XML element.
&lt;/p&gt;
&lt;p&gt;
To implement the DynamicXML type, all you need to do is define an type that implements &lt;font face="Courier New"&gt;System.Scripting.Actions.IDynamicObject&lt;/font&gt; with
its one &lt;font face="Courier New"&gt;MetaObject GetMetaObject(Expression parameter)&lt;/font&gt; method.&amp;nbsp;
The easier way to do this is to derive from &lt;font face="Courier New"&gt;Dynamic&lt;/font&gt;,
a class that is currently available in the Iron Python implementation.&amp;nbsp; (In the
future, we should expect that Microsoft will provide such a class in the framework
but no specific plans on this have been announced.)&amp;nbsp; Once deriving from &lt;font face="Courier New"&gt;Dynamic&lt;/font&gt;,
the only remaining task is to override the &lt;font face="Courier New"&gt;object GetMember(GetMemberAction
action)&lt;/font&gt; and &lt;font face="Courier New"&gt;void SetMember(SetMemberAction action,
object value)&lt;/font&gt; members.&amp;nbsp; Rudimentary implementations are shown below:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System; &lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic; &lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq; &lt;span class="kwrd"&gt;using&lt;/span&gt; System.Scripting.Actions; &lt;span class="kwrd"&gt;using&lt;/span&gt; System.Xml.Linq; &lt;span class="kwrd"&gt;using&lt;/span&gt; System.Xml.XPath;&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; DynamicXml
: Dynamic { &lt;span class="kwrd"&gt;private&lt;/span&gt; XElement Element { get; set; } &lt;span class="kwrd"&gt;public&lt;/span&gt; DynamicXml(System.Xml.Linq.XElement
element) { Element = element; } &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt; GetMember(GetMemberAction
action) { &lt;span class="kwrd"&gt;object&lt;/span&gt; result = &lt;span class="kwrd"&gt;null&lt;/span&gt;;
XElement firstDescendant = Element.Descendants(action.Name).FirstOrDefault(); &lt;span class="kwrd"&gt;if&lt;/span&gt; (firstDescendant
!= &lt;span class="kwrd"&gt;null&lt;/span&gt;) { &lt;span class="kwrd"&gt;if&lt;/span&gt; (firstDescendant.Descendants().Count()
&amp;gt; 0) { result = &lt;span class="kwrd"&gt;new&lt;/span&gt; DynamicXml(firstDescendant); } &lt;span class="kwrd"&gt;else&lt;/span&gt; {
result = firstDescendant.Value; } } &lt;span class="kwrd"&gt;return&lt;/span&gt; result; } &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SetMember(SetMemberAction
action, &lt;span class="kwrd"&gt;object&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;) { XElement
firstDescendant = Element.Descendants(action.Name).FirstOrDefault(); &lt;span class="kwrd"&gt;if&lt;/span&gt; (firstDescendant
!= &lt;span class="kwrd"&gt;null&lt;/span&gt;) { &lt;span class="kwrd"&gt;if&lt;/span&gt;(&lt;span class="kwrd"&gt;value&lt;/span&gt;.GetType()
== &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(XElement)) { firstDescendant.ReplaceWith(&lt;span class="kwrd"&gt;value&lt;/span&gt;);
} &lt;span class="kwrd"&gt;else&lt;/span&gt; { firstDescendant.Value = &lt;span class="kwrd"&gt;value&lt;/span&gt;.ToString();
} } &lt;span class="kwrd"&gt;else&lt;/span&gt; { &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ArgumentException(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;"Element
name, '{0}', does not exist."&lt;/span&gt;, action.Name)); } } }&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
That's it... that's all that is needed to understand how to implement a dynamic object.
&lt;/p&gt;
&lt;p&gt;
Caveats:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Multiple elements with the same name are not supported in this implementation.&amp;nbsp;
To do so we wanted to use the index operator with the dynamic type but this is not
supported in the PDC 2008 CTP bits - it will be. 
&lt;li&gt;
This example does not work with attributes.&amp;nbsp; What would the syntax be if it did?&amp;nbsp;
One cool idea of Mike's was to use the verbatim identifier as in &lt;font face="Courier New"&gt;personXml.@FirstName&lt;/font&gt;.
- the XPath like way to retrieve attributes. Unfortunately, this wouldn't work work
since the @ sign is removed at compile time so the IDynamicObject.GetMember() call
receives &lt;font face="Courier New"&gt;FirstName&lt;/font&gt; for the action &lt;font face="Courier New"&gt;Name&lt;/font&gt;. 
&lt;li&gt;
There is no support for reading the root element name.&amp;nbsp; The example assumes you
only navigate into the children (to avoid infinite recursion) when navigating.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
In the process of writing this dynamic XML implementation, I found a few idiosyncrasies
in the current dynamic type support found in the PDC 2008 CTP:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
There is no type checking for dynamic arguments.&amp;nbsp; Consider the sample code below:&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt; string&lt;/span&gt; text1
= &lt;span class="str"&gt;"Text"&lt;/span&gt;; &lt;span class="kwrd"&gt;dynamic&lt;/span&gt; text2 = text1;
Assert.AreEqual&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(text1, text2);&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Not only does the code sample compile (by design), but it throws an exception of type &lt;font face="Courier New"&gt;ArgumentNullException&lt;/font&gt; (not
by design - &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=d3e7ee22-8581-4884-a117-785aa80e4e01&amp;amp;url=http%3a%2f%2fblogs.msdn.com%2fmadst%2f"" target="_blank"&gt;Mads&lt;/a&gt; agree's
this probably isn't correct).
&lt;/p&gt;
&lt;/blockquote&gt;&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=d3e7ee22-8581-4884-a117-785aa80e4e01" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=d3e7ee22-8581-4884-a117-785aa80e4e01</comments>
      <category>Computer Related</category>
      <category>Computer Related/.Net</category>
      <category>Headlines</category>
    </item>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=09f4b66b-4d9f-401c-a1cc-ffee94ff9dbe</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=09f4b66b-4d9f-401c-a1cc-ffee94ff9dbe</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=09f4b66b-4d9f-401c-a1cc-ffee94ff9dbe</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=09f4b66b-4d9f-401c-a1cc-ffee94ff9dbe</wfw:commentRss>
      <title>Downloading Team Explorer 2005/2008</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=09f4b66b-4d9f-401c-a1cc-ffee94ff9dbe</guid>
      <link>http://mark.michaelis.net/Blog/DownloadingTeamExplorer20052008.aspx</link>
      <pubDate>Wed, 17 Sep 2008 04:25:04 GMT</pubDate>
      <description>&lt;p&gt;
While at Microsoft today, I was talking with a fellow developer who was complaining
that they couldn't download Team Explorer 2005 from MSDN, even as a VSTS subscriber.&amp;nbsp;
They wanted v2005 because, although they had Team Foundation Server (TFS) 2008, they
were still using Visual Studio 2005.
&lt;/p&gt;
&lt;p&gt;
As it turns out, this isn't this isn't quite true.&amp;nbsp; If you download Team Foundation
Server 2005 (either Trial or Workgroup editions), there is a &lt;font face="Courier New"&gt;TFC&lt;/font&gt; directory
on the ISO file for the Team Explorer install.&amp;nbsp; However, there is a better solution
and it doesn't even require logging on to MSDN.&amp;nbsp; It turns out that to connect
to &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=09f4b66b-4d9f-401c-a1cc-ffee94ff9dbe&amp;amp;url=http%3a%2f%2fcodeplex.com%2f"&gt;codeplex&lt;/a&gt; you
also have the option of using Team Explorer.&amp;nbsp; Since developers won't necessarily
have MSDN subscriptions, &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=09f4b66b-4d9f-401c-a1cc-ffee94ff9dbe&amp;amp;url=http%3a%2f%2fwww.codeplex.com%2fCodePlex%2fWiki%2fView.aspx%3ftitle%3dObtaining%2520the%2520Team%2520Explorer%2520Client"&gt;codeplex
links to downloads of img/iso files for Team Explorer&lt;/a&gt;:
&lt;/p&gt;
&lt;li&gt;
&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=09f4b66b-4d9f-401c-a1cc-ffee94ff9dbe&amp;amp;url=http%3a%2f%2fwww.microsoft.com%2fdownloads%2fdetails.aspx%3ffamilyid%3d0ed12659-3d41-4420-bbb0-a46e51bfca86%26displaylang%3den"&gt;Team
Explorer 2008&lt;/a&gt; (387 MB iso file) 
&lt;li&gt;
&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=09f4b66b-4d9f-401c-a1cc-ffee94ff9dbe&amp;amp;url=http%3a%2f%2fdownload.microsoft.com%2fdownload%2f2%2fa%2fd%2f2ad44873-8ccb-4a1b-9c0d-23224b3ba34c%2fVSTFClient.img"&gt;Team
Explorer 2005&lt;/a&gt; (246 MB .img file) 
&lt;p&gt;
By the way, in VSTS 2008, Microsoft includes Team Explorer on the VSTS media.&amp;nbsp;
It is located in the Team Foundation Client directory, &lt;font face="Courier New"&gt;TFS\&lt;/font&gt;.
&lt;/p&gt;
&lt;/li&gt;
&lt;p&gt;
&lt;u&gt;UPDATED 2008-09-30&lt;/u&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=09f4b66b-4d9f-401c-a1cc-ffee94ff9dbe&amp;amp;url=http%3a%2f%2fblogs.msdn.com%2fbriankel%2f"" target="_blank"&gt;Brian
Keller&lt;/a&gt; emailed me today to let me know that Microsoft has added a &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=09f4b66b-4d9f-401c-a1cc-ffee94ff9dbe&amp;amp;url=http%3a%2f%2fwww.microsoft.com%2fdownloads%2fdetails.aspx%3fFamilyId%3d46473C2A-BB85-4461-BB27-4792A5DEF222%26displaylang%3den"" target="_blank"&gt;details
page for Visual Studio Team System 2005 Team Explorer&lt;/a&gt;, making the download easier
to find.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=09f4b66b-4d9f-401c-a1cc-ffee94ff9dbe" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=09f4b66b-4d9f-401c-a1cc-ffee94ff9dbe</comments>
      <category>Computer Related</category>
      <category>Computer Related/Miscellaneous</category>
    </item>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=d7e3afe2-bd0e-46d1-9752-0f618b4ed938</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=d7e3afe2-bd0e-46d1-9752-0f618b4ed938</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=d7e3afe2-bd0e-46d1-9752-0f618b4ed938</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=d7e3afe2-bd0e-46d1-9752-0f618b4ed938</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <title>Turning Off IE Enhanced Security from the Command Line</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=d7e3afe2-bd0e-46d1-9752-0f618b4ed938</guid>
      <link>http://mark.michaelis.net/Blog/TurningOffIEEnhancedSecurityFromTheCommandLine.aspx</link>
      <pubDate>Fri, 12 Sep 2008 04:55:54 GMT</pubDate>
      <description>&lt;p&gt;
For the most part I have much of the install for Windows 2008 operating system and
programs automated (unattended).&amp;nbsp; However, one thing that I found a little more
difficult to find was a command line way to turn off IE's Enhanced Security (manually
turned off from &lt;strong&gt;Server Manager -&amp;gt; Configure IE ESC&lt;/strong&gt;. 
&lt;/p&gt;
&lt;p&gt;
I found an &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=d7e3afe2-bd0e-46d1-9752-0f618b4ed938&amp;amp;url=http%3a%2f%2fwww.itedge.net%2fblog%2f2007%2f08%2f08%2fdisable-ie7-protected-mode-on-windows-server-2008%2f"" target="_blank"&gt;unattended
method&lt;/a&gt; and created a batch file:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;font color="#008000"&gt;:: Backup registry keys &lt;/font&gt;
&lt;br&gt;
REG EXPORT "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}"
"%TEMP%.HKEY_LOCAL_MACHINE.SOFTWARE.Microsoft.Active Setup.Installed Components.A509B1A7-37EF-4b3f-8CFC-4F3A74704073.reg" 
&lt;br&gt;
REG EXPORT "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}"
"%TEMP%.HKEY_LOCAL_MACHINE.SOFTWARE.Microsoft.Active Setup.Installed Components.A509B1A8-37EF-4b3f-8CFC-4F3A74704073.reg" 
&lt;p&gt;
REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}"
/v "IsInstalled" /t REG_DWORD /d 0 /f&lt;br&gt;
REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}"
/v "IsInstalled" /t REG_DWORD /d 0 /f 
&lt;p&gt;
Rundll32 iesetup.dll, IEHardenLMSettings&lt;br&gt;
Rundll32 iesetup.dll, IEHardenUser&lt;br&gt;
Rundll32 iesetup.dll, IEHardenAdmin 
&lt;p&gt;
REG DELETE "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}"
/f /va&lt;br&gt;
REG DELETE "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}"
/f /va 
&lt;p&gt;
&lt;font color="#008000"&gt;:: Optional to remove warning on first IE Run and set home page
to blank.&lt;br&gt;
&lt;/font&gt;REG DELETE "HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main" /v
"First Home Page" /f&lt;br&gt;
REG ADD "HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main" /v "Default_Page_URL"
/t REG_SZ /d "about:blank" /f&lt;br&gt;
REG ADD "HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main" /v "Start Page"
/t REG_SZ /d "about:blank" /f
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
This seems to work well for Windows 2008.&amp;nbsp; I haven't tried it on other operating
systems.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=d7e3afe2-bd0e-46d1-9752-0f618b4ed938" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=d7e3afe2-bd0e-46d1-9752-0f618b4ed938</comments>
      <category>Computer Related</category>
      <category>Computer Related/Miscellaneous</category>
      <category>Headlines</category>
    </item>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=c2aedf40-7139-4a40-b706-7cbc58d6dcf8</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=c2aedf40-7139-4a40-b706-7cbc58d6dcf8</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=c2aedf40-7139-4a40-b706-7cbc58d6dcf8</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=c2aedf40-7139-4a40-b706-7cbc58d6dcf8</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <title>Mock Object Frameworks: NMock, RhinoMock, TypeMock</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=c2aedf40-7139-4a40-b706-7cbc58d6dcf8</guid>
      <link>http://mark.michaelis.net/Blog/MockObjectFrameworksNMockRhinoMockTypeMock.aspx</link>
      <pubDate>Wed, 03 Sep 2008 19:42:04 GMT</pubDate>
      <description>&lt;p&gt;
Recently I wanted to select a mock object framework for a new project I am starting
on.&amp;nbsp; As an early developer (it wasn't really key to the customer) &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=c2aedf40-7139-4a40-b706-7cbc58d6dcf8&amp;amp;url=http%3a%2f%2fwww.extremeprogramming.org%2frules%2fspike.html"&gt;spike&lt;/a&gt;,
I decided to investigate different .NET mock object libraries: &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=c2aedf40-7139-4a40-b706-7cbc58d6dcf8&amp;amp;url=http%3a%2f%2fwww.nmock.org%2f"" target="_blank"&gt;NMock&lt;/a&gt;, &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=c2aedf40-7139-4a40-b706-7cbc58d6dcf8&amp;amp;url=http%3a%2f%2fwww.ayende.com%2fprojects%2frhino-mocks.aspx"" target="_blank"&gt;Rhino.Mocks&lt;/a&gt;,
and &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=c2aedf40-7139-4a40-b706-7cbc58d6dcf8&amp;amp;url=http%3a%2f%2fwww.typemock.com"" target="_blank"&gt;TypeMock&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
To appreciate these differences, consider the code samples in which the goal is to
mock out a "stock provider" class (or interface) that returns stock prices (which
cannot be controlled so they are tough to test).&amp;nbsp; Although the code appears to
go from simpler to more complex,&amp;nbsp; that is simply because what TypeMock accomplishes
more with less impact on the target API.&amp;nbsp; Each tool can handle the code semantics
of the previous tool.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;NMock (&lt;/strong&gt;2.0 Release Candidate 2, Jan 31, 2008)
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Requires the object to be mocked so support an interface.&amp;nbsp; Mock objects are generated
at runtime to implement the interface.&amp;nbsp; Programmatically you inject method implementations
on the mock object so that it expects certain calls and returns values for those calls.&amp;nbsp;
This works great until the class you want to mock does not implement an interface.&amp;nbsp;
In addition, you will need to code your API such that it allows for tests to pass
in the mock objects for the target API to use. 
&lt;br&gt;
[Free]
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;Mockery mocks = &lt;span class="kwrd"&gt;new&lt;/span&gt; Mockery(); IStockProvider
provider = mocks.NewMock&amp;lt;IStockProvider&amp;gt;(); &lt;span class="rem"&gt;// Notice how
it is necessary to pass the mock object's interface into the target.&lt;/span&gt; StockService
stockService = &lt;span class="kwrd"&gt;new&lt;/span&gt; StockService(provider); Expect.Once.On(provider).
Method(&lt;span class="str"&gt;"GetCurrentPrice"&lt;/span&gt;). With(&lt;span class="str"&gt;"ITRI"&lt;/span&gt;).
Will(Return.Value(106.20)); Assert.AreEqual&amp;lt;&lt;span class="kwrd"&gt;float&lt;/span&gt;&amp;gt;(106.20,
stockService.GetCurrentPrice(&lt;span class="str"&gt;"ITRI"&lt;/span&gt;)); &lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;Rhino.Mocks&lt;/strong&gt; (3..5 Release Candidate for .NET 3.5, June 28, 2008)
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
In addition to all the NMock provides, Rhino.Mocks allows for generating a mock object
of a class without the interface a requirement.&amp;nbsp; What is powerful about this
technique, is that you can request Rhino.Mock to create a mock object of a class (even
something like &lt;font face="Courier New"&gt;System.Net.WebClient&lt;/font&gt;) and then pass
that mock object into the implementation of your class.&amp;nbsp; Now any calls to &lt;font face="Courier New"&gt;System.Net.WebClient&lt;/font&gt; will
be to your mock object even though the target library was compiled to use &lt;font face="Courier New"&gt;System.Net.WebClient&lt;/font&gt;.&amp;nbsp;
Furthermore, the setting up of method call expectations is compiled, rather than just
string names for the methods.&amp;nbsp; Like NMock, however, the target API needs to allow
for the test to pass in the mock object you wish for the target to use.&amp;nbsp; If the
target instantiated the mock object directly, then no mock object interception would
be available.&lt;br&gt;
[Free]
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;MockRepository repository = &lt;span class="kwrd"&gt;new&lt;/span&gt; MockRepository();
StockProvider provider = mocks.CreateMock&amp;lt;StockProvider&amp;gt;(); &lt;span class="rem"&gt;//
Notice how it is necessary to pass the runtime generated mock object (not the interface)
into the target.&lt;/span&gt; StockService stockService = &lt;span class="kwrd"&gt;new&lt;/span&gt; StockService(provider);&lt;span class="rem"&gt;//
Notice that the method call is compiled rather than just a string. &lt;/span&gt; Expect.Call(provider.GetCurrentPrice(&lt;span class="str"&gt;"ITRI"&lt;/span&gt;).Return(106.20));
Assert.AreEqual&amp;lt;&lt;span class="kwrd"&gt;float&lt;/span&gt;&amp;gt;(106.20, stockService.GetCurrentPrice(&lt;span class="str"&gt;"ITRI"&lt;/span&gt;));repository.VerifyAll(); &lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;TypeMock&lt;/strong&gt; (Typemock Isolator 5.0)
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
In addition to all the functionality of Rhino.Mocks, TypeMock allows for the runtime
generation of type objects on the fly within the target project, not just within the
test.&amp;nbsp; As a result, you can identify the types you wish TypeMock engine to intercept
and then, whenever the target library instantiates those objects, a mock object will
be created instead.&amp;nbsp; This allows you to code the target library without any API
changes that would make testing easier but not necessarily improve the API&lt;br&gt;
[&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=c2aedf40-7139-4a40-b706-7cbc58d6dcf8&amp;amp;url=http%3a%2f%2fwww.typemock.com%2fBuy.php"" target="_blank"&gt;Commercial&lt;/a&gt;][Free
(for open source projects)]
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;MockManager.Init();
&lt;span class="kwrd"&gt;using&lt;/span&gt; (RecordExpectations
recorder = &lt;span class="kwrd"&gt;new&lt;/span&gt; RecordExpectations()) { StockProvider provider
= &lt;span class="kwrd"&gt;new&lt;/span&gt; StockProvider(); &lt;span class="rem"&gt;// As with Rhino.Mocks,
the expected calls are compiled. &lt;/span&gt; recorder.ExpectAndReturn(provider.GetCurrentPrice(&lt;span class="str"&gt;"ITRI"&lt;/span&gt;),
106.20); } &lt;span class="rem"&gt;// Notice how it is not necessary to pass the runtime
generated mock object. The target can just &lt;/span&gt; &lt;span class="rem"&gt;// call create
StockProvider and the call will be intercepted with a mock object instantiation.&lt;/span&gt; StockService
stockService = &lt;span class="kwrd"&gt;new&lt;/span&gt; StockService();Assert.AreEqual&amp;lt;&lt;span class="kwrd"&gt;float&lt;/span&gt;&amp;gt;(106.20,
stockService.GetCurrentPrice(&lt;span class="str"&gt;"ITRI"&lt;/span&gt;)); MockManager.Verify();&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
To grok the differences, I encourage you to read the comments to understand the subtle
yet significant differences.
&lt;/p&gt;
&lt;p&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=c2aedf40-7139-4a40-b706-7cbc58d6dcf8" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=c2aedf40-7139-4a40-b706-7cbc58d6dcf8</comments>
      <category>Computer Related</category>
      <category>Computer Related/.Net</category>
      <category>Headlines</category>
    </item>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=aca65754-0937-471b-8dfd-900a73825d8d</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=aca65754-0937-471b-8dfd-900a73825d8d</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=aca65754-0937-471b-8dfd-900a73825d8d</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=aca65754-0937-471b-8dfd-900a73825d8d</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <title>Data Connection String for a CSV file on VSTS Data Driven Test</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=aca65754-0937-471b-8dfd-900a73825d8d</guid>
      <link>http://mark.michaelis.net/Blog/DataConnectionStringForACSVFileOnVSTSDataDrivenTest.aspx</link>
      <pubDate>Thu, 21 Aug 2008 17:35:28 GMT</pubDate>
      <description>&lt;p&gt;
In Visual Studio 2008 you can specify a database, CSV, or XML file for the data connection
string.&amp;nbsp; I decided to try using a CSV file because I had a sample CSV file of
test data.&amp;nbsp; Unfortunately, on initial import I received an error message, “Error
trying to sample data from &amp;lt;file name&amp;gt;, please make sure the file is valid.”&amp;nbsp;
Hmmm…?&amp;nbsp; I tried several CSV file formats, changed the quote style, and the like
- but still, I couldn’t get it to work.&amp;nbsp; 
&lt;/p&gt;
&lt;p align="center"&gt;
&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=aca65754-0937-471b-8dfd-900a73825d8d&amp;amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fcontent%2fbinary%2fWindowsLiveWriter%2fDataConnectionStringforaCSVfileonVSTSDat_94EB%2fimage_4.png"" target="_blank"&gt;&lt;img title="Error trying to sample data from &amp;lt;file name&amp;gt;, please make sure the file is valid" style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="411" alt="Error trying to sample data from &amp;lt;file name&amp;gt;, please make sure the file is valid" src="http://mark.michaelis.net/Blog/content/binary/WindowsLiveWriter/DataConnectionStringforaCSVfileonVSTSDat_94EB/image_thumb_1.png" width="460" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
It turns out, it was my file name.&amp;nbsp; I had two periods in the file name, &lt;font face="Courier New"&gt;NYSE.SymbolList.csv&lt;/font&gt;.&amp;nbsp;
As soon as I removed the extra period, the file imported without issue.&amp;nbsp; By the
way, quoting the file name also fails – the Next button remains disabled.
&lt;/p&gt;
&lt;p&gt;
Also, column headers are expected in the import file.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=aca65754-0937-471b-8dfd-900a73825d8d" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=aca65754-0937-471b-8dfd-900a73825d8d</comments>
      <category>Computer Related</category>
      <category>Computer Related/.Net</category>
    </item>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=3b149bf2-436f-40f1-be98-6a4cfb5c0e11</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=3b149bf2-436f-40f1-be98-6a4cfb5c0e11</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=3b149bf2-436f-40f1-be98-6a4cfb5c0e11</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=3b149bf2-436f-40f1-be98-6a4cfb5c0e11</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A recent install of Team Foundation Explorer errored out.  Opening the log file
(from the link on the error screen) and scrolling to the bottom, showed the following:
</p>
        <blockquote>
          <p>
            <font face="Courier New">[07/16/08,15:39:33] Microsoft Visual Studio 2008 Team Explorer
- ENU: CRootComponent::Install(): Beginning Brooklyn Component Installation<br />
[07/16/08,15:39:33] Setup.exe: ISetupManager::GetFullComponents()<br />
[07/16/08,15:39:33] Setup.exe: ISetupManager::GetFullComponents()<br />
[07/16/08,15:39:34] DepCheck: gencomp97,{12CDA52C-7A8F-4785-8A22-53C87393FEE0}<br />
[07/16/08,15:39:34] DepCheck_Result: 1<br />
[07/16/08,15:39:34] Microsoft Visual Studio 2008 Team Explorer - ENU: Install(): bAttemptInstall:
0<br />
[07/16/08,15:39:34] Microsoft Visual Studio 2008 Team Explorer - ENU: Install(): Not
attempting to call MsiInstallProduct()!!!! <font color="#ff0000"><strong>Baseline
not met</strong></font>!<br />
[07/16/08,15:39:34] Setup.exe: AddGlobalCustomProperty<br />
[07/16/08,15:39:34] Microsoft Visual Studio 2008 Team Explorer - ENU: CRootComponent::Install():
Setup Failed; MSIInstallProduct return value either ERROR_INSTALL_FAILURE or default.<br />
[07/16/08,15:39:34] Setup.exe: AddGlobalCustomProperty<br />
[07/16/08,15:39:34] Microsoft Visual Studio 2008 Team Explorer - ENU: CRootComponent::Install():
Calling LaunchWatson()...<br />
[07/16/08,15:39:34] Microsoft Visual Studio 2008 Team Explorer - ENU: CRootComponent::LaunchWatson()
- Obtained CSetupWatson instance<br />
[07/16/08,15:39:34] Setup.exe: GetGlobalCustomProperty - Property: {AA62DF98-3F2C-11D3-887B-00C04F8ECDD6}
- PropertyName: Maintenance Mode - Value: 0<br />
[07/16/08,15:39:34] Microsoft Visual Studio 2008 Team Explorer - ENU: CRootComponent::LaunchWatson()
- Launching VS Watson<br />
[07/16/08,15:39:34] Microsoft Visual Studio 2008 Team Explorer - ENU: CRootComponent::LaunchWatson()
- Completed VS Watson launching to create manifest: C:\DOCUME~1\mmichael\LOCALS~1\Temp\vs_setup.dll.txt<br />
[07/16/08,15:39:34] Setup.exe: AddGlobalCustomProperty<br />
[07/16/08,15:39:34] Microsoft Visual Studio 2008 Team Explorer - ENU: CRootComponent::LaunchWatson()
- Setting the property CustomCoreProp_WatsonManifestReady to use the VS Client Manifest.<br />
[07/16/08,15:39:34] Microsoft Visual Studio 2008 Team Explorer - ENU: CRootComponent::Install():
Finished calling LaunchWatson()<br />
[07/16/08,15:39:34] Microsoft Visual Studio 2008 Team Explorer - ENU: CRootComponent::Install():
Finished Brooklyn Component Installation<br />
[07/16/08,15:39:34] UTILS::RunNGENAction: Started<br />
[07/16/08,15:39:34] UTILS::RunNGENAction: starting "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ngen.exe
queue pause"<br />
[07/16/08,15:39:34] UTILS::RunNGENAction: ngen.exe returned 0<br />
[07/16/08,15:39:34] Setup.exe: AddGlobalCustomProperty<br />
[07/16/08,15:39:34] setup.exe: <font color="#ff0000"><strong>***ERRORLOG EVENT***
: ISetupComponent::Pre/Post/Install() failed in ISetupManager::InternalInstallManager()
with HRESULT -2147023293</strong></font>.<br />
[07/16/08,15:39:35] Setup.exe: GetGlobalCustomProperty - Property: {7F82DEDD-12EB-439F-B7A3-8B4264E0C20D}
- PropertyName: EnableRollback - Value: 
<br />
[07/16/08,15:39:35] Setup.exe: GetGlobalCustomProperty - Property: {BD495746-4FBA-49F3-8EEB-D8B20EE75235}
- PropertyName: Disable Rollback - Value: 
<br />
[07/16/08,15:39:35] Setup.exe: ISetupManager::RunInstallFromList(IP_INSTALL) completed<br />
[07/16/08,15:39:35] Setup.exe: GetGlobalCustomProperty - Property: {092114C2-997D-4D68-8F3A-8BC2584FD23B}
- PropertyName: Quiet Mode Setup - Value: 
<br />
[07/16/08,15:39:35] TFSUI: ISetupManager::GetGlobalCustomProperty() failed to find
global prop in CProgressPage::RunningComponent()<br />
[07/16/08,15:39:35] TFSUI: {4F8791EE-486F-44B5-952B-F28F9FD58BD0}</font>
          </p>
        </blockquote>
        <p>
        </p>
        <p>
Working with Dhathri Potla, I identified two issues:
</p>
        <ol>
          <li>
The HRESULT error indicates that there was a problem reading the media.  I had
mounted and ISO file of Visual Studio 2008 with the TFC (Team Foundation Client) directory
and attempted the install from there.  The ISO file itself was stored on a network
share.  To avoid this error, copy the TFS directory onto the local drive. 
</li>
          <li>
“Baseline not met” indicates the prerequisites for TFC were not installed successfully. 
Probably due to issue #1.</li>
        </ol>
        <p>
You can navigate to the TFS\WCU directory and manually install the prerequisites within
each subdirectory and then retry the install.  However, as in my case, there
prerequisites appeared to install correctly individually and yet the overall install
log file showed that there were still prerequisites missing.  To address this,
uninstall the prerequisites (like document explorer or Premier Partner Edition - PPE)
and the re-run the TFS <font face="Courier New">setup.exe</font>.
</p>
        <img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=3b149bf2-436f-40f1-be98-6a4cfb5c0e11" />
        <br />
        <hr />
© Copyright 2005-2008 Mark Michaelis</body>
      <title>Visual Studio Team Explorer/Client Installation Failure</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=3b149bf2-436f-40f1-be98-6a4cfb5c0e11</guid>
      <link>http://mark.michaelis.net/Blog/VisualStudioTeamExplorerClientInstallationFailure.aspx</link>
      <pubDate>Thu, 17 Jul 2008 23:30:00 GMT</pubDate>
      <description>&lt;p&gt;
A recent install of Team Foundation Explorer errored out.&amp;nbsp; Opening the log file
(from the link on the error screen) and scrolling to the bottom, showed the following:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;font face="Courier New"&gt;[07/16/08,15:39:33] Microsoft Visual Studio 2008 Team Explorer
- ENU: CRootComponent::Install(): Beginning Brooklyn Component Installation&lt;br&gt;
[07/16/08,15:39:33] Setup.exe: ISetupManager::GetFullComponents()&lt;br&gt;
[07/16/08,15:39:33] Setup.exe: ISetupManager::GetFullComponents()&lt;br&gt;
[07/16/08,15:39:34] DepCheck: gencomp97,{12CDA52C-7A8F-4785-8A22-53C87393FEE0}&lt;br&gt;
[07/16/08,15:39:34] DepCheck_Result: 1&lt;br&gt;
[07/16/08,15:39:34] Microsoft Visual Studio 2008 Team Explorer - ENU: Install(): bAttemptInstall:
0&lt;br&gt;
[07/16/08,15:39:34] Microsoft Visual Studio 2008 Team Explorer - ENU: Install(): Not
attempting to call MsiInstallProduct()!!!! &lt;font color="#ff0000"&gt;&lt;strong&gt;Baseline
not met&lt;/strong&gt;&lt;/font&gt;!&lt;br&gt;
[07/16/08,15:39:34] Setup.exe: AddGlobalCustomProperty&lt;br&gt;
[07/16/08,15:39:34] Microsoft Visual Studio 2008 Team Explorer - ENU: CRootComponent::Install():
Setup Failed; MSIInstallProduct return value either ERROR_INSTALL_FAILURE or default.&lt;br&gt;
[07/16/08,15:39:34] Setup.exe: AddGlobalCustomProperty&lt;br&gt;
[07/16/08,15:39:34] Microsoft Visual Studio 2008 Team Explorer - ENU: CRootComponent::Install():
Calling LaunchWatson()...&lt;br&gt;
[07/16/08,15:39:34] Microsoft Visual Studio 2008 Team Explorer - ENU: CRootComponent::LaunchWatson()
- Obtained CSetupWatson instance&lt;br&gt;
[07/16/08,15:39:34] Setup.exe: GetGlobalCustomProperty - Property: {AA62DF98-3F2C-11D3-887B-00C04F8ECDD6}
- PropertyName: Maintenance Mode - Value: 0&lt;br&gt;
[07/16/08,15:39:34] Microsoft Visual Studio 2008 Team Explorer - ENU: CRootComponent::LaunchWatson()
- Launching VS Watson&lt;br&gt;
[07/16/08,15:39:34] Microsoft Visual Studio 2008 Team Explorer - ENU: CRootComponent::LaunchWatson()
- Completed VS Watson launching to create manifest: C:\DOCUME~1\mmichael\LOCALS~1\Temp\vs_setup.dll.txt&lt;br&gt;
[07/16/08,15:39:34] Setup.exe: AddGlobalCustomProperty&lt;br&gt;
[07/16/08,15:39:34] Microsoft Visual Studio 2008 Team Explorer - ENU: CRootComponent::LaunchWatson()
- Setting the property CustomCoreProp_WatsonManifestReady to use the VS Client Manifest.&lt;br&gt;
[07/16/08,15:39:34] Microsoft Visual Studio 2008 Team Explorer - ENU: CRootComponent::Install():
Finished calling LaunchWatson()&lt;br&gt;
[07/16/08,15:39:34] Microsoft Visual Studio 2008 Team Explorer - ENU: CRootComponent::Install():
Finished Brooklyn Component Installation&lt;br&gt;
[07/16/08,15:39:34] UTILS::RunNGENAction: Started&lt;br&gt;
[07/16/08,15:39:34] UTILS::RunNGENAction: starting "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ngen.exe
queue pause"&lt;br&gt;
[07/16/08,15:39:34] UTILS::RunNGENAction: ngen.exe returned 0&lt;br&gt;
[07/16/08,15:39:34] Setup.exe: AddGlobalCustomProperty&lt;br&gt;
[07/16/08,15:39:34] setup.exe: &lt;font color="#ff0000"&gt;&lt;strong&gt;***ERRORLOG EVENT***
: ISetupComponent::Pre/Post/Install() failed in ISetupManager::InternalInstallManager()
with HRESULT -2147023293&lt;/strong&gt;&lt;/font&gt;.&lt;br&gt;
[07/16/08,15:39:35] Setup.exe: GetGlobalCustomProperty - Property: {7F82DEDD-12EB-439F-B7A3-8B4264E0C20D}
- PropertyName: EnableRollback - Value: 
&lt;br&gt;
[07/16/08,15:39:35] Setup.exe: GetGlobalCustomProperty - Property: {BD495746-4FBA-49F3-8EEB-D8B20EE75235}
- PropertyName: Disable Rollback - Value: 
&lt;br&gt;
[07/16/08,15:39:35] Setup.exe: ISetupManager::RunInstallFromList(IP_INSTALL) completed&lt;br&gt;
[07/16/08,15:39:35] Setup.exe: GetGlobalCustomProperty - Property: {092114C2-997D-4D68-8F3A-8BC2584FD23B}
- PropertyName: Quiet Mode Setup - Value: 
&lt;br&gt;
[07/16/08,15:39:35] TFSUI: ISetupManager::GetGlobalCustomProperty() failed to find
global prop in CProgressPage::RunningComponent()&lt;br&gt;
[07/16/08,15:39:35] TFSUI: {4F8791EE-486F-44B5-952B-F28F9FD58BD0}&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Working with Dhathri Potla, I identified two issues:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
The HRESULT error indicates that there was a problem reading the media.&amp;nbsp; I had
mounted and ISO file of Visual Studio 2008 with the TFC (Team Foundation Client) directory
and attempted the install from there.&amp;nbsp; The ISO file itself was stored on a network
share.&amp;nbsp; To avoid this error, copy the TFS directory onto the local drive. 
&lt;li&gt;
“Baseline not met” indicates the prerequisites for TFC were not installed successfully.&amp;nbsp;
Probably due to issue #1.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
You can navigate to the TFS\WCU directory and manually install the prerequisites within
each subdirectory and then retry the install.&amp;nbsp; However, as in my case, there
prerequisites appeared to install correctly individually and yet the overall install
log file showed that there were still prerequisites missing.&amp;nbsp; To address this,
uninstall the prerequisites (like document explorer or Premier Partner Edition - PPE)
and the re-run the TFS &lt;font face="Courier New"&gt;setup.exe&lt;/font&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=3b149bf2-436f-40f1-be98-6a4cfb5c0e11" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=3b149bf2-436f-40f1-be98-6a4cfb5c0e11</comments>
      <category>Computer Related</category>
      <category>Computer Related/.Net</category>
    </item>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=fb35de99-877e-4aa0-84cb-63fbcff473d0</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=fb35de99-877e-4aa0-84cb-63fbcff473d0</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=fb35de99-877e-4aa0-84cb-63fbcff473d0</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=fb35de99-877e-4aa0-84cb-63fbcff473d0</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
While searching for the command line to change the password expiration policy, I came
across <a title="http://www.joeware.net/freetools" href="http://mark.michaelis.net/Blog/ct.ashx?id=fb35de99-877e-4aa0-84cb-63fbcff473d0&amp;url=http%3a%2f%2fwww.joeware.net%2ffreetools">http://www.joeware.net/freetools</a>. 
Here are a bunch of free tools for Windows Administration from the command line. 
Many of them already have command line equivalents, but I suspect these versions are
significantly easier.
</p>
        <img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=fb35de99-877e-4aa0-84cb-63fbcff473d0" />
        <br />
        <hr />
© Copyright 2005-2008 Mark Michaelis</body>
      <title>A Bunch of Windows Administration Command Line Tools</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=fb35de99-877e-4aa0-84cb-63fbcff473d0</guid>
      <link>http://mark.michaelis.net/Blog/ABunchOfWindowsAdministrationCommandLineTools.aspx</link>
      <pubDate>Wed, 11 Jun 2008 12:10:26 GMT</pubDate>
      <description>&lt;p&gt;
While searching for the command line to change the password expiration policy, I came
across &lt;a title="http://www.joeware.net/freetools" href="http://mark.michaelis.net/Blog/ct.ashx?id=fb35de99-877e-4aa0-84cb-63fbcff473d0&amp;amp;url=http%3a%2f%2fwww.joeware.net%2ffreetools"&gt;http://www.joeware.net/freetools&lt;/a&gt;.&amp;nbsp;
Here are a bunch of free tools for Windows Administration from the command line.&amp;nbsp;
Many of them already have command line equivalents, but I suspect these versions are
significantly easier.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=fb35de99-877e-4aa0-84cb-63fbcff473d0" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=fb35de99-877e-4aa0-84cb-63fbcff473d0</comments>
      <category>Computer Related</category>
    </item>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=d294617e-956f-4e95-ada6-db89cf44ca77</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=d294617e-956f-4e95-ada6-db89cf44ca77</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=d294617e-956f-4e95-ada6-db89cf44ca77</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=d294617e-956f-4e95-ada6-db89cf44ca77</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <title>Skrbl - The Ultimate in Real Time Electronic Whiteboarding</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=d294617e-956f-4e95-ada6-db89cf44ca77</guid>
      <link>http://mark.michaelis.net/Blog/SkrblTheUltimateInRealTimeElectronicWhiteboarding.aspx</link>
      <pubDate>Tue, 10 Apr 2007 06:16:20 GMT</pubDate>
      <description>&lt;p&gt;
I came across &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=d294617e-956f-4e95-ada6-db89cf44ca77&amp;amp;url=http%3a%2f%2fwww.skrbl.com%2f"" target="_blank"&gt;this&lt;/a&gt; some
time ago and immediately&amp;nbsp;took a fancy.&amp;nbsp; Tonight I needed it again for some
collaboration and again I was amazed.&amp;nbsp;&amp;nbsp;The figure below is my real-time
collaboration with Prashant tonight.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://mark.michaelis.net/blog/content/binary/SkrblTheUltimateinRealTimeElectronicWhiteboarding/Skrbl.jpg"&gt; 
&lt;/p&gt;
&lt;p&gt;
Multiple users can "collaborate" by posting and editing content in real time onto
the whiteboard.&amp;nbsp; What is most incredible about it is the fact that there is no
install - none!&amp;nbsp; Nada... it appears to use&amp;nbsp;Java Script entirely.
&lt;/p&gt;
&lt;p&gt;
The difference between collaborating with this versus collaborating&amp;nbsp;with Word
is amazing.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
With MS Word, 
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
I type something 
&lt;/li&gt;
&lt;li&gt;
Save it&lt;/li&gt;
&lt;li&gt;
Email it or post it to SharePoint&lt;/li&gt;
&lt;li&gt;
You open&amp;nbsp;it&lt;/li&gt;
&lt;li&gt;
turn on track changes, 
&lt;/li&gt;
&lt;li&gt;
edit it, 
&lt;/li&gt;
&lt;li&gt;
email it back... etc.&amp;nbsp; 
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Instead, we just do Skrbl.com.&amp;nbsp; So I exaggerate slightly but you get the idea.&amp;nbsp;
It is so incredibly intuitive as well.&amp;nbsp; The only thing it took me a minute or
so to find was delete.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Heck... imagine pair programming with this technology.&amp;nbsp; Even&amp;nbsp;my 4 Gb VSTS
install&amp;nbsp;can't do this nearly as easily.&amp;nbsp; :)
&lt;/p&gt;
&lt;p&gt;
You GOTTA check it out.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=d294617e-956f-4e95-ada6-db89cf44ca77" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=d294617e-956f-4e95-ada6-db89cf44ca77</comments>
      <category>Computer Related</category>
      <category>Computer Related/.Net</category>
      <category>Computer Related/Miscellaneous</category>
    </item>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=ac361f56-616e-46a5-8e97-9df8458ca86d</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=ac361f56-616e-46a5-8e97-9df8458ca86d</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=ac361f56-616e-46a5-8e97-9df8458ca86d</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=ac361f56-616e-46a5-8e97-9df8458ca86d</wfw:commentRss>
      <slash:comments>5</slash:comments>
      <title>Google Reader</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=ac361f56-616e-46a5-8e97-9df8458ca86d</guid>
      <link>http://mark.michaelis.net/Blog/GoogleReader.aspx</link>
      <pubDate>Mon, 19 Feb 2007 07:14:29 GMT</pubDate>
      <description>&lt;p&gt;
For a few weeks now I have been using &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=ac361f56-616e-46a5-8e97-9df8458ca86d&amp;amp;url=http%3a%2f%2freader.google.com%2f"" target="_blank"&gt;Google
Reader&lt;/a&gt; as a means of reading a few blogs every now and then.&amp;nbsp; At first I
was relatively pleased.&amp;nbsp; It did a good job of importing my OPML files and in
spite of the fact that I was using a web based interface, the response time was fast
and I could zip through posts relatively quickly.&amp;nbsp; Most of all, I really like
having the feeds online.&amp;nbsp; I switch repeatedly between multiple computers and
my phone on occasion, and the fact that I don't have to worry about any synchronization
is a pleasure.&amp;nbsp; (Not to mention the convenient&amp;nbsp;fact that it is free.)
&lt;/p&gt;
&lt;p&gt;
Now that I have banged it around for a few weeks I am not so enamored, however.&amp;nbsp;
Several times the automatic marking of posts as read has not worked, especially when
switching between my phone and computer.&amp;nbsp; The result is that I end up reading
the same post twice.&amp;nbsp; Also, you can't apply any rules or filters, which means
I can't use it to block material from large feeds (such as &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=ac361f56-616e-46a5-8e97-9df8458ca86d&amp;amp;url=http%3a%2f%2fblogs.msdn.com%2f"" target="_blank"&gt;MSDN
Blogs&lt;/a&gt;) that I am not interested in or filter out duplicates.
&lt;/p&gt;
&lt;p&gt;
By far the most ironic (if not the most irritating) is the fact that &lt;strong&gt;Google
reader does not support any search capability&lt;/strong&gt;.&amp;nbsp; Really... isn't that
amazing?&amp;nbsp; I haven't yet looked around for the alternative (well I scanned &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=ac361f56-616e-46a5-8e97-9df8458ca86d&amp;amp;url=http%3a%2f%2fmy.yahoo.com%2f"&gt;my
Yahoo&lt;/a&gt;&amp;nbsp;and was unimpressed)&amp;nbsp;but I don't think the current choice is going
to last either.&amp;nbsp; 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=ac361f56-616e-46a5-8e97-9df8458ca86d" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=ac361f56-616e-46a5-8e97-9df8458ca86d</comments>
      <category>Computer Related</category>
      <category>Computer Related/Blogging</category>
      <category>Computer Related/Miscellaneous</category>
    </item>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=ec1fd35c-5c08-4822-9352-22820475ca4c</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=ec1fd35c-5c08-4822-9352-22820475ca4c</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=ec1fd35c-5c08-4822-9352-22820475ca4c</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=ec1fd35c-5c08-4822-9352-22820475ca4c</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <title>Funny - Free PHP Training to Learn ASP.NET</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=ec1fd35c-5c08-4822-9352-22820475ca4c</guid>
      <link>http://mark.michaelis.net/Blog/FunnyFreePHPTrainingToLearnASPNET.aspx</link>
      <pubDate>Fri, 16 Feb 2007 14:40:44 GMT</pubDate>
      <description>&lt;p&gt;
&amp;nbsp;While browsing&amp;nbsp;&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=ec1fd35c-5c08-4822-9352-22820475ca4c&amp;amp;url=http%3a%2f%2fwww.learn2asp.net%2f"" target="_blank"&gt;Microsoft's
ASP.NET online course offerings&lt;/a&gt;,&amp;nbsp;some of which&amp;nbsp;&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=ec1fd35c-5c08-4822-9352-22820475ca4c&amp;amp;url=http%3a%2f%2fpluralsight.com%2fblogs%2ffritz%2f"" target="_blank"&gt;Fritz
Onion&lt;/a&gt; is presenting&amp;nbsp;for Microsoft (so &lt;img alt="A seat in a new 3-hour PHP e-learning clinic and workshop&amp;quot;" src="http://mark.michaelis.net/blog/content/binary/FunnyFreePHPTrainingtoLearnASPNET/MicrosoftWebDevelopmentKit.gif" align="right"&gt;check
them out), I came across a rather humorous offer/give away.
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
"A seat in a new 3-hour PHP e-learning clinic and workshop"
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
I suspect they intended this to feature a 3-hour ASP.NET class for PHP developers
but that certainly isn't what it comes across as.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=ec1fd35c-5c08-4822-9352-22820475ca4c" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=ec1fd35c-5c08-4822-9352-22820475ca4c</comments>
      <category>Computer Related</category>
      <category>Computer Releated/.Net</category>
    </item>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=be587f4a-34e8-4232-8560-39f0b6aacf26</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=be587f4a-34e8-4232-8560-39f0b6aacf26</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=be587f4a-34e8-4232-8560-39f0b6aacf26</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=be587f4a-34e8-4232-8560-39f0b6aacf26</wfw:commentRss>
      <title>Using Yahoo Pipes for English MSDN Blog Feed</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=be587f4a-34e8-4232-8560-39f0b6aacf26</guid>
      <link>http://mark.michaelis.net/Blog/UsingYahooPipesForEnglishMSDNBlogFeed.aspx</link>
      <pubDate>Sat, 10 Feb 2007 22:14:57 GMT</pubDate>
      <description>&lt;p&gt;
Wow..... imagine a feeds designer that allows you to take input from multiple locations,
run it through a designer, and output a new feed.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Consider for example the MSDN RSS Feed.&amp;nbsp; If you subscribe to this feed and read
the posts then, 1)&amp;nbsp; You have too much time on your hands, and 2) You will find
that this single feed uses many languages.
&lt;/p&gt;
&lt;p&gt;
What is to be done.&amp;nbsp; In the past if I did happen to read the feed I would just
have to skip posts that were in a language I didn't understand or use some type of
filter in my blog reader so that I never even saw them.&amp;nbsp; It so happens&amp;nbsp;that
the current blog reader I use (&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=be587f4a-34e8-4232-8560-39f0b6aacf26&amp;amp;url=http%3a%2f%2freader.google.com"&gt;http://reader.google.com&lt;/a&gt;)&amp;nbsp;doesn't
support any filter mechanism.&amp;nbsp; Instead, I decided to create a new feed using &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=be587f4a-34e8-4232-8560-39f0b6aacf26&amp;amp;url=http%3a%2f%2fpipes.yahoo.com%2f"" target="_blank"&gt;Yahoo
Pipes&lt;/a&gt;.&amp;nbsp; What's more, I can publish this feed so that others can take advantage
of it.&amp;nbsp; There is not better way to understand Yahoo Pipes besides trying it I
expect, but Tim O'Reilly, &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=be587f4a-34e8-4232-8560-39f0b6aacf26&amp;amp;url=http%3a%2f%2fradar.oreilly.com%2farchives%2f2007%2f02%2fpipes_and_filte.html"" target="_blank"&gt;a
pretty good description&lt;/a&gt;.&amp;nbsp; Essentially, you can&amp;nbsp;take a data source (RSS
for example), and run it through a series of operators, perhaps combine it with other
feeds, and create a new feed.&amp;nbsp; The Yahoo Pipes name comes from the command line
pipe operator that allows one to pass output from one command to the next.&amp;nbsp; It
is really amazing what they were able to accomplish in the designer considering I
didn't encounter any security dialogs when running it.
&lt;/p&gt;
&lt;p&gt;
My first test was to create an MSDN Blog feed that was entirely English.&amp;nbsp; Currently
the feed simply filters out languages other than English.&amp;nbsp; However, it seems
relatively simply to add the capacity to&amp;nbsp;automatically translate those in other
languages.&amp;nbsp; &amp;nbsp;&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=be587f4a-34e8-4232-8560-39f0b6aacf26&amp;amp;url=http%3a%2f%2fpipes.yahoo.com%2f"" target="_blank"&gt;Yahoo
Pipes&lt;/a&gt;&amp;nbsp;includes a BabelFish operator that can translate a feed from one language
to another.&amp;nbsp; I confess I haven't done this yet (I haven't identified the languages
for some posts).
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=be587f4a-34e8-4232-8560-39f0b6aacf26&amp;amp;url=http%3a%2f%2fwww.shahine.com%2fomar"" target="_blank"&gt;Omar
Shahine&lt;/a&gt;&amp;nbsp;points out &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=be587f4a-34e8-4232-8560-39f0b6aacf26&amp;amp;url=http%3a%2f%2fwww.shahine.com%2fomar%2fHowToCustomizeTheLifeHackerFeed.aspx"" target="_blank"&gt;another
opportunity for customization of feeds&lt;/a&gt;.&amp;nbsp; In his post he praises how certain
tags can be removed from &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=be587f4a-34e8-4232-8560-39f0b6aacf26&amp;amp;url=http%3a%2f%2fwww.lifehacker.com%2f"&gt;LifeHacker&lt;/a&gt;.&amp;nbsp;
Yahoo Pipes could of course do the same thing for any feed and it provides a much
higher customization capability - one not necessarily&amp;nbsp;based on tags for example.&amp;nbsp;
With Yahoo Pipes Omar could have shared his feed of LifeHacker so others who had similar
filters could use it directly or even customize it further (either via coping it or
having it as the feed to a new pipe).
&lt;/p&gt;
&lt;p&gt;
Anyway, this is a pretty cool app that demonstrates SOA, mashing, and the like, in
a whole new way.&amp;nbsp; Wowzers!!
&lt;/p&gt;
&lt;p&gt;
&lt;strike&gt;For those interested in the resulting MSDN Blogs in English feed, the RSS
URL is: http://pipes.yahoo.com/pipes/DtICXmC42xGAi_AREpPZnA/run?_render=rss&lt;/strike&gt;
&lt;/p&gt;
&lt;p&gt;
Give it a try... feedback is welcome.&amp;nbsp; I will continue to remove or translate
posts as I encounter them coming through.
&lt;/p&gt;
&lt;p&gt;
[UPDATE] 2/13/2006
&lt;/p&gt;
&lt;p&gt;
It really is amazing what they have done in Java Script but the&amp;nbsp;site still has
some growing up to do.&amp;nbsp; Each time I re-load my filter I have to reset the fields
because they are not loading correctly.&amp;nbsp; I have crossed out the URL so as to
not have any (further) expectations that this will work.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=be587f4a-34e8-4232-8560-39f0b6aacf26" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=be587f4a-34e8-4232-8560-39f0b6aacf26</comments>
      <category>Computer Related</category>
      <category>Computer Related/.Net</category>
      <category>Computer Related/Blogging</category>
      <category>Computer Related/Miscellaneous</category>
    </item>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=15134e07-2290-43b6-9083-40979d15a397</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=15134e07-2290-43b6-9083-40979d15a397</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=15134e07-2290-43b6-9083-40979d15a397</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=15134e07-2290-43b6-9083-40979d15a397</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
        </p>
        <p>
Many moons ago I discussed the <a href="http://mark.michaelis.net/Blog/ct.ashx?id=15134e07-2290-43b6-9083-40979d15a397&amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fCForeachWithArrays.aspx">foreach
loop</a>.  I expand on that post here as I continue my series for the <a href="http://mark.michaelis.net/Blog/ct.ashx?id=15134e07-2290-43b6-9083-40979d15a397&amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fct.ashx%3fid%3d1af5d51a-d313-4f0b-afd0-0f2dd71e8900%26url%3dhttp%253a%252f%252fmsdn.microsoft.com%252fvcsharp">MSDN
C# Developer Center</a>. 
</p>
        <p>
The advantage of a foreach loop over a for loop is the fact that it is unnecessary
to know the number of items within the collection when an iteration starts. This avoids
iterating off the end of the collection using an index that is not available. As Bill
Wagner pointed out in his <a href="http://mark.michaelis.net/Blog/ct.ashx?id=15134e07-2290-43b6-9083-40979d15a397&amp;url=http%3a%2f%2fmsdn2.microsoft.com%2fen-us%2fvcsharp%2fbb264519.aspx">Custom
Iterators</a> article last week, a foreach loop also allows code to iterate over a
collection without first loading the collection in entirety into memory. In this article
I am going to explore how the foreach statement works under the covers. This sets
the stage for a follow on discussion of how the yield statement works. 
</p>
        <h3>
          <strong>
            <font face="Courier New">foreach</font> with Arrays</strong>
        </h3>
        <p>
Consider the foreach code listing shown in Listing 1: 
</p>
        <p>
Listing 1: <font face="Courier New">foreach</font> with Arrays<a></a></p>
        <blockquote>
          <p>
            <font face="Courier New">
              <font color="#0000ff">int</font>[] array = <font color="#0000ff">new
int</font>[]{1, 2, 3, 4, 5, 6};<br /></font>
            <font face="Courier New">
              <font color="#0000ff">foreach</font>(<font color="#0000ff">int</font> item <font color="#0000a0">in</font> array)<br /></font>
            <font face="Courier New">{<br />
     Console.WriteLine(item);<br />
}</font>
          </p>
        </blockquote>
        <p>
From this code, the C# compiler creates CIL equivalent of a for loop like this (Listing
2): 
</p>
        <p>
          <a>
          </a>Listing 2: Compiled Implementation of foreach with Arrays 
</p>
        <blockquote>
          <p>
            <font face="Courier New">
              <font face="Courier New" color="#0000ff">int</font>[] tempArray;<br /><font face="Courier New" color="#0000ff">int</font>[] array = <font color="#0000ff">new
int</font>[]{1, 2, 3, 4, 5, 6};<br />
tempArray = array;<br /><font color="#0000ff">for</font> (<font face="Courier New" color="#0000ff">int</font> counter=0;
(counter &lt; tempArray.Length); counter++)<br />
{<br />
     <font color="#0000ff">readonly int</font> item = tempArray[counter];<br />
     Console.WriteLine(item);<br />
}</font>
          </p>
        </blockquote>
        <p>
Since the collection is an array and indexing the array is fast, the foreach loop
implementation relies on support for the Length property and the index operator ([]).
However, these two array features are not available on all collections. Many collections
do not have a known number of elements and many collection classes do not support
retrieving elements by index. 
</p>
        <h3>
          <strong>
            <font face="Courier New">foreach</font> with <font face="Courier New">IEnumerable&lt;T&gt;</font></strong>
        </h3>
        <p>
To address this, the foreach loop uses the <font face="Courier New">System.Collections.Generic.IEnumerator&lt;T&gt;</font>.
(Given C# 2.0’s generics support, there is very little reason to consider using the
non-generic equivalent collections so I will ignore them from this discussion except
to say their behavior is almost identical.) <font face="Courier New">IEnumerator&lt;T&gt;</font> is
designed to enable the iterator pattern for iterating over collections of elements,
rather than the length-index pattern shown in earlier. <font face="Courier New">IEnumerator&lt;T&gt;</font> includes
three members. The first is bool <font face="Courier New">MoveNext()</font>. Using
this method, we can move from one element within the collection to the next while
at the same time detecting when we have enumerated through every item using the Boolean
return. The second member, a read-only property called Current, returns the element
currently in process. With these two members on the collection class, it is possible
to iterate over the collection simply using a while loop as demonstrated in the code
listing below (Listing 3): 
</p>
        <p>
Listing 3: Iterating over a collection using <font face="Courier New">while</font></p>
        <blockquote>
          <p>
            <font face="Courier New">System.Collections.Generic.Stack&lt;<font color="#0000ff">int</font>&gt;
stack =<br />
     </font>
            <font face="Courier New">
              <font color="#0000ff">new</font> System.Collections.Generic.Stack&lt;<font color="#0000ff">int</font>&gt;();<br /></font>
            <font face="Courier New">
              <font color="#0000ff">int</font> number;<br /></font>
            <font face="Courier New">// ...<br /></font>
            <font face="Courier New">// This code is conceptual, not that the actual code.<br /></font>
            <font face="Courier New">
              <font color="#0000ff">while</font>(stack.MoveNext())<br /></font>
            <font face="Courier New">{<br /></font>
            <font face="Courier New">     number = stack.Current;<br /></font>
            <font face="Courier New">     Console.WriteLine(number);<br /></font>
            <font face="Courier New">}</font>
          </p>
        </blockquote>
        <p>
The <font face="Courier New">MoveNext()</font> method in this listing returns false
when it moves past the end of the collection. This replaces the need to count elements
while looping. (The last member on <font face="Courier New">IEnumerator&lt;T&gt;</font>, <font face="Courier New">Reset()</font>,
will reset the enumeration.) This while listing shows the gist of the C# compiler
output, but it doesn’t actually work this way because it omits two important details
about the actual implementation: interleaving and error handling. 
</p>
        <h3>
          <strong>Interleaving</strong>
        </h3>
        <p>
The problem with is that if there are two (or more) interleaving loops over the same
collection, one foreach inside another, then the collection must maintain a state
indicator of the current element so that when <font face="Courier New">MoveNext()</font> is
called, the next element can be determined. The problem is that one interleaving loop
can affect the other. (The same is true of loops executed by multiple threads.) 
</p>
        <p>
          <img height="319" alt="C:\Dev\Projects\Books\EssentialC#\12-08.IEnumeratorAndIEnumeratorInterfaces.png" src="http://mark.michaelis.net/blog/Content/binary/TheInternalsofforeach_D7D/clip_image0022.gif" width="485" border="0" />
        </p>
        <p>
          <a>
          </a>Figure 1: <font face="Courier New">IEnumerable</font> class diagram 
</p>
        <p>
To overcome this problem, the <font face="Courier New">IEnumerator&lt;T&gt;</font> interfaces
are not supported by the collection classes directly. As shown in Figure 1, there
is a second interface called <font face="Courier New">IEnumerable&lt;T&gt;</font> whose
only method is <font face="Courier New">GetEnumerator()</font>. The purpose of this
method is to return an object that supports <font face="Courier New">IEnumerator&lt;T&gt;</font>.
Rather than the collection class maintaining the state itself, a different class,
usually a nested class so that it has access to the internals of the collection, will
support the <font face="Courier New">IEnumerator&lt;T&gt;</font> interface and keep
the state of the iteration loop. Using this pattern, the C# equivalent of a foreach
loop will look like what's shown in Listing 4. 
</p>
        <p>
          <a>
          </a>Listing 4: A separate enumerator maintains state during an iteration 
</p>
        <blockquote>
          <p>
            <font face="Courier New">System.Collections.Generic.Stack&lt;int&gt; stack =<br />
     </font>
            <font face="Courier New">new System.Collections.Generic.Stack&lt;int&gt;();<br /></font>
            <font face="Courier New">int number;<br /></font>
            <font face="Courier New">System.Collections.Generic.Stack&lt;int&gt;.IEnumerator&lt;int&gt; </font>
            <font face="Courier New">enumerator;<br /></font>
            <font face="Courier New">
              <br />
// ...<br /></font>
            <font face="Courier New">// If IEnumerable&lt;T&gt; is implemented explicitly, 
<br /></font>
            <font face="Courier New">// then a cast is required.<br /></font>
            <font face="Courier New">// ((IEnumerable)stack).GetEnumeraor();<br /></font>
            <font face="Courier New">enumerator = stack.GetEnumerator();<br /></font>
            <font face="Courier New">while (enumerator.MoveNext())<br /></font>
            <font face="Courier New">{<br /></font>
            <font face="Courier New">     number = enumerator.Current;<br /></font>
            <font face="Courier New">     Console.WriteLine(number);<br /></font>
            <font face="Courier New">}</font>
          </p>
        </blockquote>
        <h3>
          <strong>Error Handling</strong>
        </h3>
        <p>
Since the classes that implement the <font face="Courier New">IEnumerator&lt;T&gt;</font> interface
maintain the state, there are occasions when the state needs cleaning up after all
iterations have completed. To achieve this, the <font face="Courier New">IEnumerator&lt;T&gt;</font> interface
derives from <font face="Courier New">IDisposable</font>. Enumerators that implement <font face="Courier New">IEnumerator</font> do
not necessarily implement <font face="Courier New">IDisposable</font>, but if they
do, <font face="Courier New">Dispose()</font> will be called as well. This enables
the calling of <font face="Courier New">Dispose()</font> after the foreach loop exits.
The C# equivalent of the final CIL code, therefore, looks like Listing 5. 
</p>
        <p>
          <a>
          </a>Listing 5: Compiled Result of foreach on Collections 
</p>
        <blockquote>
          <p>
            <font face="Courier New">System.Collections.Generic.Stack&lt;int&gt; stack =<br />
     </font>
            <font face="Courier New">new System.Collections.Generic.Stack&lt;int&gt;();<br /></font>
            <font face="Courier New">int number;<br /></font>
            <font face="Courier New">System.Collections.Generic.Stack&lt;int&gt;.Enumerator&lt;int&gt; </font>
            <font face="Courier New">enumerator;<br /></font>
            <font face="Courier New">IDisposable disposable;<br /></font>
            <font face="Courier New">enumerator = stack.GetEnumerator();<br /><br /></font>
            <font face="Courier New">try<br /></font>
            <font face="Courier New">{<br /></font>
            <font face="Courier New">     while (enumerator.MoveNext())<br /></font>
            <font face="Courier New">     {<br /></font>
            <font face="Courier New">         
number = enumerator.Current;<br /></font>
            <font face="Courier New">         
Console.WriteLine(number);<br /></font>
            <font face="Courier New">     }<br /></font>
            <font face="Courier New">}<br /></font>
            <font face="Courier New">finally<br /></font>
            <font face="Courier New">{<br /></font>
            <font face="Courier New">     // Explicit cast used for
IEnumerator&lt;T&gt;.<br /></font>
            <font face="Courier New">     disposable = (IDisposable)
enumerator;<br /></font>
            <font face="Courier New">     disposable.Dispose();<br /></font>
            <font face="Courier New">
              <br />
     // IEnumerator will use the as operator unless IDisposable<br /></font>
            <font face="Courier New">     // support determinable at
compile time.<br /></font>
            <font face="Courier New">     // disposable = (enumerator
as IDisposable);<br /></font>
            <font face="Courier New">     // if (disposable != null)<br />
     </font>
            <font face="Courier New">// {<br /></font>
            <font face="Courier New">     // disposable.Dispose();<br /></font>
            <font face="Courier New">     // }<br /></font>
            <font face="Courier New">}</font>
          </p>
        </blockquote>
        <p>
Notice that because the <font face="Courier New">IDisposable</font> interface is supported
by <font face="Courier New">IEnumerator&lt;T&gt;</font>, the C# code can be simplified
with the using keyword as shown in Listing 6. 
</p>
        <p>
          <a>
          </a>Listing 6: Error handling and resource cleanup with using 
</p>
        <blockquote>
          <p>
            <font face="Courier New">System.Collections.Generic.Stack&lt;int&gt; stack =<br />
     </font>
            <font face="Courier New">new System.Collections.Generic.Stack&lt;int&gt;();<br /></font>
            <font face="Courier New">int number;<br /><br /></font>
            <font face="Courier New">using(<br />
     </font>
            <font face="Courier New">System.Collections.Generic.Stack&lt;int&gt;.Enumerator&lt;int&gt; </font>
            <font face="Courier New">enumerator
= 
<br />
          stack.GetEnumerator())<br /></font>
            <font face="Courier New">{<br />
     </font>
            <font face="Courier New">while (enumerator.MoveNext())<br /></font>
            <font face="Courier New">     {<br /></font>
            <font face="Courier New">         
number = enumerator.Current;<br /></font>
            <font face="Courier New">         
Console.WriteLine(number);<br /></font>
            <font face="Courier New">     }<br /></font>
            <font face="Courier New">}</font>
          </p>
        </blockquote>
        <p>
However, recall that the using keyword is not directly supported by CIL either, so
in reality the former code is a more accurate C# representation of the foreach CIL
code. 
</p>
        <p>
Readers may recall that the compiler prevents assignment of the <font face="Courier New">foreach</font> variable
identifier (<font face="Courier New">number</font>). As is demonstrated in Listing
6, an assignment of number would not be a change to the collection element itself
so rather than mistakenly assume that, the C# compiler prevents such an assignment
altogether. 
</p>
        <p>
In addition, the element count within a collection cannot be modified during the execution
of a <font face="Courier New">foreach</font> loop. If, for example, we called <font face="Courier New">stack.Push(42)</font> inside
the <font face="Courier New">foreach</font> loop, it would be ambiguous whether the
iterator should ignore or incorporate the change to stack – should iterator iterate
over the newly added item or ignore it and assume the exact same state as when it
was instantiated. 
</p>
        <p>
Because of this ambiguity, an exception of type <font face="Courier New">System.InvalidOperationException</font> is
thrown if the collection is modified within a <font face="Courier New">foreach</font> loop,
reporting that the collection was modified after the enumerator was instantiated. 
</p>
        <p>
(This content was largely taken from the Collections chapter of my book, <a href="http://mark.michaelis.net/Blog/ct.ashx?id=15134e07-2290-43b6-9083-40979d15a397&amp;url=http%3a%2f%2fmark.michaelis.net%2fessentialcsharp">Essential
C# 2.0 [Addison-Wesley]</a>)
</p>
        <img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=15134e07-2290-43b6-9083-40979d15a397" />
        <br />
        <hr />
© Copyright 2005-2008 Mark Michaelis</body>
      <title>The Internals of foreach</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=15134e07-2290-43b6-9083-40979d15a397</guid>
      <link>http://mark.michaelis.net/Blog/TheInternalsOfForeach.aspx</link>
      <pubDate>Fri, 02 Feb 2007 09:03:21 GMT</pubDate>
      <description>&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Many moons ago I discussed the &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=15134e07-2290-43b6-9083-40979d15a397&amp;amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fCForeachWithArrays.aspx"&gt;foreach
loop&lt;/a&gt;.&amp;nbsp; I expand on that post here as I continue my series for the &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=15134e07-2290-43b6-9083-40979d15a397&amp;amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fct.ashx%3fid%3d1af5d51a-d313-4f0b-afd0-0f2dd71e8900%26url%3dhttp%253a%252f%252fmsdn.microsoft.com%252fvcsharp"&gt;MSDN
C# Developer Center&lt;/a&gt;. 
&lt;p&gt;
The advantage of a foreach loop over a for loop is the fact that it is unnecessary
to know the number of items within the collection when an iteration starts. This avoids
iterating off the end of the collection using an index that is not available. As Bill
Wagner pointed out in his &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=15134e07-2290-43b6-9083-40979d15a397&amp;amp;url=http%3a%2f%2fmsdn2.microsoft.com%2fen-us%2fvcsharp%2fbb264519.aspx"&gt;Custom
Iterators&lt;/a&gt; article last week, a foreach loop also allows code to iterate over a
collection without first loading the collection in entirety into memory. In this article
I am going to explore how the foreach statement works under the covers. This sets
the stage for a follow on discussion of how the yield statement works. 
&lt;h3&gt;&lt;strong&gt;&lt;font face="Courier New"&gt;foreach&lt;/font&gt; with Arrays&lt;/strong&gt;
&lt;/h3&gt;
&lt;p&gt;
Consider the foreach code listing shown in Listing 1: 
&lt;p&gt;
Listing 1: &lt;font face="Courier New"&gt;foreach&lt;/font&gt; with Arrays&lt;a&gt;&lt;/a&gt; &lt;blockquote&gt; 
&lt;p&gt;
&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;[] array = &lt;font color="#0000ff"&gt;new
int&lt;/font&gt;[]{1, 2, 3, 4, 5, 6};&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;foreach&lt;/font&gt;(&lt;font color="#0000ff"&gt;int&lt;/font&gt; item &lt;font color="#0000a0"&gt;in&lt;/font&gt; array)&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(item);&lt;br&gt;
}&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
From this code, the C# compiler creates CIL equivalent of a for loop like this (Listing
2): 
&lt;p&gt;
&lt;a&gt;&lt;/a&gt;Listing 2: Compiled Implementation of foreach with Arrays &lt;blockquote&gt; 
&lt;p&gt;
&lt;font face="Courier New"&gt;&lt;font face="Courier New" color="#0000ff"&gt;int&lt;/font&gt;[] tempArray;&lt;br&gt;
&lt;font face="Courier New" color="#0000ff"&gt;int&lt;/font&gt;[] array = &lt;font color="#0000ff"&gt;new
int&lt;/font&gt;[]{1, 2, 3, 4, 5, 6};&lt;br&gt;
tempArray = array;&lt;br&gt;
&lt;font color="#0000ff"&gt;for&lt;/font&gt; (&lt;font face="Courier New" color="#0000ff"&gt;int&lt;/font&gt; counter=0;
(counter &amp;lt; tempArray.Length); counter++)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;readonly int&lt;/font&gt; item = tempArray[counter];&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(item);&lt;br&gt;
}&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Since the collection is an array and indexing the array is fast, the foreach loop
implementation relies on support for the Length property and the index operator ([]).
However, these two array features are not available on all collections. Many collections
do not have a known number of elements and many collection classes do not support
retrieving elements by index. 
&lt;h3&gt;&lt;strong&gt;&lt;font face="Courier New"&gt;foreach&lt;/font&gt; with &lt;font face="Courier New"&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/font&gt;&lt;/strong&gt;
&lt;/h3&gt;
&lt;p&gt;
To address this, the foreach loop uses the &lt;font face="Courier New"&gt;System.Collections.Generic.IEnumerator&amp;lt;T&amp;gt;&lt;/font&gt;.
(Given C# 2.0’s generics support, there is very little reason to consider using the
non-generic equivalent collections so I will ignore them from this discussion except
to say their behavior is almost identical.) &lt;font face="Courier New"&gt;IEnumerator&amp;lt;T&amp;gt;&lt;/font&gt; is
designed to enable the iterator pattern for iterating over collections of elements,
rather than the length-index pattern shown in earlier. &lt;font face="Courier New"&gt;IEnumerator&amp;lt;T&amp;gt;&lt;/font&gt; includes
three members. The first is bool &lt;font face="Courier New"&gt;MoveNext()&lt;/font&gt;. Using
this method, we can move from one element within the collection to the next while
at the same time detecting when we have enumerated through every item using the Boolean
return. The second member, a read-only property called Current, returns the element
currently in process. With these two members on the collection class, it is possible
to iterate over the collection simply using a while loop as demonstrated in the code
listing below (Listing 3): 
&lt;p&gt;
Listing 3: Iterating over a collection using &lt;font face="Courier New"&gt;while&lt;/font&gt; &lt;blockquote&gt; 
&lt;p&gt;
&lt;font face="Courier New"&gt;System.Collections.Generic.Stack&amp;lt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&amp;gt;
stack =&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt; System.Collections.Generic.Stack&amp;lt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&amp;gt;();&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt; number;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;// ...&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;// This code is conceptual, not that the actual code.&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;while&lt;/font&gt;(stack.MoveNext())&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;{&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; number = stack.Current;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(number);&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
The &lt;font face="Courier New"&gt;MoveNext()&lt;/font&gt; method in this listing returns false
when it moves past the end of the collection. This replaces the need to count elements
while looping. (The last member on &lt;font face="Courier New"&gt;IEnumerator&amp;lt;T&amp;gt;&lt;/font&gt;, &lt;font face="Courier New"&gt;Reset()&lt;/font&gt;,
will reset the enumeration.) This while listing shows the gist of the C# compiler
output, but it doesn’t actually work this way because it omits two important details
about the actual implementation: interleaving and error handling. 
&lt;h3&gt;&lt;strong&gt;Interleaving&lt;/strong&gt;
&lt;/h3&gt;
&lt;p&gt;
The problem with is that if there are two (or more) interleaving loops over the same
collection, one foreach inside another, then the collection must maintain a state
indicator of the current element so that when &lt;font face="Courier New"&gt;MoveNext()&lt;/font&gt; is
called, the next element can be determined. The problem is that one interleaving loop
can affect the other. (The same is true of loops executed by multiple threads.) 
&lt;p&gt;
&lt;img height="319" alt="C:\Dev\Projects\Books\EssentialC#\12-08.IEnumeratorAndIEnumeratorInterfaces.png" src="http://mark.michaelis.net/blog/Content/binary/TheInternalsofforeach_D7D/clip_image0022.gif" width="485" border="0"&gt; 
&lt;p&gt;
&lt;a&gt;&lt;/a&gt;Figure&amp;nbsp;1: &lt;font face="Courier New"&gt;IEnumerable&lt;/font&gt; class diagram 
&lt;p&gt;
To overcome this problem, the &lt;font face="Courier New"&gt;IEnumerator&amp;lt;T&amp;gt;&lt;/font&gt; interfaces
are not supported by the collection classes directly. As shown in Figure 1, there
is a second interface called &lt;font face="Courier New"&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/font&gt; whose
only method is &lt;font face="Courier New"&gt;GetEnumerator()&lt;/font&gt;. The purpose of this
method is to return an object that supports &lt;font face="Courier New"&gt;IEnumerator&amp;lt;T&amp;gt;&lt;/font&gt;.
Rather than the collection class maintaining the state itself, a different class,
usually a nested class so that it has access to the internals of the collection, will
support the &lt;font face="Courier New"&gt;IEnumerator&amp;lt;T&amp;gt;&lt;/font&gt; interface and keep
the state of the iteration loop. Using this pattern, the C# equivalent of a foreach
loop will look like what's shown in Listing 4. 
&lt;p&gt;
&lt;a&gt;&lt;/a&gt;Listing 4: A separate enumerator maintains state during an iteration &lt;blockquote&gt; 
&lt;p&gt;
&lt;font face="Courier New"&gt;System.Collections.Generic.Stack&amp;lt;int&amp;gt; stack =&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font face="Courier New"&gt;new System.Collections.Generic.Stack&amp;lt;int&amp;gt;();&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;int number;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;System.Collections.Generic.Stack&amp;lt;int&amp;gt;.IEnumerator&amp;lt;int&amp;gt;&amp;nbsp;&lt;/font&gt;&lt;font face="Courier New"&gt;enumerator;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;
&lt;br&gt;
// ...&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;// If IEnumerable&amp;lt;T&amp;gt; is implemented explicitly, 
&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;// then a cast is required.&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;// ((IEnumerable)stack).GetEnumeraor();&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;enumerator = stack.GetEnumerator();&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;while (enumerator.MoveNext())&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;{&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; number = enumerator.Current;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(number);&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;h3&gt;&lt;strong&gt;Error Handling&lt;/strong&gt;
&lt;/h3&gt;
&lt;p&gt;
Since the classes that implement the &lt;font face="Courier New"&gt;IEnumerator&amp;lt;T&amp;gt;&lt;/font&gt; interface
maintain the state, there are occasions when the state needs cleaning up after all
iterations have completed. To achieve this, the &lt;font face="Courier New"&gt;IEnumerator&amp;lt;T&amp;gt;&lt;/font&gt; interface
derives from &lt;font face="Courier New"&gt;IDisposable&lt;/font&gt;. Enumerators that implement &lt;font face="Courier New"&gt;IEnumerator&lt;/font&gt; do
not necessarily implement &lt;font face="Courier New"&gt;IDisposable&lt;/font&gt;, but if they
do, &lt;font face="Courier New"&gt;Dispose()&lt;/font&gt; will be called as well. This enables
the calling of &lt;font face="Courier New"&gt;Dispose()&lt;/font&gt; after the foreach loop exits.
The C# equivalent of the final CIL code, therefore, looks like Listing 5. 
&lt;p&gt;
&lt;a&gt;&lt;/a&gt;Listing 5: Compiled Result of foreach on Collections &lt;blockquote&gt; 
&lt;p&gt;
&lt;font face="Courier New"&gt;System.Collections.Generic.Stack&amp;lt;int&amp;gt; stack =&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font face="Courier New"&gt;new System.Collections.Generic.Stack&amp;lt;int&amp;gt;();&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;int number;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;System.Collections.Generic.Stack&amp;lt;int&amp;gt;.Enumerator&amp;lt;int&amp;gt; &lt;/font&gt;&lt;font face="Courier New"&gt;enumerator;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;IDisposable disposable;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;enumerator = stack.GetEnumerator();&lt;br&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;try&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;{&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while (enumerator.MoveNext())&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
number = enumerator.Current;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Console.WriteLine(number);&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;}&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;finally&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;{&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Explicit cast used for
IEnumerator&amp;lt;T&amp;gt;.&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; disposable = (IDisposable)
enumerator;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; disposable.Dispose();&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // IEnumerator will use the as operator unless IDisposable&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // support determinable at
compile time.&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // disposable = (enumerator
as IDisposable);&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // if (disposable != null)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font face="Courier New"&gt;// {&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // disposable.Dispose();&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // }&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Notice that because the &lt;font face="Courier New"&gt;IDisposable&lt;/font&gt; interface is supported
by &lt;font face="Courier New"&gt;IEnumerator&amp;lt;T&amp;gt;&lt;/font&gt;, the C# code can be simplified
with the using keyword as shown in Listing 6. 
&lt;p&gt;
&lt;a&gt;&lt;/a&gt;Listing 6: Error handling and resource cleanup with using &lt;blockquote&gt; 
&lt;p&gt;
&lt;font face="Courier New"&gt;System.Collections.Generic.Stack&amp;lt;int&amp;gt; stack =&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font face="Courier New"&gt;new System.Collections.Generic.Stack&amp;lt;int&amp;gt;();&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;int number;&lt;br&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;using(&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font face="Courier New"&gt;System.Collections.Generic.Stack&amp;lt;int&amp;gt;.Enumerator&amp;lt;int&amp;gt; &lt;/font&gt;&lt;font face="Courier New"&gt;enumerator
= 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; stack.GetEnumerator())&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font face="Courier New"&gt;while (enumerator.MoveNext())&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
number = enumerator.Current;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Console.WriteLine(number);&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
However, recall that the using keyword is not directly supported by CIL either, so
in reality the former code is a more accurate C# representation of the foreach CIL
code. 
&lt;p&gt;
Readers may recall that the compiler prevents assignment of the &lt;font face="Courier New"&gt;foreach&lt;/font&gt; variable
identifier (&lt;font face="Courier New"&gt;number&lt;/font&gt;). As is demonstrated in Listing
6, an assignment of number would not be a change to the collection element itself
so rather than mistakenly assume that, the C# compiler prevents such an assignment
altogether. 
&lt;p&gt;
In addition, the element count within a collection cannot be modified during the execution
of a &lt;font face="Courier New"&gt;foreach&lt;/font&gt; loop. If, for example, we called &lt;font face="Courier New"&gt;stack.Push(42)&lt;/font&gt; inside
the &lt;font face="Courier New"&gt;foreach&lt;/font&gt; loop, it would be ambiguous whether the
iterator should ignore or incorporate the change to stack – should iterator iterate
over the newly added item or ignore it and assume the exact same state as when it
was instantiated. 
&lt;p&gt;
Because of this ambiguity, an exception of type &lt;font face="Courier New"&gt;System.InvalidOperationException&lt;/font&gt; is
thrown if the collection is modified within a &lt;font face="Courier New"&gt;foreach&lt;/font&gt; loop,
reporting that the collection was modified after the enumerator was instantiated. 
&lt;p&gt;
(This content was largely taken from the Collections chapter of my book, &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=15134e07-2290-43b6-9083-40979d15a397&amp;amp;url=http%3a%2f%2fmark.michaelis.net%2fessentialcsharp"&gt;Essential
C# 2.0 [Addison-Wesley]&lt;/a&gt;)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=15134e07-2290-43b6-9083-40979d15a397" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=15134e07-2290-43b6-9083-40979d15a397</comments>
      <category>Computer Related</category>
      <category>Computer Related/.Net</category>
    </item>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=acd8e54e-6c15-464b-a1bf-f349a2188e13</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=acd8e54e-6c15-464b-a1bf-f349a2188e13</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=acd8e54e-6c15-464b-a1bf-f349a2188e13</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=acd8e54e-6c15-464b-a1bf-f349a2188e13</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Today I received an email asking how to associate a work item with a changeset after
all the code was checked in (without performing the association.)
</p>
        <p>
It turns out the solution is relatively simple.  On the <strong>Links</strong> tab
of the work item select <strong>Add</strong>.  By default, this shows the <strong>Link
Type</strong> is set to <strong>Work Item</strong>.  However, you can change
the type to <strong>Changeset</strong> and then browse for the changeset(s) you wish
to associate with the code.
</p>
        <p>
          <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" alt="Work Item Add Link" src="http://mark.michaelis.net/blog/Content/binary/AssociatingaWorkItemtoaChangesetAfterChe_7C22/WorkItemAddLink.jpg" border="0" />
        </p>
        <p>
(The browse functionality is a good reason why you always want to include comments
with your check-in.)
</p>
        <img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=acd8e54e-6c15-464b-a1bf-f349a2188e13" />
        <br />
        <hr />
© Copyright 2005-2008 Mark Michaelis</body>
      <title>Associating a Work Item to a Changeset After Checking in</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=acd8e54e-6c15-464b-a1bf-f349a2188e13</guid>
      <link>http://mark.michaelis.net/Blog/AssociatingAWorkItemToAChangesetAfterCheckingIn.aspx</link>
      <pubDate>Thu, 07 Dec 2006 16:56:31 GMT</pubDate>
      <description>&lt;p&gt;
Today I received an email asking how to associate a work item with a changeset after
all the code was checked in (without performing the association.)
&lt;/p&gt;
&lt;p&gt;
It turns out the solution is relatively simple.&amp;nbsp; On the &lt;strong&gt;Links&lt;/strong&gt; tab
of the work item select &lt;strong&gt;Add&lt;/strong&gt;.&amp;nbsp; By default, this shows the &lt;strong&gt;Link
Type&lt;/strong&gt; is set to &lt;strong&gt;Work Item&lt;/strong&gt;.&amp;nbsp; However, you can change
the type to &lt;strong&gt;Changeset&lt;/strong&gt; and then browse for the changeset(s) you wish
to associate with the code.
&lt;/p&gt;
&lt;p&gt;
&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" alt="Work Item Add Link" src="http://mark.michaelis.net/blog/Content/binary/AssociatingaWorkItemtoaChangesetAfterChe_7C22/WorkItemAddLink.jpg" border="0"&gt; 
&lt;/p&gt;
&lt;p&gt;
(The browse functionality is a good reason why you always want to include comments
with your check-in.)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=acd8e54e-6c15-464b-a1bf-f349a2188e13" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=acd8e54e-6c15-464b-a1bf-f349a2188e13</comments>
      <category>Computer Related</category>
      <category>Computer Releated/.Net</category>
    </item>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=43aaa715-cdc0-4fe5-96a9-331a33771f56</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=43aaa715-cdc0-4fe5-96a9-331a33771f56</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=43aaa715-cdc0-4fe5-96a9-331a33771f56</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=43aaa715-cdc0-4fe5-96a9-331a33771f56</wfw:commentRss>
      <slash:comments>6</slash:comments>
      <title>Essential C# Chapter on MSDN C# Developer Center</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=43aaa715-cdc0-4fe5-96a9-331a33771f56</guid>
      <link>http://mark.michaelis.net/Blog/EssentialCChapterOnMSDNCDeveloperCenter.aspx</link>
      <pubDate>Tue, 31 Oct 2006 06:48:55 GMT</pubDate>
      <description>&lt;p&gt;
I just noticed today that Charlie Calvert has posted my&amp;nbsp;&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=43aaa715-cdc0-4fe5-96a9-331a33771f56&amp;amp;url=http%3a%2f%2fmark.michaelis.net%2fessentialcsharp%2fGenerics_ch11.pdf"" target=_blank&gt;Chapter
11 - Generics&lt;/a&gt;&amp;nbsp;of my &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=43aaa715-cdc0-4fe5-96a9-331a33771f56&amp;amp;url=http%3a%2f%2fmark.michaelis.net%2fEssentialCSharp"" target=_blank&gt;Essential
C# (Addison-Wesley)&lt;/a&gt;&amp;nbsp;book to the &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=43aaa715-cdc0-4fe5-96a9-331a33771f56&amp;amp;url=http%3a%2f%2fmsdn2.microsoft.com%2fen-us%2fvcsharp%2fdefault.aspx"" target=_blank&gt;C#
Developer Center&lt;/a&gt;.&amp;nbsp; &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=43aaa715-cdc0-4fe5-96a9-331a33771f56&amp;amp;url=http%3a%2f%2fblogs.msdn.com%2fnoahc"&gt;Noah
Coad&lt;/a&gt; pointed out to me that this shows up in on the Start Page of Visual Studio
if you have C# as you language (and SQL Server didn't change the RSS feed).
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;img alt="Chapter 11 announcement within Visual Studio" hspace=0 src="http://mark.michaelis.net/Blog/content/binary/EssentialCChapterOnMSDNCDeveloperCenter/Chapter11WithinVisualStudio.jpg" align=baseline border=0&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Thanks Charlie!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=43aaa715-cdc0-4fe5-96a9-331a33771f56" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=43aaa715-cdc0-4fe5-96a9-331a33771f56</comments>
      <category>Computer Related</category>
      <category>Computer Related/.Net</category>
    </item>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=e9f42908-9515-4312-8e7a-6c1ae2b5f69e</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=e9f42908-9515-4312-8e7a-6c1ae2b5f69e</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=e9f42908-9515-4312-8e7a-6c1ae2b5f69e</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=e9f42908-9515-4312-8e7a-6c1ae2b5f69e</wfw:commentRss>
      <slash:comments>9</slash:comments>
      <title>What's Next for the .NET CLR?</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=e9f42908-9515-4312-8e7a-6c1ae2b5f69e</guid>
      <link>http://mark.michaelis.net/Blog/WhatsNextForTheNETCLR.aspx</link>
      <pubDate>Mon, 23 Oct 2006 04:41:16 GMT</pubDate>
      <description>&lt;p&gt;
&lt;strong&gt;2000&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Microsoft releases beta versions of the .NET Framework.&amp;nbsp; At that time the .NET
Framework and the CLR&amp;nbsp;were the core, the foundation of .NET.&amp;nbsp;&amp;nbsp;The CLR
was&amp;nbsp;modernizing/popularizing/mainstreaming&amp;nbsp;compile-on-demand, runtime hosted
programming.&amp;nbsp; (Sure, Java was doing&amp;nbsp;it, but .NET ushered in a change such
that&amp;nbsp;programming languages were to predominantly consist of languages&amp;nbsp;compiled
to IL and hosted in a runtime.)&amp;nbsp; The Microsoft development division leaders were
those building the framework.&amp;nbsp; (Okay, C# was cool to but not really a revolution...
just the perfect language to match the Framework.&amp;nbsp; What made C# spectacular was
it's meticulous development and painstaking pursuit of OOP perfection.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;2003&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e9f42908-9515-4312-8e7a-6c1ae2b5f69e&amp;amp;url=http%3a%2f%2fmark.michaelis.net%2fessentialcsharp%2fGenerics_ch11.pdf"" target=_blank&gt;Generics&lt;/a&gt; are
added to early betas of&amp;nbsp;the .NET Framework.&amp;nbsp; Revolutionary... no... just
an obvious next step that folks begged for at the language level but Microsoft wisely
postponed so that it could be in the Framework.&amp;nbsp; Was there anything revolutionary
at the time for the .NET CLR.... not particularly.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;2006&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Okay, so what is on the horizon in the .NET CLR?&amp;nbsp; I would say &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e9f42908-9515-4312-8e7a-6c1ae2b5f69e&amp;amp;url=http%3a%2f%2fmsdn.microsoft.com%2fnetframework%2ffuture%2flinq"" target=_blank&gt;LINQ&lt;/a&gt; but
unlike generics, this is a language implemented feature, not some fundamental change
in the CLR.&amp;nbsp; Well, Microsoft is obviously&amp;nbsp;very pregnant with WCF/WF/WPF
- known as .NET 3.0.&amp;nbsp; But this didn't emerge from the CLR team and there wasn't
any fundamental CLR change needed to support .NET 3.0 development.&amp;nbsp; &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e9f42908-9515-4312-8e7a-6c1ae2b5f69e&amp;amp;url=http%3a%2f%2fresearch.microsoft.com%2fphoenix%2f"" target=_blank&gt;Phoenix&lt;/a&gt; is
cool too but not anything that is garnering wide spread adoption.
&lt;/p&gt;
&lt;p&gt;
So... what's next for the CLR?&amp;nbsp; As I see it there are three main possibilities:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Move to maintenance only mode.&amp;nbsp; Heck, lets focus higher up the stack, we have
solved this level in the same way that we "solved" assembler - making it unnecessary
detail for the vast majority of developers. 
&lt;li&gt;
Aspect Oriented Programming:&amp;nbsp; The idea has fallen out of vogue but there is still
an untapped vision here. 
&lt;li&gt;
.NET scripting/dynamic language&amp;nbsp;support&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Well, Microsoft's recent hire of&amp;nbsp;&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e9f42908-9515-4312-8e7a-6c1ae2b5f69e&amp;amp;url=http%3a%2f%2fwww.iunknown.com%2f"" target=_blank&gt;John
Lam&lt;/a&gt; seems to&amp;nbsp;be pretty indicative of where they are investing.&amp;nbsp;And I
am excited.&amp;nbsp; If the&amp;nbsp;&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e9f42908-9515-4312-8e7a-6c1ae2b5f69e&amp;amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fMSHMonadTheGoodTheBadAndTheUgly.aspx"" target=_blank&gt;pain&lt;/a&gt; I
have &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e9f42908-9515-4312-8e7a-6c1ae2b5f69e&amp;amp;url=http%3a%2f%2fmark.michaelis.net%2fBlog%2fMyFirstMSHScript.aspx"" target=_blank&gt;endured&lt;/a&gt; to
learn &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e9f42908-9515-4312-8e7a-6c1ae2b5f69e&amp;amp;url=http%3a%2f%2fwww.microsoft.com%2fwindowsserver2003%2ftechnologies%2fmanagement%2fpowershell%2fdefault.mspx"" target=_blank&gt;PowerShell&lt;/a&gt; is
any indication, Microsoft has lots of work to do in this area.&amp;nbsp; Sure, I love
PowerShell but only because it has a .NET object pipe and that it exposes .NET objects
on the command line.&amp;nbsp; After that... Yuck!&amp;nbsp; Anyway, imagine a world in which
the &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e9f42908-9515-4312-8e7a-6c1ae2b5f69e&amp;amp;url=http%3a%2f%2fresearch.microsoft.com%2f%257Eemeijer%2fPapers%2fRDL04Meijer.pdf"" target=_blank&gt;CLR
changes to truly embrace and conquer the dichotomy between strongly typed languages
and scripting languages&lt;/a&gt;.&amp;nbsp; Imagine scripting languages that supported intellisense.&amp;nbsp;
Imagine writing C# code on the command line and not having to go through the bother
of compilation to an executable.
&lt;/p&gt;
&lt;p&gt;
Well.... is that where Microsoft is going for sure?&amp;nbsp; I can't say unfortunately,
but I do know that the CLR team has been wrestling with it and the dabbling with &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e9f42908-9515-4312-8e7a-6c1ae2b5f69e&amp;amp;url=http%3a%2f%2fsearch.msdn.microsoft.com%2fsearch%2fRedirect.aspx%3ftitle%3dMSDN%2bTV%253a%2bIronPython%253a%2bPython%2bon%2bthe%2b.NET%2bFramework%26url%3dhttp%3a%2f%2fmsdn.microsoft.com%2fmsdntv%2fepisode.aspx%3fxml%3depisodes%2fen%2f20051110PythonJH%2fmanifest.xml"" target=_blank&gt;Python&lt;/a&gt;,
...,&amp;nbsp;&lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e9f42908-9515-4312-8e7a-6c1ae2b5f69e&amp;amp;url=http%3a%2f%2fresearch.microsoft.com%2f%7eemeijer%2fPapers%2fMondrianDDJ.pdf"" target=_blank&gt;etc&lt;/a&gt;&amp;nbsp;means
they clearly looking at it today&amp;nbsp;and have been for some time now.&amp;nbsp; I look
forward to seeing what will emerge.&amp;nbsp; I hope there is enough time to still see
it in Orcas?
&lt;/p&gt;
&lt;p&gt;
P.S.&amp;nbsp; In hiring &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e9f42908-9515-4312-8e7a-6c1ae2b5f69e&amp;amp;url=http%3a%2f%2fwww.iunknown.com%2f"" target=_blank&gt;John
Lam&lt;/a&gt;, Microsoft has&amp;nbsp;made another &lt;em&gt;surprising&lt;/em&gt; hiring move.&amp;nbsp; Not
because it was a bad move - certainly not!&amp;nbsp; Rather, it is surprising because
John Lam was willing to be hired by Microsoft.&amp;nbsp; Again, not because&amp;nbsp;he should
have any unwillingness to working for Microsoft - certainly&amp;nbsp;not!&amp;nbsp; Rather,
it is surprising because&amp;nbsp;top industry experts have&amp;nbsp;already been courted&amp;nbsp;unsuccessfully
by Microsoft multiple times in the past(meaning each expert multiple times).&amp;nbsp;
What makes this time different?&amp;nbsp; I don't know in this particular case besides &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=e9f42908-9515-4312-8e7a-6c1ae2b5f69e&amp;amp;url=http%3a%2f%2fwww.iunknown.com%2farticles%2f2006%2f10%2f20%2fdynamic-languages-microsoft-and-me"" target=_blank&gt;what
John states in his blog&lt;/a&gt;, but I do know that Microsoft does not just make one attempt
to hire these types of people and then quit.&amp;nbsp; Generally,&amp;nbsp;expert hires like
this&amp;nbsp;only come about by long term relationships - some times taking years.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=e9f42908-9515-4312-8e7a-6c1ae2b5f69e" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=e9f42908-9515-4312-8e7a-6c1ae2b5f69e</comments>
      <category>Computer Related</category>
      <category>Computer Related/.Net</category>
    </item>
    <item>
      <trackback:ping>http://mark.michaelis.net/Blog/Trackback.aspx?guid=61b9569c-9241-4118-a105-1175db4827b9</trackback:ping>
      <pingback:server>http://mark.michaelis.net/Blog/pingback.aspx</pingback:server>
      <pingback:target>http://mark.michaelis.net/Blog/PermaLink.aspx?guid=61b9569c-9241-4118-a105-1175db4827b9</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://mark.michaelis.net/Blog/CommentView.aspx?guid=61b9569c-9241-4118-a105-1175db4827b9</wfw:comment>
      <wfw:commentRss>http://mark.michaelis.net/Blog/SyndicationService.asmx/GetEntryCommentsRss?guid=61b9569c-9241-4118-a105-1175db4827b9</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <title>CoolMon</title>
      <guid isPermaLink="false">http://mark.michaelis.net/Blog/PermaLink.aspx?guid=61b9569c-9241-4118-a105-1175db4827b9</guid>
      <link>http://mark.michaelis.net/Blog/CoolMon.aspx</link>
      <pubDate>Wed, 11 Oct 2006 17:32:18 GMT</pubDate>
      <description>&lt;p&gt;
Check out &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=61b9569c-9241-4118-a105-1175db4827b9&amp;amp;url=http%3a%2f%2fCoolMon.org"" target="_blank"&gt;CoolMon&lt;/a&gt; as
a replacement for &lt;a href="http://mark.michaelis.net/Blog/ct.ashx?id=61b9569c-9241-4118-a105-1175db4827b9&amp;amp;url=http%3a%2f%2fwww.sysinternals.com%2futilities%2fbginfo.html"" target="_blank"&gt;BGInfo&lt;/a&gt; from
sysinternals.&amp;nbsp; The difference being that CoolMon updates dynamically.&amp;nbsp; For
example, you can watch the CPU change within the CoolMon window on the desktop.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://mark.michaelis.net/Blog/aggbug.ashx?id=61b9569c-9241-4118-a105-1175db4827b9" /&gt;
&lt;br /&gt;
&lt;hr /&gt;© Copyright 2005-2008 Mark Michaelis</description>
      <comments>http://mark.michaelis.net/Blog/CommentView.aspx?guid=61b9569c-9241-4118-a105-1175db4827b9</comments>
      <category>Computer Related</category>
      <category>Computer Related/Miscellaneous</category>
    </item>
  </channel>
</rss>