<?xml version="1.0" encoding="utf-8"?>
<feed xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom">
  <title>Zupancic Perspective (v2.0)</title>
  <link rel="alternate" type="text/html" href="http://blog.devstone.com/aaron/" />
  <link rel="self" href="http://blog.devstone.com/aaron/SyndicationService.asmx/GetAtom" />
  <icon>favicon.ico</icon>
  <updated>2008-08-17T23:34:53.9965972-06:00</updated>
  <author>
    <name>R. Aaron Zupancic</name>
  </author>
  <subtitle />
  <id>http://blog.devstone.com/aaron/</id>
  <generator uri="http://www.dasblog.net" version="2.0.7180.0">DasBlog</generator>
  <entry>
    <title>Repairing TFS's Team Explorer Build Node in Visual Studio 2008</title>
    <link rel="alternate" type="text/html" href="http://blog.devstone.com/aaron/2008/08/18/RepairingTFSsTeamExplorerBuildNodeInVisualStudio2008.aspx" />
    <id>http://blog.devstone.com/aaron/PermaLink,guid,3de56574-c826-4e92-a777-dd0232633cf2.aspx</id>
    <published>2008-08-17T23:34:53.996-06:00</published>
    <updated>2008-08-17T23:34:53.9965972-06:00</updated>
    <category term="Team Foundation Server" label="Team Foundation Server" scheme="http://blog.devstone.com/aaron/CategoryView,category,Team%2BFoundation%2BServer.aspx" />
    <category term="Visual Studio" label="Visual Studio" scheme="http://blog.devstone.com/aaron/CategoryView,category,Visual%2BStudio.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <font face="Tahoma">
            <img style="FLOAT: left" src="http://blog.devstone.com/aaron/content/binary/TeamExplorer01.gif" border="0" />I've
had an issue on two computers (my primary development machine and a virtual pc dev
box) which I was <em>finally</em> able to solve today after many hours of frustrated
searching and experimenting.  Interestingly, this issue only affected my two
machines, but not those of a co-worker.  What was more peculiar was that I have
higher privileges in TFS.  The issue revolved around getting the Team Foundation
Server Team Explorer 2008 to recognize our automated builds.</font>
        </p>
        <p>
          <font face="Tahoma">Within Visual Studio 2008's Team Explorer pane I am able to browse
all work items, documents, reports, etc, but not builds.  In fact, the node shows
up with a red 'X' icon and is mislabeled 'Build' rather than the correct 'Builds'.</font>
        </p>
        <p>
          <font face="Tahoma">I attempted to fix it by uninstalling / reinstalling the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=00803636-1d16-4df1-8a3d-ef1ad4f4bbab&amp;displaylang=en">TFS
2008 Power Tools (July Release)</a>, repairing my VS2008 installation, disabling my
firewall, disabling my antivirus.  I tried digging into various configuration
files and renaming / deleting my cache folder to no avail.</font>
        </p>
        <p>
          <font face="Tahoma">Ultimately, to fix the issue I had to resort to resetting my Visual
Studio settings to their factory settings.  To do this, I did the following:</font>
        </p>
        <ol>
          <li>
            <font face="Tahoma">Renamed/Deleted by TFS Cache folder.  On my Vista machine
it's found in (C:\Users\[USERNAME]\AppData\Local\Microsoft\Team Foundation\2.0).</font>
          </li>
          <li>
            <font face="Tahoma">Reset Visual Studio 2008 settings by typing <font face="Courier New"><strong>devenv
/resetuserdata</strong></font> from the command line.</font>
          </li>
        </ol>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=3de56574-c826-4e92-a777-dd0232633cf2" />
      </div>
    </content>
  </entry>
  <entry>
    <title>VS 2008 SP1 Fixes Missing .resources Issue</title>
    <link rel="alternate" type="text/html" href="http://blog.devstone.com/aaron/2008/08/14/VS2008SP1FixesMissingResourcesIssue.aspx" />
    <id>http://blog.devstone.com/aaron/PermaLink,guid,7fb0b94f-7b10-407d-8772-852e3edc2469.aspx</id>
    <published>2008-08-14T16:27:22.086-06:00</published>
    <updated>2008-08-14T16:27:22.0861585-06:00</updated>
    <category term="Visual Studio" label="Visual Studio" scheme="http://blog.devstone.com/aaron/CategoryView,category,Visual%2BStudio.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <font face="Tahoma">I upgraded my Visual Studio 2008 installation the other day to </font>
          <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=FBEE1648-7106-44A7-9649-6D9F6D58056E&amp;displaylang=en">
            <font face="Tahoma">SP1</font>
          </a>
          <font face="Tahoma"> and
everything went beautifully.  One of the issues that Microsoft fixed centered
around the naming of embedded binary resource files.</font>
        </p>
        <p>
          <font face="Tahoma">Traditionally, binary resource files have an extension of
.resources.  However, when VS2008 was introduced, </font>
          <a href="http://blog.devstone.com/aaron/2008/02/20/LosingResourcesInVS2008CompiledAssemblies.aspx">
            <font face="Tahoma">it came
with a bug that forced you to tack on a second extension</font>
          </a>
          <font face="Tahoma">: fileName.resources.resources.</font>
        </p>
        <p>
          <font face="Tahoma">Apparently, this is now fixed, but I did have to go back and rename
my files accordingly.</font>
        </p>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=7fb0b94f-7b10-407d-8772-852e3edc2469" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Succumbing to Peer Pressure</title>
    <link rel="alternate" type="text/html" href="http://blog.devstone.com/aaron/2008/08/05/SuccumbingToPeerPressure.aspx" />
    <id>http://blog.devstone.com/aaron/PermaLink,guid,f2b849eb-26fd-434d-a4b3-a68c6a745187.aspx</id>
    <published>2008-08-05T01:18:27.655-06:00</published>
    <updated>2008-08-05T09:53:19.410608-06:00</updated>
    <category term="facebook.com" label="facebook.com" scheme="http://blog.devstone.com/aaron/CategoryView,category,facebook.com.aspx" />
    <category term="Journal" label="Journal" scheme="http://blog.devstone.com/aaron/CategoryView,category,Journal.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <font face="Tahoma">I finally gave in (for better or for worse) and signed up on </font>
          <a href="http://www.facebook.com/">
            <font face="Tahoma">facebook.com</font>
          </a>
          <font face="Tahoma"> this
past weekend.  I've always had an aversion to such social networking sites for
one reason or another.  In fact, </font>
          <a href="http://www.facebook.com/">
            <font face="Tahoma">facebook.com</font>
          </a>
          <font face="Tahoma"> and
myspace.com have long been blocked on my firewall at home until just recently. 
I may go back to block myspace.com, however; pretty much everything I've seen on it has
been annoying, sleasy, trashy, and not worth my time - basically stuff I didn't
want on my computer in the first place.</font>
        </p>
        <p>
          <font face="Tahoma">Now I don't know all the specifics about </font>
          <a href="http://www.facebook.com/">
            <font face="Tahoma">facebook.com</font>
          </a>
          <font face="Tahoma">,
but I've had a great time on it in the past few days reestablishing connections with
friends from my youth in New Mexico.  I've made contact with some people that
I've not been able to find until now, which is very exciting.</font>
        </p>
        <p>
          <font face="Tahoma">I realize that I'm a <em>late bloomer</em> of a sort with regards
to social networking, but such is the way of things I suppose.  Among other things,
I've simply not had time for it.  I still don't have time for it, but I may make
some for it, we'll see how it goes.</font>
        </p>
        <p>
          <font face="Tahoma">If you on </font>
          <a href="http://www.facebook.com/">
            <font face="Tahoma">facebook.com</font>
          </a>
          <font face="Tahoma"> and
you know me, drop me a line!</font>
        </p>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=f2b849eb-26fd-434d-a4b3-a68c6a745187" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Accessing a Remote Database in ASP.NET (Working Around the Double Hop Conundrum)</title>
    <link rel="alternate" type="text/html" href="http://blog.devstone.com/aaron/2008/07/14/AccessingARemoteDatabaseInASPNETWorkingAroundTheDoubleHopConundrum.aspx" />
    <id>http://blog.devstone.com/aaron/PermaLink,guid,3b0d363e-42aa-41a9-95fb-782dbf5b1567.aspx</id>
    <published>2008-07-13T22:02:49.603-06:00</published>
    <updated>2008-07-13T22:02:49.6039067-06:00</updated>
    <category term="C#" label="C#" scheme="http://blog.devstone.com/aaron/CategoryView,category,C%23.aspx" />
    <category term="SQL Server" label="SQL Server" scheme="http://blog.devstone.com/aaron/CategoryView,category,SQL%2BServer.aspx" />
    <category term="ASP.NET" label="ASP.NET" scheme="http://blog.devstone.com/aaron/CategoryView,category,ASP.NET.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p dir="ltr" style="MARGIN-RIGHT: 0px">
          <font face="Tahoma">I've recently been thinking about database authentication in an
ASP.NET application.  While this concept is most definitely unoriginal - a great
many web applications must perform data access of some sort - it is easy to get confused
by the many variations of data access.</font>
        </p>
        <p>
          <font face="Tahoma">To summarize in brief, there are two primary methods for authenticating
to a database: Windows Authentication (also called Integrated Security), and Sql
Authentication.  All SQL Servers support Windows Authentication and it's the
natural choice.  Enabling Sql Authentication, on the other hand, requires that
the server be configured to support it; this can be accomplished either during installation
or after the fact.  What's more, not all organizations will support Sql Authentication.</font>
        </p>
        <p>
          <font face="Tahoma">Despite the aforementioned, perhaps he simplest technique to authenticate
a user in the database is to use Sql Authentication.  It requires that 1) a login
be created in the SQL Server and mapped to the database and 2) the connection string
contain the appropriate User ID and Password parameters.  It is the simplest
also because the database can be located locally or remotely and the authentication
will succeed.</font>
        </p>
        <p>
          <font face="Tahoma">As soon as you use Windows Authentication in a web application
the level of difficulty raises, even if only slightly.  To properly implement
Windows Authentication in a web application, the identity of the process must be determined. 
For purposes of this article, as it is not directly pertinent and can be quite large
in scope, I will refrain from exploring the topic of ASP.NET process identity. 
Suffice it to say that on a Windows Server 2003/2008 the default identity for an IIS
application pool is NT AUTHORITY\NETWORK SERVICE.  On other platforms this identity
will vary.</font>
        </p>
        <p>
          <font face="Tahoma">
            <strong>ASP.NET Application - Anonymous or Integrated Windows
Authentication, No Impersonation</strong>
          </font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Tahoma">If the requesting user is not being impersonated, IIS will access
resources using the identity of the application pool (e.g., NT AUTHORITY\NETWORK SERVICE).</font>
          </p>
        </blockquote>
        <p>
          <font face="Tahoma">
            <strong>ASP.NET Application - Anonymous Authentication, Impersonation
Enabled</strong>
          </font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Tahoma">If your web application is using anonymous access and the user
is being impersonated a couple of things can happen.  First, if, in your web.config
file, you specify <font face="Courier New">&lt;identity impersonate="true" /&gt;</font>,
IIS will impersonate the anonymous user specified for your web site (e.g., IUSR_MACHINENAME,
IUSR, etc.).  A user may be specified in the web.config file as well via <font face="Courier New">&lt;identity
impersonate="true" userName="DOMAIN\User" password="xxx" /&gt;</font>.  In this
case, the web server will impersonate the user on the server.  NOTE: This user
needs, at a minimum, Write access to the \Temporary ASP.NET Files folder.</font>
          </p>
        </blockquote>
        <p>
          <font face="Tahoma">
            <strong>ASP.NET Application - Integrated Windows Authentication,
Impersonation Enabled</strong>
          </font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Tahoma">This is functionally similar to the previous item except if you
use the simple form of the identity element (i.e., &lt;identity impersonate="true"
/&gt;), the user account that is performing the request is impersonated.  This
is quite helpful especially if you need to control access to a server-side resource
by ACL.</font>
          </p>
        </blockquote>
        <p>
          <font face="Tahoma">When connecting to a SQL Server database that is local to the
web server, that is, it is physically on the same machine, you can grant access to
the identity under which the web application is running (ASPNET, NT AUTHORITY\NETWORK
SERVICE, IUSR_MACHINENAME, or the impersonated user for instance).</font>
        </p>
        <p>
          <font face="Tahoma">When the database is physically remote, however, care must be
taken to properly flow user credentials to remote server.  That is, in fact,
something of a misnomer.  Credentials aren't actually flowing to the remote server,
but rather an authentication token.  This token is generated on the computer
where the user identity is authenticated.</font>
        </p>
        <p>
          <font face="Tahoma">A user token generated on the web server will be able to flow
to the remote machine without any extra work.  This token is created in the following
scenarios:</font>
        </p>
        <ol>
          <li>
            <font face="Tahoma">Using Basic authentication - the user is actually logged-in on
the server.</font>
          </li>
          <li>
            <font face="Tahoma">Using no impersonation - the website is locally authenticated
as ASPNET or NT AUTHORITY\NETWORK SERVICE.</font>
          </li>
          <li>
            <font face="Tahoma">The impersonation identity is manually set in the web.config's
&lt;identity /&gt; element.</font>
          </li>
        </ol>
        <p>
          <font face="Tahoma">NTLM will permit the token a 'single hop' to the remote server. 
Provided the identity in question has access to the database, the connection will
be successfully established, and the requested information returned.</font>
        </p>
        <p>
          <font face="Tahoma">If, on the other hand, the web server is impersonating the requesting
user, the solution is not so cut-and-dry.  The user's token is created on the
client computer and makes a 'single hop' to the web server.  When making a request
to a remote server a 'double hop' must be performed.  NTLM will prohibit the
token from being passed to the server and you will encounter an error resembling "<strong>Login
failed for user 'NT AUTHORITY\ANONYMOUS LOGON'</strong>".</font>
        </p>
        <p>
          <font face="Tahoma">This error may be confusing and disheartening to a developer who
has not seen it before.  This is often the result of having tested the website
on a development machine (which is usually local) - "<em>It works on my machine.</em>" 
Well, it works because the token is created locally and only needs a 'single hop'
to get to the database server.</font>
        </p>
        <p>
          <font face="Tahoma">There are a few solutions that may help to address the oft-times
confusing and frustrating 'double hop' conundrum.</font>
        </p>
        <ol>
          <li>
            <font face="Tahoma">
              <strong>Setup Constrained Delegation<br /></strong>Less far-sweeping than full delegation, Kerberos constrained delegation allows
tokens to flow against a limited set of services.  This option is only available
on Windows Server 2003+.  To properly implement constrained delegation, you must
set up a Service Principal Name (SPN), identifying the service and the machine trusted
for delegating the tokens.  While simple in principle, I've found this solution
to be tempermental and very sensitive.  You may seemingly have everything set
up correctly and still not get it to work.</font>
          </li>
          <li>
            <font face="Tahoma">
              <strong>Fall back (a.k.a., revert) to the base IIS process's identity<br /></strong>Having fought the 'double hop' issue more times than I care to admit, and
for more hours than are healthy, this idea came to me last week while discussing the
'problem' with a friend and associate at Microsoft.  While this idea is not revolutionary
nor original, it is definitely useful.  This technique allows your website to
retain its ability to identify the calling user while deferring to the process's identity
(e.g., NT AUTHORITY\NETWORK SERVICE) to access remote databases.</font>
          </li>
        </ol>
        <p>
          <font face="Tahoma">To make this (#2) work we need the ability to 'undo' the impersonation
that ASP.NET performs and then reimpersonate when we're finished.  Unfortunately,
this functionality is not native to the .NET Framework as far as I'm aware - it is,
however, accessible via the RevertToSelf() Window API function.  In order to
encapsulate the logic of reverting to the base process's identity and restoring impersonation,
I've created a simple disposable class which is presented below:</font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Courier New">
              <font color="#a9a9a9">
                <em>/// &lt;summary&gt;<br />
/// Represents a disposable class that, for the lifetime of the object, runs using
the<br />
/// underlying identity of the process.  This class is useful within an ASP.NET
application<br />
/// that is impersonating the caller, but needs to access network or directory resources<br />
/// that would otherwise be prohibited without setting up constrained delegation in
Active<br />
/// Directory.<br />
/// &lt;/summary&gt;</em>
              </font>
              <br />
              <font color="#008000">public sealed class</font> RevertImpersonator : IDisposable
{<br />
  <font color="#008000">public</font> RevertImpersonator() {<br />
     <font color="#a9a9a9"><em>// acquire the identity of the
current user (the user being impersonated)<br /></em></font>     _userIdentity = WindowsIdentity.GetCurrent();<br /><br /></font>
            <font face="Courier New">     <font color="#a9a9a9"><em>//
revert to the underlying process' identity<br />
     // for ASP.NET applications that impersonate, this will be
the identity of the IIS process<br />
     // (e.g., the identity of the application pool which, by
default, is NETWORK SERVICE).<br />
     // NOTE: the NETWORK SERVICE account will access network
resources as the MACHINE$ account, local resources as NT AUTHORITY\NETWORK SERVICE.</em></font><br />
     RevertedIdentity = ( 0 != RevertToSelf() );<br />
  }<br /><br /></font>
            <font face="Courier New">  <font color="#008000">private readonly</font> WindowsIdentity
_userIdentity;<br /><br />
  <br />
  [DllImport(<font color="#a52a2a">"advapi32.dll"</font>)]<br />
  <font color="#008000">private static extern int</font> RevertToSelf();<br /><br /></font>
            <font face="Courier New">  ~RevertImpersonator() {<br />
     restore();<br />
  }<br /><br /><br /></font>
            <font face="Courier New">  <font color="#a9a9a9"><em>/// &lt;summary&gt;<br />
  /// Returns whether the user's identity was successfully reverted on initialization.<br />
  /// &lt;/summary&gt;<br /></em></font>  <font color="#008000">public bool</font> RevertedIdentity { <font color="#008000">get</font>; <font color="#008000">private
set</font>; }<br /><br /><br /></font>
            <font face="Courier New">  <font color="#008000">public void</font> Dispose()
{<br />
     GC.SuppressFinalize(<font color="#008000">this</font>);<br />
     restore();<br />
  }<br /><br /><br /></font>
            <font face="Courier New">  <font color="#008000">private void</font> restore()
{<br />
     <font color="#a9a9a9"><em>// re-impersonate the user during
cleanup<br /></em></font>     <font color="#008000">if</font> ( RevertedIdentity
)<br />
        _userIdentity.Impersonate();<br />
  }<br />
}</font>
          </p>
        </blockquote>
        <p>
          <font face="Tahoma">Effectively, this class allows you to encapsulate database calls
thus:</font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Courier New">
              <font color="#008000">using</font> ( <font color="#008000">new</font> RevertImpersonator()
) {<br />
   <font color="#a9a9a9"><em>// perform data access here<br /></em></font>}</font>
          </p>
        </blockquote>
        <p>
          <font face="Tahoma">
            <font color="#ff0000">
              <strong>An important note is warranted.</strong>
            </font> 
As previously mentioned, using this class will revert the identity on the thread to
the process's identity.  You can set your IIS Application Pool to use a domain
account rather than the default NT AUTHORITY\NETWORK SERVICE.  Doing so will
require that the domain user have access to the database in question.  If, however,
you decide to use the default, you must be aware of a few items.  First, a local
database will be accessed with the NT AUTHORITY\NETWORK SERVICE account as expected. 
A remote database will be accessed with the MACHINE$ account - this is how the NT
AUTHORITY\NETWORK SERVICE account is authenticated remotely.</font>
        </p>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=3b0d363e-42aa-41a9-95fb-782dbf5b1567" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Patching 'A severe error occurred on the current command.'</title>
    <link rel="alternate" type="text/html" href="http://blog.devstone.com/aaron/2008/07/01/PatchingASevereErrorOccurredOnTheCurrentCommand.aspx" />
    <id>http://blog.devstone.com/aaron/PermaLink,guid,e7051698-fe1f-4c1b-a981-9547a519be29.aspx</id>
    <published>2008-07-01T10:53:43.12-06:00</published>
    <updated>2008-07-01T10:53:43.1203056-06:00</updated>
    <category term="SQL Server" label="SQL Server" scheme="http://blog.devstone.com/aaron/CategoryView,category,SQL%2BServer.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <font face="Tahoma">While we use TFS (Team Foundation Server) for all of our current
development projects, we do maintain a SourceGear Vault server for most if not all
of our legacy projects.  I've had nothing but a great experience with Vault over
the past 3 or 4 years that I've used it.</font>
        </p>
        <p>
          <font face="Tahoma">Recently, however, I moved the server and SQL databases over to
a new Windows Server 2008 x64 system with SQL Server 2005 SP2.  Everything seems
to transition smoothly.  This particular SCC system does not get a lot of activity
due to the nature of what data it maintains, but about a month after the upgrade one
user suddenly couldn't access the system with authentication errors.  Likewise,
I was unable to access several pages on the administrative Vault website.  The
error reported was 'Object reference not set to an instance of an object.'</font>
        </p>
        <p>
          <font face="Tahoma">The next thing I did was open the Sql Profiler and watch the activity
as it pertained to the Vault database (sgvault).  I noticed that it was attempting
to execute a stored procedure by the name of spgettreestructure with the repository
id and the transaction id.  Attempting to run the statement directly, I was presented
with a SQL Server error:</font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p class="MsoPlainText" style="MARGIN: 0in 0in 0pt">
            <font face="Courier New" color="#a52a2a">Msg 0, Level 11, State 0, Line 0</font>
          </p>
          <p class="MsoPlainText" style="MARGIN: 0in 0in 0pt">
            <font face="Courier New" color="#a52a2a">A severe error occurred on the current command.<span style="mso-spacerun: yes">  </span>The
results, if any, should be discarded.</font>
          </p>
          <p class="MsoPlainText" style="MARGIN: 0in 0in 0pt">
            <font face="Courier New" color="#a52a2a">Msg 0, Level 20, State 0, Line 0</font>
          </p>
          <p class="MsoPlainText" style="MARGIN: 0in 0in 0pt">
            <font face="Courier New" color="#a52a2a">A severe error occurred on the current command.<span style="mso-spacerun: yes">  </span>The
results, if any, should be discarded.</font>
          </p>
        </blockquote>
        <p>
          <font face="Tahoma">This had me a little worried, but I opened up a ticket with SourceGear
support.  After a few emails back and forth, a GoToMeeting, I was referred to
Pinalkumar's blog page.  It turns out this was a bug in SQL Server that was fixed
in the Cumulative update package 6 for SQL Server 2005 SP2.  Applying the patch
(</font>
          <a href="http://support.microsoft.com/default.aspx/kb/946608/LN/">
            <font face="Tahoma">http://support.microsoft.com/default.aspx/kb/946608/LN/</font>
          </a>
          <font face="Tahoma">)
fixed the issue :)</font>
        </p>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=e7051698-fe1f-4c1b-a981-9547a519be29" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Suppressing Control Redrawing While Updating</title>
    <link rel="alternate" type="text/html" href="http://blog.devstone.com/aaron/2008/06/27/SuppressingControlRedrawingWhileUpdating.aspx" />
    <id>http://blog.devstone.com/aaron/PermaLink,guid,91d9e1f6-1e4e-4b88-bae1-9375bc1082bc.aspx</id>
    <published>2008-06-27T14:28:14.703-06:00</published>
    <updated>2008-06-27T14:28:14.7033462-06:00</updated>
    <category term=".NET" label=".NET" scheme="http://blog.devstone.com/aaron/CategoryView,category,.NET.aspx" />
    <category term="C#" label="C#" scheme="http://blog.devstone.com/aaron/CategoryView,category,C%23.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <font face="Tahoma">I was putting together a small application today that presents
data in a TextBox.  Now while this isn't too uncommon :), the text gets added
to the TextBox a line at a time via the TextBox's .AppendText() method.  I needed
to do this repeatedly and in succession.  As it turns out, an unwelcome
side effect of AppendText is that it scrolls the TextBox as the text is appended. 
This resulted in the TextBox getting cleared and then 'wiping' down as the text was
added.  Not only was this visually unappealing, but I wanted the insertion point to
stay at the top of the contents.</font>
        </p>
        <p>
          <font face="Tahoma">To my knowledge, which is quite flawed and limited, there's not
a built-in mechanism in .NET that provides this functionality.  Sure, I could
override the TextBox control and manage the WndProc method and/or use SetStyle to
make the control user drawn.  But I didn't want to do that.  Well, accomplishing
this is quite easy.</font>
        </p>
        <p>
          <font face="Tahoma">There are a few ways we can do it:</font>
        </p>
        <ol>
          <li>
            <font face="Tahoma">Use the LockWindowUpdate() API function.</font>
          </li>
          <li>
            <font face="Tahoma">Use SendMessage() API function with the WM_SETREDRAW message.</font>
          </li>
        </ol>
        <p>
          <font face="Tahoma">LockWindowUpdate() is slick and arguably easier to use, but it's
intended purpose isn't to suppress the redrawing of controls in this manner.  Plus,
you can only have one window locked at a time.  So I threw that one out.</font>
        </p>
        <p>
          <font face="Tahoma">I wrapped the logic to lock and unlock the redrawing of the control
in an IDisposable object so I wouldn't have to worry about remembering to clean up
after myself.  My class is as follows:</font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Courier New">
              <font color="#008000">public class</font> LockVisualUpdate
: IDisposable {<br />
   <font color="#008000">public</font> LockVisualUpdate(IWin32Window control)
{<br />
      _hWnd = control.Handle;<br />
      SendMessage(control.Handle, <font color="#0000ff">WM_SETREDRAW</font>, <font color="#0000ff">0</font>, <font color="#0000ff">0</font>);<br />
   }</font>
          </p>
          <p>
            <br />
            <font face="Courier New">   <font color="#008000">private readonly</font> IntPtr
_hWnd;<br />
   <font color="#008000">private const int</font><font color="#0000ff">WM_SETREDRAW</font> = <font color="#0000ff">0x000B</font>;</font>
          </p>
          <p>
            <br />
            <font face="Courier New">   [DllImport(<font color="#a52a2a">"user32.dll"</font>)]<br />
   <font color="#008000">private static extern bool</font> SendMessage(IntPtr
hWnd, <font color="#008000">int</font> msg, <font color="#008000">int</font> wParam, <font color="#008000">int</font> lParam);</font>
          </p>
          <p>
            <br />
            <font face="Courier New">   [DllImport(<font color="#a52a2a">"user32.dll"</font>)]<br />
   <font color="#008000">private static extern bool</font> InvalidateRect(IntPtr
hWnd, IntPtr lpRect, <font color="#008000">bool</font> bErase);</font>
          </p>
          <p>
            <br />
            <font face="Courier New">   <font color="#008000">public void</font> Dispose()
{<br />
      SendMessage(_hWnd, <font color="#0000ff">WM_SETREDRAW</font>, <font color="#0000ff">1</font>, <font color="#0000ff">0</font>);<br />
      InvalidateRect(_hWnd, IntPtr.Zero, <font color="#008000">false</font>);<br />
   }<br />
}</font>
          </p>
        </blockquote>
        <p>
          <font face="Tahoma">Really simple to use.  To consume it, I simply have to do
the following:</font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Courier New">
              <font color="#008000">using</font> ( <font color="#008000">new</font> LockVisualUpdate(textBox1)
) {<br />
   textBox1.AppendText(...);<br />
   <font color="#a9a9a9"><em>// ...repeated as often as necessary to populate
the control<br /><br />
   // when finished, position the insertion point to the top of the control<br /></em></font>   textBox1.SelectionStart = <font color="#0000ff">0</font>;<br />
   textBox1.ScrollToCaret();<br />
}</font>
          </p>
        </blockquote>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=91d9e1f6-1e4e-4b88-bae1-9375bc1082bc" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Retransitioning My Blog to DasBlog</title>
    <link rel="alternate" type="text/html" href="http://blog.devstone.com/aaron/2008/06/24/RetransitioningMyBlogToDasBlog.aspx" />
    <id>http://blog.devstone.com/aaron/PermaLink,guid,c0fb0023-6d33-4471-8ede-8f5d1eb595ed.aspx</id>
    <published>2008-06-23T22:46:47.585-06:00</published>
    <updated>2008-06-23T22:46:47.5853238-06:00</updated>
    <category term=".NET" label=".NET" scheme="http://blog.devstone.com/aaron/CategoryView,category,.NET.aspx" />
    <category term="DasBlog" label="DasBlog" scheme="http://blog.devstone.com/aaron/CategoryView,category,DasBlog.aspx" />
    <category term="Journal" label="Journal" scheme="http://blog.devstone.com/aaron/CategoryView,category,Journal.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <font face="Tahoma">A few days ago I realized that my blog wasn't working properly. 
This came with more than a bit of frustration because I had upgraded ito to DasBlog
on May 25th (almost 1 month ago exactly!).  What clued me off was the fact that
I wasn't getting any comments to prior posts.  While the <em>vast</em> majority
of comments came from my download control and my rating control (neither of which
has yet been ported over), I would get the occasional comment through the blog directly. 
But since the upgrade nothing.  Well, that's not true, I got two comments on
my <a href="http://blog.devstone.com/aaron/2008/05/26/MigratedFromTextToDasBlog.aspx">transition
post</a> but I didn't get either one because I didn't set up my mail setting correctly. 
That has since been fixed.</font>
        </p>
        <p>
          <font face="Tahoma">As it turns out, the code that I originally used to port the blog
site over was flawed, but I didn't realize it until it was too late.  Pretty
much all of my google links where my blog was the top page or in the top few have
all but disappeared :(.  I have, however, updated the code (which I present below)
in the event there is any other poor soul out there needing to migrate from .Text
to DasBlog.</font>
        </p>
        <p>
          <font face="Tahoma">Comments should now work on the blog.</font>
        </p>
        <p>
          <font face="Tahoma">I hope this works better for everyone moving forward:</font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Courier New">
              <font color="#0000ff">using</font> System;<br /><font color="#0000ff">using</font> System.Collections.Generic;<br /><font color="#0000ff">using</font> System.Data;<br /><font color="#0000ff">using</font> System.Data.SqlClient;<br /><font color="#0000ff">using</font> System.IO;<br /><font color="#0000ff">using</font> newtelligence.DasBlog.Runtime;<br /><br /></font>
            <font face="Courier New">
              <font color="#0000ff">namespace</font> ConvDotTextToDasBlog
{<br />
   <font color="#0000ff">internal class</font> Program {<br />
      <font color="#0000ff">private class</font> EntryData
{<br />
         <font color="#0000ff">public</font> EntryData(<font color="#0000ff">string</font> id, <font color="#0000ff">string</font> title)
{<br />
            Id = id;<br />
            Title = title;<br />
         }<br /></font>
            <font face="Courier New">
              <br />
         <font color="#0000ff">public readonly
string </font>Id, Title;<br />
      }<br /></font>
            <font face="Courier New">
              <br />
      <font color="#0000ff">private static readonly </font>Dictionary&lt;<font color="#0000ff">int</font>,
EntryData&gt; _postDict = <font color="#0000ff">new</font> Dictionary&lt;<font color="#0000ff">int</font>,
EntryData&gt;();<br /><br />
 </font>
            <font face="Courier New">     <font color="#0000ff">private
static void </font>Main() {<br />
         <font color="#0000ff">string</font> path
= Path.Combine(AppDomain.CurrentDomain.BaseDirectory, <font color="#a52a2a">"output"</font>);<br />
         Directory.CreateDirectory(path);<br /><br /></font>
            <font face="Courier New">         IBlogDataService
dataService = BlogDataServiceFactory.GetService(path, <font color="#0000ff">null</font>);<br />
         <font color="#0000ff">string</font> connStr
= <font color="#a52a2a">@"Initial Catalog=Blog; Data Source=(local)\SQLEXPRESS; Integrated
Security=True"</font>;<br /><br /></font>
            <font face="Courier New">         <font color="#0000ff">using </font>(
SqlConnection conn = <font color="#0000ff">new</font> SqlConnection(connStr) ) {<br />
            conn.Open();<br /></font>
            <font face="Courier New">            <font color="#0000ff">using </font>(
SqlCommand cmPosts = <font color="#0000ff">new</font> SqlCommand(<font color="#a52a2a">"SELECT
COUNT(ID) FROM blog_Content WHERE PostType=1; SELECT * FROM blog_Content WHERE PostType=1"</font>,
conn) )<br />
            <font color="#0000ff">using</font> (
SqlDataReader drPosts = cmPosts.ExecuteReader() ) {<br />
              
drPosts.Read();<br />
               <font color="#0000ff">int</font> totalCount
= drPosts.GetInt32(0);<br />
              
drPosts.NextResult();<br /><br /></font>
            <font face="Courier New">              
int currIndex = 0;<br />
               <font color="#0000ff">while</font> (
drPosts.Read() ) {<br />
                  <font color="#0000ff">int</font> postId
= drPosts.GetInt32(0);<br />
                  <font color="#0000ff">string</font> postTitle
= drPosts.IsDBNull(1) ? <font color="#0000ff">string</font>.Empty : drPosts.GetString(1);<br />
                 
DateTime dtCreated = drPosts.GetDateTime(2);<br />
                 
DateTime dtModified = drPosts.GetDateTime(10);<br />
                  <font color="#0000ff">string</font> postText
= drPosts.GetString(12);<br />
                  <font color="#0000ff">string</font> postAuthor
= drPosts.GetString(5);</font>
          </p>
          <p>
            <font face="Courier New">                  <font color="#a9a9a9">//
catalog the id, assigning it a guid</font><br />
                  <font color="#0000ff">string</font> newPostId
= Guid.NewGuid().ToString().ToLowerInvariant();<br />
                  <font color="#0000ff">string</font> newPostTitle
= ( postTitle.Length &gt; 0 ? postTitle : postText.Substring(0, Math.Min(20, postText.Length))
);<br />
                 
_postDict.Add(postId, <font color="#0000ff">new</font> EntryData(newPostId, newPostTitle));</font>
          </p>
          <p>
            <font face="Courier New">                 
Console.WriteLine(<font color="#a52a2a">"Processing Post #{0} ({1} of {2})"</font>,
postId, ++currIndex, totalCount);<br />
                 
Entry entry = <font color="#0000ff">new</font> Entry();<br />
                 
entry.CreatedUtc = dtCreated;<br />
                 
entry.ModifiedUtc = dtModified;<br />
                 
entry.Title = newPostTitle;<br />
                 
entry.Content = postText;<br />
                 
entry.EntryId = newPostId;<br />
                 
entry.Categories = getPostCategories(postId, connStr);<br />
                 
entry.Author = postAuthor;<br />
                 
dataService.SaveEntry(entry);<br />
              
}<br />
            }<br /><br /></font>
            <font face="Courier New">            <font color="#0000ff">using</font> (
SqlCommand cmComments = <font color="#0000ff">new</font> SqlCommand<font color="#a52a2a">("SELECT
COUNT(ID) FROM blog_Content WHERE PostType=3; SELECT * FROM blog_Content WHERE PostType=3"</font>,
conn) )<br />
            <font color="#0000ff">using</font> (
SqlDataReader drComments = cmComments.ExecuteReader() ) {<br />
              
drComments.Read();<br />
               <font color="#0000ff">int</font> totalCount
= drComments.GetInt32(0);<br />
              
drComments.NextResult();<br /><br /></font>
            <font face="Courier New">               <font color="#0000ff">int</font> currIndex
= 0;<br />
               <font color="#0000ff">while</font> (
drComments.Read() ) {<br />
                  <font color="#0000ff">int</font> commentId
= drComments.GetInt32(0);<br />
                  <font color="#0000ff">int</font> refPostId
= drComments.GetInt32(13);<br />
                 
DateTime dtCreated = drComments.GetDateTime(2);<br />
                  <font color="#0000ff">string</font> commentAuthorName
= drComments.IsDBNull(5) ? <font color="#0000ff">string</font>.Empty : drComments.GetString(5);<br />
                  <font color="#0000ff">string</font> commentAuthorIp
= drComments.IsDBNull(7) ? <font color="#0000ff">string</font>.Empty : drComments.GetString(7);<br />
                  <font color="#0000ff">string</font> commentAuthorUrl
= drComments.IsDBNull(11) ? <font color="#0000ff">string</font>.Empty : drComments.GetString(11);<br />
                  <font color="#0000ff">string</font> commentText
= drComments.GetString(12);<br /><br /></font>
            <font face="Courier New">                 
EntryData refEntry;<br />
                  <font color="#0000ff">if</font> (
!_postDict.TryGetValue(refPostId, <font color="#0000ff">out</font> refEntry) )<br />
                    
Console.WriteLine(<font color="#a52a2a">"Error processing comment #{0} ({1} of {2});
post {3} was not resolved."</font>, commentId, ++currIndex, totalCount, refPostId);<br />
                  <font color="#0000ff">else</font> {<br />
                    
Console.WriteLine(<font color="#a52a2a">"Processing Comment #{0} ({1} of {2})"</font>,
commentId, ++currIndex, totalCount);<br />
                    
Comment comment = <font color="#0000ff">new</font> Comment();<br />
                    
comment.EntryId = Guid.NewGuid().ToString().ToLowerInvariant();<br />
                    
comment.CreatedUtc = dtCreated;<br />
                    
comment.ModifiedUtc = dtCreated;<br />
                    
comment.TargetEntryId = refEntry.Id;<br />
                    
comment.TargetTitle = refEntry.Title;<br />
                    
comment.Author = commentAuthorName;<br />
                    
comment.AuthorHomepage = commentAuthorUrl;<br />
                    
comment.AuthorIPAddress = commentAuthorIp;<br />
                    
comment.Content = commentText;<br />
                    
dataService.AddComment(comment);<br />
                 
}<br />
              
}<br />
            }<br />
         }<br />
      }<br /><br /></font>
            <font face="Courier New">      <font color="#0000ff">private
static string</font> getPostCategories(<font color="#0000ff">int</font> postId, <font color="#0000ff">string</font> connStr)
{<br />
         <font color="#0000ff">const string</font> sql
= <font color="#a52a2a">"SELECT cat.Title FROM blog_Links AS links INNER JOIN blog_LinkCategories
AS cat ON links.CategoryID = cat.CategoryID WHERE links.PostID = @PostID"</font>;<br /><br /></font>
            <font face="Courier New">         List&lt;<font color="#0000ff">string</font>&gt;
categories = <font color="#0000ff">new</font> List&lt;string&gt;();<br />
         <font color="#0000ff">using</font> (
SqlConnection cn = <font color="#0000ff">new</font> SqlConnection(connStr) )<br />
         <font color="#0000ff">using</font> (
SqlCommand cm = <font color="#0000ff">new</font> SqlCommand(sql, cn) ) {<br />
            cn.Open();<br />
            cm.Parameters.Add<font color="#a52a2a">("@PostID"</font>,
SqlDbType.Int).Value = postId;<br />
            <font color="#0000ff">using</font> (
SqlDataReader dr = cm.ExecuteReader(CommandBehavior.CloseConnection) ) {<br />
               <font color="#0000ff">while</font> (
dr.Read() ) {<br />
                  <font color="#0000ff">string</font> category
= dr.GetString(0);<br />
                 
categories.Add(category);<br />
              
}<br />
            }<br />
         }<br />
         <font color="#0000ff">return string</font>.Join(<font color="#a52a2a">";"</font>,
categories.ToArray());<br />
      }<br />
   }<br />
}</font>
          </p>
        </blockquote>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=c0fb0023-6d33-4471-8ede-8f5d1eb595ed" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Troubleshooting a Website Service</title>
    <link rel="alternate" type="text/html" href="http://blog.devstone.com/aaron/2008/06/14/TroubleshootingAWebsiteService.aspx" />
    <id>http://blog.devstone.com/aaron/PermaLink,guid,990952cd-0746-4093-81eb-37db165d78bc.aspx</id>
    <published>2008-06-14T10:42:17.08-06:00</published>
    <updated>2008-06-14T10:44:38.1676489-06:00</updated>
    <category term=".NET" label=".NET" scheme="http://blog.devstone.com/aaron/CategoryView,category,.NET.aspx" />
    <category term="Web" label="Web" scheme="http://blog.devstone.com/aaron/CategoryView,category,Web.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <font face="Tahoma">
          <img style="FLOAT: right" src="http://blog.devstone.com/aaron/content/binary/womm.png" border="0" />
        </font>
        <p>
          <font face="Tahoma">I was experiencing a most perplexing issue yesterday and the day
prior that I <em>*finally*</em> resolved late last night.  In essence, I have
a Windows Service that I wrote that hosts an adapted Cassini server which, in
turn, hosts an ASP.NET website product running on the client's computer.  The
issue was the classic case of 'it works on my machine'.</font>
        </p>
        <p>
          <font face="Tahoma">I could install my service, configure it, and run an ASP.NET website
on my computer.  It was a beautiful and exciting thing to witness.  When
I went to execute it on another computer, however, the service would start up perfectly
but when I made the first request to the website the service would crash (immediately
stop) and log an error to the system's Application event log.  The error was
a FileNotFoundException.</font>
        </p>
        <p>
          <font face="Tahoma">After troubleshooting the obvious stuff for a bit (folder permissions
(the Service runs as NETWORK SERVICE), executables in the proper places, comparing
systems, etc), I resorted to more drastic means. :)  Actually, this is technique
I frequently employ when troubleshooting issues loading assemblies.</font>
        </p>
        <p>
          <font face="Tahoma">You can troubleshoot Fusion binding issues by simply setting up
some registry keys on the machine in question.  Fusion, in short, is the
name given by Microsoft for their assembly loading and binding technology in .NET. 
Because I don't have the .NET SDK or Visual Studio on the target machine in question,
I had to set it up manually.  I added the following registry keys:</font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Tahoma">
              <strong>HKLM\SOFTWARE\Microsoft\Fusion\LogPath</strong> (string)
with value pointing to my desired output folder (<strong>C:\(TEMP)\FusionLog</strong>).<br /><strong>HKLM\SOFTWARE\Microsoft\Fusion\LogFailures</strong> (DWORD) with a value of <strong>1</strong>.</font>
          </p>
        </blockquote>
        <p dir="ltr">
          <font face="Tahoma">I restarted the service and made another web request to witness
the failure for the umpteenth time.  Sure enough I got some output in my FusionLog
folder:</font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p dir="ltr">
            <font face="Courier New">*** Assembly Binder Log Entry  (6/13/2008 @ 9:18:40
PM) ***</font>
          </p>
          <p dir="ltr">
            <font face="Courier New">The operation failed.<br />
Bind result: hr = 0x80070002. The system cannot find the file specified.</font>
          </p>
          <p dir="ltr">
            <font face="Courier New">Assembly manager loaded from:  C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll<br />
Running under executable  C:\Program Files\Devstone\WebHostSvc\WebHostSvc.exe<br />
--- A detailed error log follows. </font>
          </p>
          <p dir="ltr">
            <font face="Courier New">=== Pre-bind state information ===<br />
LOG: User = NT AUTHORITY\NETWORK SERVICE<br />
LOG: DisplayName = WebHostSvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxxxxxxxx<br />
 (Fully-specified)<br />
LOG: Appbase = file:///C:/Documents and Settings/All Users/Application Data/Devstone/Web/<br />
LOG: Initial PrivatePath = NULL<br />
LOG: Dynamic Base = NULL<br />
LOG: Cache Base = NULL<br />
LOG: AppName = f9861834<br />
Calling assembly : (Unknown).<br />
===<br />
LOG: This bind starts in default load context.<br />
LOG: Using application configuration file: C:\Documents and Settings\All Users\Application
Data\Devstone\Web\web.config<br />
LOG: Using machine configuration file from C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\config\machine.config.<br />
LOG: Post-policy reference: WebHostSvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxxxxxxxx<br />
LOG: GAC Lookup was unsuccessful.<br />
ERR: No codebases found to download from.<br />
ERR: Unrecoverable error occurred during pre-download check (hr = 0x80070002).</font>
          </p>
        </blockquote>
        <p dir="ltr">
          <font face="Tahoma">The thing that immeidately stood out was the fact that the Initial
PrivatePath, Dynamic Base, and Cache Base were all NULL.  On my development machine
these all referenced the /Web/bin folder.  Why wasn't it looking in the \bin
folder?</font>
        </p>
        <p dir="ltr">
          <font face="Tahoma">At this point I began debugging the service, actually stepping
into the .NET Framework code itself to see if I could figure out the issue. 
Delving into the HttpRuntime.cs file I could see that the \bin folder gets appended
to the app domain's private paths in the InitFusion() method, just as I had expected. 
However, somehow the code wasn't getting that far.  Unfortunately, I couldn't
step through some of the code leading up to this point so it was difficult to see
exactly why it wasn't getting here.  Actually, in retrospect, I should have looked
at the code a little longer - the answer was right in front of me.</font>
        </p>
        <p dir="ltr">
          <font face="Tahoma">I noticed from the fusion log that it was performing a GAC Lookup
for the assembly.  Now the assembly isn't GAC-registered on my development machine
but I was at my wit's end with the issue.  So I GAC'd it:</font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p dir="ltr">
            <strong>
              <font face="Tahoma">gacutil /i WebHostSvc.exe</font>
            </strong>
          </p>
        </blockquote>
        <p dir="ltr">
          <font face="Tahoma">Immediately upon the next request I got the error I was looking
for in the browser:</font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p dir="ltr">
            <font face="Tahoma">
              <strong>The current identity (NT AUTHORITY\NETWORK SERVICE) does
not have write access to 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary
ASP.NET Files'.</strong>
            </font>
          </p>
        </blockquote>
        <p dir="ltr">
          <font face="Tahoma">Aha!  The one thing I didn't check but should have before. 
Granting NETWORK SERVICE rights to that folder fixed the problem straight away.</font>
        </p>
        <p dir="ltr">
          <font face="Tahoma">I then removed it from the GAC and removed the Temporary ASP.NET
Files that were created, restarted the service, and ran it again to verify that
it was running properly.</font>
        </p>
        <p dir="ltr">
          <font face="Tahoma">At this point I went back to the source code and sure enough I
saw the line I was looking for.  When initializing, it invokes a method called
SetUpCodegenDirectory (which maps to the Temporary ASP.NET Files folder).  This
method ensures that the caller has write access to it.</font>
        </p>
        <p dir="ltr">
          <font face="Tahoma">So the moral of the story: make sure that the user account that
you're using for ASP.NET has write access to the Temporary ASP.NET Files folder and
you'll be a much happier developer.</font>
        </p>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=990952cd-0746-4093-81eb-37db165d78bc" />
      </div>
    </content>
  </entry>
  <entry>
    <title>The Case of the Uninstallable Virtual Machine Additions</title>
    <link rel="alternate" type="text/html" href="http://blog.devstone.com/aaron/2008/06/12/TheCaseOfTheUninstallableVirtualMachineAdditions.aspx" />
    <id>http://blog.devstone.com/aaron/PermaLink,guid,26eb2785-e66e-48c5-b34e-a46fb0ca86e6.aspx</id>
    <published>2008-06-12T15:06:31.915-06:00</published>
    <updated>2008-06-12T15:06:31.9154922-06:00</updated>
    <category term="Virtual PC" label="Virtual PC" scheme="http://blog.devstone.com/aaron/CategoryView,category,Virtual%2BPC.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <font face="Tahoma">I have some pretty old virtual machines that I use extensively
for development and testing.  Recently I upgraded to <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=28c97d22-6eb8-4a09-a7f7-f6c7a1f000b5&amp;DisplayLang=en">Virtual
PC 2007 SP1</a> and wanted to upgrade their Virtual Machine Additions, but when I
attempted to uninstall the older software I was greeted with the following dialog
box:</font>
        </p>
        <p>
          <font face="Tahoma">
            <img src="http://blog.devstone.com/aaron/content/binary/UninstallingVPCAdditions.png" border="0" />
          </font>
        </p>
        <p>
          <font face="Tahoma">Well, I immediately clicked OK, knowing full well that a source
of "1" was invalid just to see what would happen.  Sure enough, it would not
uninstall.  Browsing for the source prompted for the "Virtual Machine Additions.msi"
file which I don't have - at least not the version it's looking for.</font>
        </p>
        <p>
          <font face="Tahoma">I had no recollection as to which version of Virtual PC was used
to create this particular .vhd file, but I knew it wasn't recent.  To fix it,
I had to locate the correct version of the VMAdditions.iso, mount it, and then uninstall. 
This is how you might go about fixing it:</font>
        </p>
        <ol>
          <li>
            <font face="Tahoma">Locate <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=6D58729D-DFA8-40BF-AFAF-20BCB7F01CD1&amp;displaylang=en">Virtual
PC 2004 SP1</a> and download it (I didn't have it anymore).</font>
          </li>
          <li>
            <font face="Tahoma">It's a .zip file, so extract it to a folder (i.e. c:\vpc2004).</font>
          </li>
          <li>
            <font face="Tahoma">Don't install it, we don't want to mess up our existing installation
of 2007+.  Instead, perform an administrative install of the .msi file which
will prompt you for a network location (a local path is fine) to extract the contents
(I chose c:\vpc2004\extract).<br /><strong>msiexec /a "Microsoft Virtual PC 2004 MSDN.msi"</strong></font>
          </li>
          <li>
            <font face="Tahoma">Then you can navigate to the appropriate location and retrieve
the VMAdditions.iso file.<br /><strong>C:\vpc2004\extract\Program Files\Microsoft Virtual PC\Virtual Machine Additions</strong></font>
          </li>
          <li>
            <font face="Tahoma">Then, within your VPC, capture the VMAdditions.iso file, cancelling
any installation process that may start via Auto-Play.</font>
          </li>
          <li>
            <font face="Tahoma">Uninstall the previous software.</font>
          </li>
        </ol>
        <p>
          <font face="Tahoma">Not too painful, but definitely an annoyance.  Now, I've
since archived off the .iso and .vfd files from the 2004 SP1, 2007, and 2007 SP1 versions
of Virtual PC just in case I have to do this again in the future.</font>
        </p>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=26eb2785-e66e-48c5-b34e-a46fb0ca86e6" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Troubleshooting 401.1 Against IIS 6.0 and Integrated Security on Local Machine</title>
    <link rel="alternate" type="text/html" href="http://blog.devstone.com/aaron/2008/06/12/Troubleshooting4011AgainstIIS60AndIntegratedSecurityOnLocalMachine.aspx" />
    <id>http://blog.devstone.com/aaron/PermaLink,guid,a0b48b25-e0b5-485b-a395-056aa5cc4655.aspx</id>
    <published>2008-06-12T10:18:22.106-06:00</published>
    <updated>2008-06-12T10:18:22.1062608-06:00</updated>
    <category term="Debugging" label="Debugging" scheme="http://blog.devstone.com/aaron/CategoryView,category,Debugging.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <font face="Tahoma">If you attempt to browse to a website on your local machine identified
by a host header that differs from the NetBIOS name of the computer or if you reference
your server via its fully qualified domain name (i.e., server.domain.local) you may
be presented with a login dialog.  This login dialog will not accept your credentials
and after three attempts you'll be presented with an error message: <strong>HTTP 401.1
- Unauthorized: Logon Failed</strong>.  This can be quite disconcerting and confusing.</font>
        </p>
        <p>
          <font face="Tahoma">I've lost many a sleepless hour trying to troubleshoot it in the
past.</font>
        </p>
        <p>
          <font face="Tahoma">Well, it happened again today and for the life of me I couldn't
find a reference to how to fix it on my blog.  I was <em>certain</em> I had blogged
about it before.</font>
        </p>
        <p>
          <font face="Tahoma">The fix is to add a registry setting to bypass a security check
introduced by Windows XP SP2 and Windows Server 2003 SP1.</font>
        </p>
        <ol>
          <li>
            <font face="Tahoma">Open your registry editor (regedit.exe)</font>
          </li>
          <li>
            <font face="Tahoma">Locate <strong>HKLM\SYSTEM\CurrentControlSet\Control\Lsa</strong>.</font>
          </li>
          <li>
            <font face="Tahoma">Create a new <strong>DWORD value</strong> named <strong>DisableLoopbackCheck</strong> and
assign it a value of <strong>1</strong>.</font>
          </li>
        </ol>
        <p>
          <font face="Tahoma">Though the </font>
          <a href="http://support.microsoft.com/kb/896861">
            <font face="Tahoma">KB
article</font>
          </a>
          <font face="Tahoma"> where I got this information says you need
to reboot, I've not needed to.</font>
        </p>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=a0b48b25-e0b5-485b-a395-056aa5cc4655" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Embedded Resource Assemblies Part II: Wrapping Static Classes</title>
    <link rel="alternate" type="text/html" href="http://blog.devstone.com/aaron/2008/06/09/EmbeddedResourceAssembliesPartIIWrappingStaticClasses.aspx" />
    <id>http://blog.devstone.com/aaron/PermaLink,guid,80decc97-e634-49ae-b3ad-200667633c65.aspx</id>
    <published>2008-06-09T09:20:56.493-06:00</published>
    <updated>2008-06-09T09:27:29.6211911-06:00</updated>
    <category term=".NET" label=".NET" scheme="http://blog.devstone.com/aaron/CategoryView,category,.NET.aspx" />
    <category term="Reflection" label="Reflection" scheme="http://blog.devstone.com/aaron/CategoryView,category,Reflection.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <font face="Tahoma">Almost immediately following <a href="http://blog.devstone.com/aaron/2008/06/08/DynamicallyLoadingEmbeddedResourceAssemblies.aspx">yesterday's
post</a> I got to thinking about supporting static classes / methods.  I see
static classes all the time where the class represents a set of related-but-operationally-distinct
methods, often utilities.  The post yesterday really had two aspects about it:
1) the retrieval / extraction and the hosting of an assembly embedded as a resource
within another assembly and 2) the creation of a proxy type by wrapping the logic
surrounding using Reflection to dig into the guts of the referenced object in a base
class.</font>
        </p>
        <p>
          <font face="Tahoma">The ante is raised (only slightly) when dealing with static objects. 
Static objects have no instance methods and therefore have no inheritance support
and no constructors (the static .ctor is really a type initializer and it's quite
the same thing).  Our simple example yesterday defines an abstract base
class (<em>ProxyClassBase</em>) that encapsulates the logic for creating the proxy
instance and invoking the methods within it.</font>
        </p>
        <p>
          <font face="Tahoma">If we were to mimic the structure of the reference object (the
object from the extracted assembly) in our proxy class we would be unable to inherit
ProxyClassBase because our proxy would be static.  Allow me to flesh out an example
illustrating this:</font>
        </p>
        <p>
          <strong>
            <font face="Tahoma">Example 01: Static Proxy</font>
          </strong>
        </p>
        <p>
          <font face="Tahoma">For this to work, I'd have to create a new class.  Let's
name it <em>StaticProxyClass.</em>  This class would, in large measure, be quite
similar to the <em>ProxyClassBase</em> base type we defined yesterday with a few distinctions: 
1) we wouldn't need an Instance (all methods are static) and 2) we can't have a protected
.ctor (our proxy would be static and would be unable to inherit the class).</font>
        </p>
        <p>
          <font face="Tahoma">Our type might resemble the following:</font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Courier New">
              <font color="#008000">namespace</font> HostAsm {<br /><br />
   <font color="#008000">internal class</font> StaticProxyClass {<br />
      <font color="#008000">internal</font> StaticProxyClass(<font color="#008000">string</font> assemblyName, <font color="#008000">string</font> typeName)
{<br />
         _type = AssemblyLoader.GetType(assemblyName,
typeName);<br />
      }<br /><br />
      <font color="#008000">private readonly</font> Type
_type;<br /><br />
      <font color="#008000">internal void</font> InvokePublicVoidMethod(<font color="#008000">string</font> methodName, <font color="#008000">object</font>[]
parameters) {<br />
         Type[] types = getTypes(parameters);<br />
         MethodInfo method = _type.GetMethod(methodName,
BindingFlags.Static | BindingFlags.Public, <font color="#008000">null</font>, CallingConventions.Standard,
types, <font color="#008000">null</font>);<br />
         method.Invoke(<font color="#008000">null</font>,
parameters);<br />
      }<br /><br />
      <font color="#008000">private static</font> Type[]
getTypes(<font color="#008000">object</font>[] parameters) {<br />
         Type[] result;<br />
         <font color="#008000">if</font> ( <font color="#008000">null</font> ==
parameters || <font color="#0000ff">0</font> == parameters.Length )<br />
            result = Type.EmptyTypes;<br />
         <font color="#008000">else</font> {<br />
            result = <font color="#008000">new</font> Type[parameters.Length];<br />
            <font color="#008000">for</font> ( <font color="#008000">int</font> i
= <font color="#0000ff">0</font>; i &lt; parameters.Length; i++ ) {<br />
              
result[i] = parameters[i].GetType();<br />
            }<br />
         }<br />
         <font color="#008000">return</font> result;<br />
      }<br />
   }<br />
   
<br />
}</font>
          </p>
        </blockquote>
        <p>
          <font face="Tahoma">Note that I've included a method (getTypes) that I didn't include
in yesterday's example but may well belong in the <em>ProxyClassBase</em> type as
well.  This method will assist in resolving overloaded methods (methods with
the same name but with differing parameters).</font>
        </p>
        <p>
          <font face="Tahoma">Our static proxy class would effectively wrap an instance of this
type and delegate calls to the reference object through it.</font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Courier New">
              <font color="#008000">namespace</font> HostAsm {<br /><br />
   <font color="#008000">internal static class</font> CustomStaticClass
{<br />
      <font color="#008000">static</font> CustomStaticClass()
{<br />
         _proxy = <font color="#008000">new</font> StaticProxyClass(<font color="#a52a2a">"EmbeddedAsm.dll"</font>, <font color="#a52a2a">"EmbeddedAsm.CustomStaticClass"</font>);<br />
      }<br /><br />
      <font color="#008000">private static readonly</font> StaticProxyClass
_proxy;<br /><br />
      <font color="#008000">internal static void</font> StaticMethod(<font color="#008000">string</font> data)
{<br />
         _proxy.InvokePublicVoidMethod(<font color="#a52a2a">"StaticMethod"</font>, <font color="#008000">new
object</font>[] { data });<br />
      }<br />
   }<br /><br />
}</font>
          </p>
        </blockquote>
        <p>
          <font face="Tahoma">This is all well and good and it works perfectly well.  There's
something missing, however, and a few things bug me about it.</font>
        </p>
        <p>
          <font face="Tahoma">First of all, it bugs me most that we'd end up having to duplicate
(in large part) the functionality in one class (<em>ProxyClassBase</em>) in another
(<em>StaticProxyClass</em>).  Secondly, we're omitting one major part of the
discussion: objects that have both instance methods and static methods.  To me,
this is the deal breaker.</font>
        </p>
        <p>
          <font face="Tahoma">To support this and to leverage our <em>ProxyClassBase</em> type
even for static methods, I'd do away with the <em>StaticProxyClass</em> and add the
methods therein to the <em>ProxyClassBase</em>.  This will necessitate that our
proxy type for static types be non-static, but we can pseudo-simulate that by making
its .ctor private.  For these, we will have to encapsulate the actual proxy within
our proxy type.  In fact, we'd have to take that one more level by creating delegate
methods on our proxy class that direct the calls to the base type.  I'd rather
do this than muck with the scope of the base class's methods to keep my intentions
pure with the base class.</font>
        </p>
        <p>
          <strong>
            <font face="Tahoma">Example 02: Enhancing the ProxyClassBase</font>
          </strong>
        </p>
        <p>
          <font face="Tahoma">The ProxyClassBase will get the functionality we just added to <em>StaticProxyClass</em> as
well as a flag indicating whether the wrapped type is a static type.</font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Courier New">
              <font color="#008000">using</font> System;<br /><font color="#008000">using</font> System.Reflection;<br /><br /><font color="#008000">namespace</font> HostAsm {<br /><br />
   <font color="#008000">internal abstract class</font> ProxyClassBase {<br />
      <font color="#008000">protected</font> ProxyClassBase(<font color="#008000">string</font> assemblyName, <font color="#008000">string</font> typeName, <font color="#008000">bool</font> isStatic)
{<br />
         ObjType = AssemblyLoader.GetType(assemblyName,
typeName);<br />
         Instance = isStatic ? <font color="#008000">null</font> :
Activator.CreateInstance(ObjType);<br />
      }<br /><br />
      <font color="#008000">protected</font> Type ObjType
{ <font color="#008000">get</font>; <font color="#008000">private set</font>; }<br />
      <font color="#008000">protected object</font> Instance
{ <font color="#008000">get</font>; <font color="#008000">private set</font>; }<br />
      <font color="#008000">protected bool</font> IsStatic
{ <font color="#008000">get</font>; <font color="#008000">private set</font>; }<br /><br />
      <font color="#008000">protected</font> T InvokePublicMethod&lt;T&gt;(<font color="#008000">string</font> methodName)
{<br />
         MethodInfo method = ObjType.GetMethod(methodName,
BindingFlags.Public | BindingFlags.Instance, <font color="#008000">null</font>, CallingConventions.Standard,
Type.EmptyTypes, <font color="#008000">null</font>);<br />
         <font color="#008000">return</font> (
T )method.Invoke(Instance, <font color="#008000">null</font>);<br />
      }<br /><br />
      <font color="#008000">protected void</font> InvokePublicStaticVoidMethod(<font color="#008000">string</font> methodName, <font color="#008000">object</font>[]
parameters) {<br />
         Type[] types = getTypes(parameters);<br />
         MethodInfo method = ObjType.GetMethod(methodName,
BindingFlags.Public | BindingFlags.Static, <font color="#008000">null</font>, CallingConventions.Standard,
types, <font color="#008000">null</font>);<br />
         method.Invoke(<font color="#008000">null</font>,
parameters);<br />
      }<br /><br />
      <font color="#008000">private</font> Type[] getTypes(<font color="#008000">object</font>[]
parameters) {<br />
         Type[] result;<br />
         <font color="#008000">if</font> ( <font color="#008000">null</font> ==
parameters || <font color="#0000ff">0</font> == parameters.Length )<br />
            result = Type.EmptyTypes;<br />
         <font color="#008000">else</font> {<br />
            result = <font color="#008000">new</font> Type[parameters.Length];<br />
            <font color="#008000">for</font> ( <font color="#008000">int</font> i
= <font color="#0000ff">0</font>; i &lt; parameters.Length; i++ ) {<br />
              
result[i] = parameters[i].GetType();<br />
            }<br />
         }<br />
         <font color="#008000">return</font> result;<br />
      }<br />
   }<br /><br />
}</font>
          </p>
        </blockquote>
        <p>
          <font face="Tahoma">Then, to finish the puzzle, our proxy class that wraps the static
type gets a face lift:</font>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <font face="Courier New">
              <font color="#008000">using</font> System;<br /><br /><font color="#008000">namespace</font> HostAsm {<br /><br />
   <font color="#008000">internal class</font> CustomStaticClass : ProxyClassBase
{<br />
      <font color="#008000">private</font> CustomStaticClass()<br />
         : <font color="#008000">base</font>(<font color="#a52a2a">"EmbeddedAsm.dll"</font>, <font color="#a52a2a">"EmbeddedAsm.CustomStaticClass"</font>, <font color="#008000">true</font>)
{<br />
      }<br /><br />
      <font color="#008000">private static readonly</font> CustomClass2
_proxy = <font color="#008000">new</font> CustomClass2();<br /><br />
      <font color="#008000">internal static void</font> StaticMethod(<font color="#008000">string</font> data)
{<br />
         _proxy.invokePublicStaticVoidMethod(<font color="#a52a2a">"StaticMethod"</font>, <font color="#008000">new
object</font>[] { data });<br />
      }<br /><br />
      <font color="#008000">private void</font> invokePublicStaticVoidMethod(<font color="#008000">string</font> methodName, <font color="#008000">object</font>[]
parameters) {<br />
         <font color="#008000">base</font>.InvokePublicStaticVoidMethod(methodName,
parameters);<br />
      }<br />
   }<br /><br />
}</font>
          </p>
        </blockquote>
        <p dir="ltr">
          <font face="Tahoma">I've not given this approach a great deal of scrutiny.  At
first glance I can see it being somewhat fragile.  If the base class changes
you have to proliferate changes to the inheriting types.  Then again, I don't
see this base class like this changing much if at all except for new additions.</font>
        </p>
        <img width="0" height="0" src="http://blog.devstone.com/aaron/aggbug.ashx?id=80decc97-e634-49ae-b3ad-200667633c65" />
      </div>
    </content>
  </entry>
</feed>