<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>PFE - Developer Notes for the Field : Zach</title><link>http://blogs.msdn.com/pfedev/archive/tags/Zach/default.aspx</link><description>Tags: Zach</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>How do I dump out a string?</title><link>http://blogs.msdn.com/pfedev/archive/2009/11/12/how-do-i-dump-out-a-string.aspx</link><pubDate>Thu, 12 Nov 2009 17:58:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9919314</guid><dc:creator>zakramer</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/pfedev/comments/9919314.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pfedev/commentrss.aspx?PostID=9919314</wfw:commentRss><description>&lt;p&gt;The topic came up a while back on one of our aliases – How can I dump out a string?&lt;/p&gt;  &lt;p&gt;There are a lot of ways do this in the debugger and there are also debugger extensions that will help out with.&amp;#160; What most people in WinDBG do is us the “du” command for Unicode strings and “da” for ASCII strings. However this has a problem in that output looks like:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;00000001`40234dd8 &amp;quot;Server=com-appdb-01\moss1;Databa&amp;quot;     &lt;br /&gt;00000001`40234e18 &amp;quot;se=SharedServices2_55;Trusted_Co&amp;quot;      &lt;br /&gt;00000001`40234e58 &amp;quot;nnection=yes;App=Windows SharePo&amp;quot;      &lt;br /&gt;00000001`40234e98 &amp;quot;int Services;Timeout=15&amp;quot;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You cannot easily cut and paste this into other places.&amp;#160; You have the addresses and such.&amp;#160; Also, this only handles a few lines.&amp;#160; If you check out the help for the du commands there is /c switch which says only dump the characters instead of all the characters.&amp;#160; You would end up with a command like - “du /c”.&amp;#160; To take it one step further you can actually create an alias:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;as !ds du /c 100 c+ &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Then all you have to do is - !ds &amp;lt;address to String object&amp;gt;&lt;/p&gt;  &lt;p&gt;So this combines both aliases and come special switches.&lt;/p&gt;  &lt;p&gt;Thanks,&lt;/p&gt;  &lt;p&gt;Zach&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9919314" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pfedev/archive/tags/Zach/default.aspx">Zach</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/WinDBG/default.aspx">WinDBG</category></item><item><title>What does High Performance Mean?</title><link>http://blogs.msdn.com/pfedev/archive/2009/11/10/what-does-high-performance-mean.aspx</link><pubDate>Tue, 10 Nov 2009 17:35:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9919310</guid><dc:creator>zakramer</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/pfedev/comments/9919310.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pfedev/commentrss.aspx?PostID=9919310</wfw:commentRss><description>&lt;p&gt;Over my years in PFE and Microsoft as a whole I have worked on some REALLY cool websites and applications that are used around the world and drive a lot of business.&amp;#160; Getting work on these cool projects is one of the main reasons that I love what I do.&amp;#160; Getting to see what cool problems people are solving with Microsoft technology.&amp;#160; One of those cases was highlighted a few months back on Channel9!&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a title="http://channel9.msdn.com/shows/ARCast.TV/ARCastTV-Steve-Michelotti-of-eimagination-on-High-Performance-Web-Solutions/" href="http://channel9.msdn.com/shows/ARCast.TV/ARCastTV-Steve-Michelotti-of-eimagination-on-High-Performance-Web-Solutions/"&gt;http://channel9.msdn.com/shows/ARCast.TV/ARCastTV-Steve-Michelotti-of-eimagination-on-High-Performance-Web-Solutions/&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Steve Michelotti does a great job of explaining some of the stuff that we did and what the applications look like.&amp;#160; So check it out!&lt;/p&gt;  &lt;p&gt;Thanks,&lt;/p&gt;  &lt;p&gt;Zach&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9919310" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pfedev/archive/tags/Zach/default.aspx">Zach</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/IIS/default.aspx">IIS</category></item><item><title>Passing a Managed Function Pointer to Unmanaged Code</title><link>http://blogs.msdn.com/pfedev/archive/2009/11/08/passing-a-managed-function-pointer-to-unmanaged-code.aspx</link><pubDate>Sun, 08 Nov 2009 22:27:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9919308</guid><dc:creator>zakramer</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/pfedev/comments/9919308.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pfedev/commentrss.aspx?PostID=9919308</wfw:commentRss><description>&lt;P&gt;I was working with a customer a while back and they had a situation where they wanted to be able to register a managed callback function with a native API.&amp;nbsp; This is not a big problem and the sample that I extended did this already.&amp;nbsp; The question that arose was – How do I pass a managed object to the native API so that it can pass that object to the callback function.&amp;nbsp; Then I need to be able to determine the type of the managed object because it is possible that any number of objects could get passed to this call back function.&amp;nbsp; I took the code sample that is provided on MSDN and extended it a bit to handle this.&amp;nbsp; Here is the original sample - &lt;A title=http://msdn.microsoft.com/en-us/library/367eeye0(VS.80).aspx href="http://msdn.microsoft.com/en-us/library/367eeye0.aspx" mce_href="http://msdn.microsoft.com/en-us/library/367eeye0.aspx"&gt;http://msdn.microsoft.com/en-us/library/367eeye0.aspx&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The first commend here is that this is some DANGEROUS territory.&amp;nbsp; It is really easy to corrupt things and get mess up.&amp;nbsp; For those that are used to manage code this is very much C++ territory where you have all the power and with that comes all of the rope that you need to hang your self.&lt;/P&gt;
&lt;P&gt;As I mentioned about the customer wanted to be able to pass different types of objects in the lpUserData so the callback can handle different types of data.&amp;nbsp; So the way to do this is with a GCHandle.&amp;nbsp; Basically this gives you a native handle the object.&amp;nbsp; You pass that around on the native size and when it arrives on the managed side you can “trade it in” for the managed object.&lt;/P&gt;
&lt;P&gt;So let’s say you have some sort of managed class.&amp;nbsp; In this case I called it “callbackData” and you want to pass it off.&amp;nbsp; &lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=csharpcode&gt;callbackData^ cd = gcnew callbackData();&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;P&gt;First you need to get a “pointer” to the object that can be passed off:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;GCHandle gch2 = GCHandle::Alloc(cd);&lt;/PRE&gt;&lt;PRE&gt;IntPtr ip2 = GCHandle::ToIntPtr(gch2);&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; obj = ip2.ToInt32();&lt;/PRE&gt;&lt;/DIV&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;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;You need to keep the GCHandle around so you can free it up later.&amp;nbsp; It is very possible to leak GCHandles.&amp;nbsp; In addition GCHandles are roots to CLR objects and therefore you are rooting any memory referenced by the object you have the GCHandle for so the GC will not release any of that memory.&amp;nbsp; This however is not as bad as pinning the memory.&amp;nbsp; The GCHandle is a reference to the object that can be used later to retrieve the address of the actual object when needed.&lt;/P&gt;
&lt;P&gt;From the GCHandle you can convert that to a an IntPtr.&amp;nbsp; Once you have an Int from the IntPtr that you can pass around to the lpUserData parameter.&amp;nbsp; You could also just directly pass the IntPtr but I just wanted to demonstrate taking it all the way down to the int.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Then you can pass that value as part of an LPARAM or whatever you want to the native code.&amp;nbsp; &lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; answer = TakesCallback(cb, 243, 257, obj);&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;P&gt;That will get passed to your callback that uses your delegate to call into your managed function.&amp;nbsp; The native code might do something simple like this:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;typedef &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; (__stdcall *ANSWERCB)(&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt;, &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt;, &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; ANSWERCB cb;&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; TakesCallback(ANSWERCB fp, &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; n, &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; m, &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; ptr) {&lt;/PRE&gt;&lt;PRE class=alt&gt;   cb = fp;&lt;/PRE&gt;&lt;PRE&gt;   &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (cb) {&lt;/PRE&gt;&lt;PRE class=alt&gt;      printf_s(&lt;SPAN class=str&gt;"[unmanaged] got callback address (%d), calling it...\n"&lt;/SPAN&gt;, cb);&lt;/PRE&gt;&lt;PRE&gt;      &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; cb(n, m, ptr);&lt;/PRE&gt;&lt;PRE class=alt&gt;   }&lt;/PRE&gt;&lt;PRE&gt;   printf_s(&lt;SPAN class=str&gt;"[unmanaged] unregistering callback"&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE class=alt&gt;   &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; 0;&lt;/PRE&gt;&lt;PRE&gt;}&lt;/PRE&gt;&lt;/DIV&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;P&gt;In inside your callback function you simply get back an object:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV class=csharpcode&gt;&lt;PRE class=alt&gt;&lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;delegate&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; GetTheAnswerDelegate(&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt;, &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt;, &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; GetNumber(&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; n, &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; m, &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; ptr) {&lt;/PRE&gt;&lt;PRE&gt;   Console::WriteLine(&lt;SPAN class=str&gt;"[managed] callback!"&lt;/SPAN&gt;);&lt;/PRE&gt;&lt;PRE class=alt&gt;   &lt;SPAN class=kwrd&gt;static&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; x = 0;&lt;/PRE&gt;&lt;PRE&gt;   ++x;&lt;/PRE&gt;&lt;PRE class=alt&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE&gt;   IntPtr ip2(ptr);&lt;/PRE&gt;&lt;PRE class=alt&gt;   GCHandle val = GCHandle::FromIntPtr(ip2);&lt;/PRE&gt;&lt;PRE&gt;   System::Object ^obj = val.Target;&lt;/PRE&gt;&lt;PRE class=alt&gt;   Console::WriteLine(&lt;SPAN class=str&gt;"Type - "&lt;/SPAN&gt; + obj-&amp;gt;GetType()-&amp;gt;ToString() );&lt;/PRE&gt;&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=alt&gt;   &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; n + m + x;&lt;/PRE&gt;&lt;PRE&gt;}&lt;/PRE&gt;&lt;/DIV&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;P&gt;Once you have the object you can cast it or do whatever you need to move forward.&amp;nbsp; This approach allows you to bridge across the managed and native world when you have a native function that makes a callback.&amp;nbsp; I will attach a complete sample for you to play with if you interested and let me know if there are any questions.&amp;nbsp; There are other ways to approach this I am sure but this seemed to work pretty well and as long as you manage you rGCHandles and callback references you should be good to go!&lt;/P&gt;
&lt;P&gt;Thanks,&lt;/P&gt;
&lt;P&gt;Zach&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;REFERENCES&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;GCHandle.Target - &lt;A href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle.target.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle.target.aspx"&gt;http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle.target.aspx&lt;/A&gt; &lt;/LI&gt;
&lt;LI&gt;How to: Marshal Callbacks and Delegates Using C++ Interop - &lt;A href="http://msdn.microsoft.com/en-us/library/367eeye0.aspx" mce_href="http://msdn.microsoft.com/en-us/library/367eeye0.aspx"&gt;http://msdn.microsoft.com/en-us/library/367eeye0.aspx&lt;/A&gt; &lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9919308" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/pfedev/attachment/9919308.ashx" length="7048" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/pfedev/archive/tags/Zach/default.aspx">Zach</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/Win32/default.aspx">Win32</category></item><item><title>IIS and Hyper-V</title><link>http://blogs.msdn.com/pfedev/archive/2009/09/03/iis-and-hyper-v.aspx</link><pubDate>Fri, 04 Sep 2009 00:01:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9891178</guid><dc:creator>zakramer</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/pfedev/comments/9891178.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pfedev/commentrss.aspx?PostID=9891178</wfw:commentRss><description>&lt;p&gt;The other day the topic came up about best practices with IIS and Hyper-V.&amp;#160; One of our team mates pointed out the following links which are an interesting read:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://www.virtualization.info/2008/05/microsoft-migrates-msdn-and-technet-on.html" href="http://www.virtualization.info/2008/05/microsoft-migrates-msdn-and-technet-on.html"&gt;http://www.virtualization.info/2008/05/microsoft-migrates-msdn-and-technet-on.html&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a title="http://blogs.iis.net/mailant/archive/2008/05/29/technet-msdn-iis7-front-end-servers-running-100-virtualized-using-hyper-v.aspx" href="http://blogs.iis.net/mailant/archive/2008/05/29/technet-msdn-iis7-front-end-servers-running-100-virtualized-using-hyper-v.aspx"&gt;http://blogs.iis.net/mailant/archive/2008/05/29/technet-msdn-iis7-front-end-servers-running-100-virtualized-using-hyper-v.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;These go over the migration of MSDN/TechNet infrastructure over to Hyper-V.&amp;#160; Cool stuff!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9891178" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pfedev/archive/tags/Zach/default.aspx">Zach</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/IIS/default.aspx">IIS</category></item><item><title>Windows Server 2003 Service Pack 2 and 24-bit Color TS Connections</title><link>http://blogs.msdn.com/pfedev/archive/2009/03/23/windows-server-2003-service-pack-2-and-24-bit-color-ts-connections.aspx</link><pubDate>Mon, 23 Mar 2009 22:13:34 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9502293</guid><dc:creator>zakramer</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/pfedev/comments/9502293.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pfedev/commentrss.aspx?PostID=9502293</wfw:commentRss><description>&lt;p&gt;Okay this is a really weird one!&amp;#160; When you install Service Pack 2 on Windows Server 2003 you can no longer connect using MSTSC via Terminal Services (TS)/Remote Desktop(RDP) with a 24-bit color setting.&amp;#160; For the customer I was working with this meant that the applications they are hosting on those servers did not look good at all over this down graded connection.&amp;#160; For them it meant a blocker to upgrading to SP2.&amp;#160; This has gotten more important recently because Service Pack 1 for Windows Server 2003 is about to be out of support.&lt;/p&gt;  &lt;p&gt;So a hunt ensued for how to get this working.&amp;#160; It turns out that there was a bug in Service Pack 2 that disable some of these higher bit rates.&amp;#160; The bug was corrected in KB – 942610 although this was not apparent that it applied to my problem since the description was different.&amp;#160; However it turns out that the same underlying issue was causing both problems.&amp;#160; A couple of other changes needed to happen and then everything was working.&amp;#160; Here are the steps that I came up with to take a Win2K3 SP2 box and enable 24-bit Color Connections:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Install the following hotfix - &lt;a href="http://support.microsoft.com/kb/942610"&gt;http://support.microsoft.com/kb/942610&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Update the following registry key to enable the fix:     &lt;br /&gt;      &lt;br /&gt;Registry subkey: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server      &lt;br /&gt;Registry entry: AllowHigherColorDepth      &lt;br /&gt;Type: REG_DWORD      &lt;br /&gt;Value: 1      &lt;br /&gt;      &lt;br /&gt;Note that I found the hotfix does add this registry key but it had the value set to 0 so it disabled the fix.&amp;#160; I had to change it to 1.&amp;#160; Also, typical warnings about editing the registry apply.&amp;#160; If you go crazy you can toast your box so back up stuff first!&amp;#160; For those that are sticklers here is the official warning:&lt;/li&gt;    &lt;blockquote&gt;     &lt;p&gt;&lt;b&gt;Important&lt;/b&gt; This section, method, or task contains steps that tell you how to modify the registry. However, serious problems might occur if you modify the registry incorrectly. Therefore, make sure that you follow these steps carefully. For added protection, back up the registry before you modify it. Then, you can restore the registry if a problem occurs. For more information about how to back up and restore the registry, click the following article number to view the article in the Microsoft Knowledge Base: &lt;/p&gt;      &lt;p&gt;&lt;a href="http://support.microsoft.com/kb/322756/"&gt;322756&lt;/a&gt; How to back up and restore the registry in Windows&lt;/p&gt;   &lt;/blockquote&gt; &lt;/ol&gt;  &lt;ol&gt;   &lt;li&gt;Ensure the TS box is excepting 24-bit connections&lt;/li&gt;    &lt;ol&gt;     &lt;li&gt;Go to Start-&amp;gt;Run&lt;/li&gt;      &lt;li&gt;Type “tscc.msc” and hit enter&lt;/li&gt;      &lt;li&gt;Click “Connections”&lt;/li&gt;      &lt;li&gt;Right click on “Rdp-tcp” and select properties&lt;/li&gt;      &lt;li&gt;Click the “Client Settings” tab&lt;/li&gt;      &lt;li&gt;Ensure that “Limit Maximum Color Depth” is set to 24-bit&lt;/li&gt;   &lt;/ol&gt;    &lt;li&gt;Restart the server to ensure everything is set.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Hope this helps!&lt;/p&gt;  &lt;p&gt;Thanks,   &lt;br /&gt;Zach&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9502293" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pfedev/archive/tags/Zach/default.aspx">Zach</category></item><item><title>Combining NetMon CAP Files</title><link>http://blogs.msdn.com/pfedev/archive/2009/03/14/combing-netmon-cap-files.aspx</link><pubDate>Sat, 14 Mar 2009 02:37:37 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9473836</guid><dc:creator>zakramer</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/pfedev/comments/9473836.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pfedev/commentrss.aspx?PostID=9473836</wfw:commentRss><description>&lt;p&gt;Today I was working on a problem that we thought was network related.&amp;#160; That meant it was time to try out some of those NetMon skills.&amp;#160; NetMon is the Microsoft Network Packet Capture and Analysis tool that is similar to WireShark/ethereal and can the current 3.2 version can be download for free from here - &lt;a title="http://www.microsoft.com/downloads/details.aspx?FamilyID=f4db40af-1e08-4a21-a26b-ec2f4dc4190d&amp;amp;DisplayLang=en" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=f4db40af-1e08-4a21-a26b-ec2f4dc4190d&amp;amp;DisplayLang=en"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyID=f4db40af-1e08-4a21-a26b-ec2f4dc4190d&amp;amp;DisplayLang=en&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;For the longest time I am a lot of my colleagues used WireShark/ethereal to do network captures.&amp;#160; However Netmon has come a long way and I really am a big fan of it now.&lt;/p&gt;  &lt;p&gt;Back to my problem today.&amp;#160; We were dealing with a Web Server that has a decent amount of traffic and problem that occurred intermittently.&amp;#160; I first started just capturing with the UI but quickly saw the memory grow and the box slow down a bit.&amp;#160; I did not need to see the traffic going by I just needed to do a capture.&amp;#160; This lead me to the &lt;a href="http://blogs.technet.com/netmon/archive/2006/10/24/nmcap-the-easy-way-to-automate-capturing.aspx"&gt;NMCAP&lt;/a&gt; tool that ships with NetMon.&amp;#160; This is a basic command line tool that allows you do to do captures.&lt;/p&gt;  &lt;p&gt;So I started capturing and by default if you use the *.chn extension on the file name you specify it will create 20 MB CAP files with your network data.&amp;#160; This as great.&amp;#160; I could easily filter out the ones I did not want while I awaited the problem.&lt;/p&gt;  &lt;p&gt;Finally the problem reproduced and now I was ready to analyze.&amp;#160; I opened the trace closest to when the problem occurred and began working through the trace.&amp;#160; I quickly found some conversations that I was interested but – Where was the beginning? Where was the end?&lt;/p&gt;  &lt;p&gt;The answer to this – In some of the other traces!&lt;/p&gt;  &lt;p&gt;Now I had 3, 4, 5, 6 different traces open and that was no good.&amp;#160; I quickly wanted to be able to combine the 6 or 10 traces that I was interested it.&amp;#160; I found out that the same NMCAP tool can easily do this.&amp;#160; All you have to do is use the /InputCapture param.&amp;#160; You end up with a command line like this:&lt;/p&gt;  &lt;p&gt;namcap /InputCapture Trace1.cap Trace2.cap Trace3.cap /capture /file Trace.cap:500M&lt;/p&gt;  &lt;p&gt;This was a life saver so I thought I would pass it along!&amp;#160; Enjoy and have a great weekend.&lt;/p&gt;  &lt;p&gt;Thanks,&lt;/p&gt;  &lt;p&gt;Zach&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9473836" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pfedev/archive/tags/Zach/default.aspx">Zach</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/NetMon/default.aspx">NetMon</category></item><item><title>.NET Framework 2.0 Service Pack 2</title><link>http://blogs.msdn.com/pfedev/archive/2009/01/27/net-framework-2-0-service-pack-2.aspx</link><pubDate>Tue, 27 Jan 2009 09:44:50 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9376945</guid><dc:creator>zakramer</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/pfedev/comments/9376945.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pfedev/commentrss.aspx?PostID=9376945</wfw:commentRss><description>&lt;p&gt;I have worked with several customers that want .NET Framework 2.0 SP2 but do not want to either require their customers to install .NET Framework 3.5 w/ SP1 or do not want to do it themselves.&lt;/p&gt;  &lt;p&gt;Well due to the way it was packaged up until this point that was the only way to get it.&amp;#160; However ask of just the other week they finally released a standalone installer for .NET Framework 2.0 Service Pack 2:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://www.microsoft.com/downloads/details.aspx?FamilyID=5b2c0358-915b-4eb5-9b1d-10e506da9d0f&amp;amp;displaylang=en" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=5b2c0358-915b-4eb5-9b1d-10e506da9d0f&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyID=5b2c0358-915b-4eb5-9b1d-10e506da9d0f&amp;amp;displaylang=en&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This is great news and will make the deployment a bit easier for people on Windows XP and Windows Server 2003.&amp;#160; For Vista and Windows Server 2008 you still have to get .NET Framework 3.5 SP1 installed to get .NET Framework 2.0 SP2.&lt;/p&gt;  &lt;p&gt;Finally, make sure that you also install the following update - &lt;a title="http://support.microsoft.com/kb/959209" href="http://support.microsoft.com/kb/959209"&gt;http://support.microsoft.com/kb/959209&lt;/a&gt;.&amp;#160; This update fixes some of the known issues that have been found with the service packs since their release.&lt;/p&gt;  &lt;p&gt;Have a great day and happy installing!&lt;/p&gt;  &lt;p&gt;Zach&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9376945" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pfedev/archive/tags/Zach/default.aspx">Zach</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/.NET/default.aspx">.NET</category></item><item><title>Windows Error Reporting (WER) Web Service</title><link>http://blogs.msdn.com/pfedev/archive/2008/12/03/windows-error-reporting-wer-web-service.aspx</link><pubDate>Wed, 03 Dec 2008 18:11:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9170313</guid><dc:creator>zakramer</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/pfedev/comments/9170313.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pfedev/commentrss.aspx?PostID=9170313</wfw:commentRss><description>&lt;p&gt;I have long thought that one of the coolest features of the Windows OS for developers is the Windows Error Reporting infrastructure (with roots in Dr. Watson).&amp;#160; You can have your application upload dumps to the WinQual portal – &lt;a href="http://winqual.microsoft.com"&gt;http://winqual.microsoft.com&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;One of the problems though has always been getting those dumps off of the WER site.&amp;#160; Before it was a manual process of going to the WinQual website and download CAB files.&amp;#160; Well I found out today that the WER team recently released a Web Service that allows you to pull them down automatically.&amp;#160;&amp;#160; They have also released some sample applications to get you started:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Windows Error Reporting on CodePlex - &lt;a title="http://www.codeplex.com/wer" href="http://www.codeplex.com/wer"&gt;http://www.codeplex.com/wer&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This opens up all sorts of possibilities such as automatically creating bugs in your bug DB (TFS hopefully!) in response to a new dump file getting uploaded so that someone on your team can take a look.&lt;/p&gt;  &lt;p&gt;Finally the WER team has a blog up and running (&lt;a href="http://blogs.msdn.com/wer"&gt;http://blogs.msdn.com/wer&lt;/a&gt;) and their first entry discusses this and has some demo videos from PDC:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a title="http://blogs.msdn.com/wer/archive/2008/11/25/windows-error-reporting-wer-blog.aspx" href="http://blogs.msdn.com/wer/archive/2008/11/25/windows-error-reporting-wer-blog.aspx"&gt;http://blogs.msdn.com/wer/archive/2008/11/25/windows-error-reporting-wer-blog.aspx&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;  &lt;p&gt;Zach&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9170313" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pfedev/archive/tags/Zach/default.aspx">Zach</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/WinDBG/default.aspx">WinDBG</category></item><item><title>Best Practice - &lt;GeneratePublisherEvidence&gt; in ASPNET.CONFIG</title><link>http://blogs.msdn.com/pfedev/archive/2008/11/26/best-practice-generatepublisherevidence-in-aspnet-config.aspx</link><pubDate>Wed, 26 Nov 2008 06:23:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9141159</guid><dc:creator>zakramer</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/pfedev/comments/9141159.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pfedev/commentrss.aspx?PostID=9141159</wfw:commentRss><description>&lt;h1&gt;Best Practice Recommendation&lt;/h1&gt;  &lt;p&gt;Add the following line to your ASPNET.CONFIG or APP.CONFIG file:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&amp;lt;?xml version=&lt;span class="str"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt; encoding=&lt;span class="str"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;?&amp;gt;
&amp;lt;configuration&amp;gt;
    &amp;lt;runtime&amp;gt;
        &amp;lt;generatePublisherEvidence enabled=&lt;span class="str"&gt;&amp;quot;false&amp;quot;&lt;/span&gt;/&amp;gt;
    &amp;lt;/runtime&amp;gt;
&amp;lt;/configuration&amp;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;p&gt;Note the ASPNET.CONFIG file is located in Framework Directory for the version of the Framework you are using.&amp;#160; For example for a 64-bit ASP.NET application it would be:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;c:\Windows\Microsoft.NET\Framework64\v2.0.50727&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For a 32-bit application it would be:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;c:\Windows\Microsoft.NET\Framework\v2.0.50727&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;Details&lt;/h1&gt;

&lt;p&gt;I have seen this a bunch of times while onsite.&amp;#160; The problem goes something like this:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;When I restart my ASP.NET application the initial page load is very slow.&amp;#160; Sometimes upwards of 30+ seconds.&amp;#160; &lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Many people just blame this on “.NET Startup” costs but there is no out of the box reason that an ASP.NET application should take that long to load.&amp;#160; Some applications do work on startup which can cause a startup slow down but there are other things that cause slow downs.&amp;#160; A common cause that I have seen often recently is &lt;a href="http://technet.microsoft.com/en-us/library/bb457027.aspx"&gt;Certificate Revocation List (CRL)&lt;/a&gt; checking when generating &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.policy.publisher.aspx"&gt;Publisher Evidence&lt;/a&gt; for &lt;a href="http://msdn.microsoft.com/en-us/library/930b76w0.aspx"&gt;Code Access Security (CAS)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A little background – CAS is feature in .NET that allows you to have more granular control over what code can execute in your process.&amp;#160; Basically there are 3 parts:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Evidence &lt;/strong&gt;– Information that a module/code presents to the runtime.&amp;#160; This can be where the module was loaded from, the hash of the binary, strong name, and importantly for this case the &lt;a href="http://msdn.microsoft.com/en-us/library/ms537359.aspx"&gt;Authenticode&lt;/a&gt; signature that identifies a modules publisher. &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;Permissions Set&lt;/strong&gt; – Group of Permissions to give code (Access to File System, Access to AD, Access to Registry) &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;Code Group – &lt;/strong&gt;The evidence is used to provide membership in a code group.&amp;#160; Permission Sets are granted to a code group. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So when a module loads it presents a bunch of evidence to the CLR and the CLR validates it.&amp;#160; One type of evidence is the “publisher” of the module.&amp;#160; This evidence is validated by looking at the Authenticode signature which involves a Certificate.&amp;#160; When validating the Certificate the OS walks the chain of Certificates and tries to download the Certificate Revocation List from a server on the internet.&amp;#160; This is where the slowdown occurs.&lt;/p&gt;

&lt;p&gt;A lot of servers do not have access to make calls out to internet.&amp;#160; It is either explicitly blocked, the server might be on a secure network, or a proxy server might require credentials to gain access to the internet.&amp;#160; If the DNS/network returns quickly with a failure the OS check will move on but if the DNS/network is slow or does not respond at all to the request we have to timeout.&amp;#160; &lt;/p&gt;

&lt;p&gt;This can occur for multiple modules because we create this evidence for each module that is loaded.&amp;#160; However if we have looked for a CRL and failed we will not recheck.&amp;#160; However different certificates have different CRLs.&amp;#160; For instance a VeriSign Certificate may have one CRL URL but a Microsoft Certificate will have a different one.&lt;/p&gt;

&lt;p&gt;Since this probe can slow things down it is best to just avoid the probe if you do not need it.&amp;#160; For .NET the only reason you would need it is if you are setting Code Access Security based on the module Publisher.&amp;#160; Because this can cause potential slow downs and you do not need to occur this penalty you can just disable the generation of the Publisher Evidence when your module is loaded.&amp;#160; To disable this use the &lt;a href="http://msdn.microsoft.com/en-us/library/bb629393.aspx"&gt;&amp;lt;generatePublisherEvidence&amp;gt;&lt;/a&gt; Application configuration.&amp;#160; Just set the enabled property to false and you will avoid all of this.&lt;/p&gt;

&lt;p&gt;Now for ASP.NET applications it was not immediately obvious how to do this but it turns out that you cannot add this to an applications Web.Config but you can add it to the ASPNET.CONFIG file in the Framework directory.&amp;#160; For other applications just add the attribute to the APP.CONFIG file.&lt;/p&gt;

&lt;p&gt;In closing there are several blog entries that do a great job of demonstrating how this will show up in the debugger and other details on CRL issues and workarounds:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a title="http://blogs.msdn.com/tom/archive/2008/10/28/web-site-stops-responding-for-15-25-seconds.aspx" href="http://blogs.msdn.com/tom/archive/2008/10/28/web-site-stops-responding-for-15-25-seconds.aspx"&gt;http://blogs.msdn.com/tom/archive/2008/10/28/web-site-stops-responding-for-15-25-seconds.aspx&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a title="http://blogs.msdn.com/tess/archive/2008/05/13/asp-net-hang-authenticode-signed-assemblies.aspx" href="http://blogs.msdn.com/tess/archive/2008/05/13/asp-net-hang-authenticode-signed-assemblies.aspx"&gt;http://blogs.msdn.com/tess/archive/2008/05/13/asp-net-hang-authenticode-signed-assemblies.aspx&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a title="http://blogs.msdn.com/dougste/archive/2008/02/29/should-i-authenticode-sign-my-net-assembly.aspx" href="http://blogs.msdn.com/dougste/archive/2008/02/29/should-i-authenticode-sign-my-net-assembly.aspx"&gt;http://blogs.msdn.com/dougste/archive/2008/02/29/should-i-authenticode-sign-my-net-assembly.aspx&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are highlighting this as the first in a series of general best practice recommendations.&lt;/p&gt;

&lt;p&gt;NOTE – If you have .NET 2.0 RTM you will need this hotfix - &lt;a title="http://support.microsoft.com/default.aspx/kb/936707" href="http://support.microsoft.com/default.aspx/kb/936707"&gt;http://support.microsoft.com/default.aspx/kb/936707&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9141159" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pfedev/archive/tags/Zach/default.aspx">Zach</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/Best+Practice/default.aspx">Best Practice</category></item><item><title>Why is my Window Grayed Out?</title><link>http://blogs.msdn.com/pfedev/archive/2008/11/15/why-is-my-window-grayed-out.aspx</link><pubDate>Sat, 15 Nov 2008 03:57:15 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9082724</guid><dc:creator>zakramer</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/pfedev/comments/9082724.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pfedev/commentrss.aspx?PostID=9082724</wfw:commentRss><description>&lt;p&gt;Starting back in Windows 2000, if I recall correctly, the OS added a feature to try and handle unresponsive windows.&amp;#160; The idea is that if an application hangs we do not want the window that is associated with that application to block other stuff that the user is trying to do.&amp;#160; This feature has been improved through Windows XP and now into Vista.&amp;#160; The feature is not pretty good.&lt;/p&gt;  &lt;p&gt;When the OS detects that the application is not “responding” to messages it will take control of y&lt;/p&gt;  &lt;p&gt;I came across this when working with a customer that has a client side application.&amp;#160; It is single threaded for the most part and has a work flow like this:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Start long running Operation&lt;/li&gt;    &lt;li&gt;Prevent painting main UI and ignore most input to that region&lt;/li&gt;    &lt;li&gt;Update Status Pane via periodic calls to pump messages for that pane&lt;/li&gt;    &lt;li&gt;Update full UI after the operation is complete&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This is not an uncommon scenario especially for application that have been around for a while.&amp;#160; Sometimes it can be very hard to allow the window to paint during some long running applications and while allowing painting is the real answer there are times where this is MUCH easier said than done. &lt;/p&gt;  &lt;p&gt;The feature that grays out windows seems to have gotten more aggressive in Windows Vista to better detect various hang scenarios.&amp;#160; This is why this became an issue for them.&amp;#160; Basically it was becoming more common to see the graying or “ghosting” of the application’s window.&amp;#160; This lead to users thinking the application was dead (the status bar also gets grayed out) and terminating the application.&amp;#160; In XP the application would stay there and while the main part of the UI would not respond you could still watch the status bar move.&lt;/p&gt;  &lt;p&gt;The question though became what do we do about this?&amp;#160; The obvious answer is make the application responsive during the long running application.&amp;#160; While this is a goal there is no short term way to do this.&amp;#160; We tried a bit to pump more messages but run into a sticky issue – How do I “appear” responsive without actually being responsive.&amp;#160; We were basically trying to guess what the OS was looking for and since this can change, as we have seen, this is not reliable.&lt;/p&gt;  &lt;p&gt;After some digging I found an interesting API:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;DisableProcessWindowGhosting     &lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms648415.aspx"&gt;http://msdn.microsoft.com/en-us/library/ms648415.aspx&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Basically this API tells the OS to skip the ghosting even it detects the application as unresponsive.&amp;#160; This API will take effect for the run of the application.&lt;/p&gt;  &lt;p&gt;The real answer is to fix the application to be responsive as&amp;#160; mentioned but that is not always easy so this is a stop gap.&amp;#160; &lt;/p&gt;  &lt;p&gt;Side note is that when you debug an application the graying or ghosting of the window will not occur.&amp;#160; So if you are trying to reproduce make sure that you are running outside of the debugger (this got me when trying to reproduce!)&lt;/p&gt;  &lt;p&gt;Hope this helps and have a great weekend!&lt;/p&gt;  &lt;p&gt;Zach&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9082724" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pfedev/archive/tags/Zach/default.aspx">Zach</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/Win32/default.aspx">Win32</category></item><item><title>$(SolutionDir) and MSBUILD</title><link>http://blogs.msdn.com/pfedev/archive/2008/09/26/solutiondir-and-msbuild.aspx</link><pubDate>Sat, 27 Sep 2008 01:02:58 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8967086</guid><dc:creator>zakramer</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/pfedev/comments/8967086.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pfedev/commentrss.aspx?PostID=8967086</wfw:commentRss><description>&lt;p&gt;A while back I was working with a customer that was moving from doing all of their builds with the devenv command line to using MSBUILD.&amp;#160; However we ran into a hiccup that did not make sense at first.&amp;#160; Basically when they tried to build their solution using MSBUILD some of the custom build steps where failing because $(SolutionDir) was not defined.&amp;#160; &lt;/p&gt;  &lt;p&gt;After thinking about it a bit is became clear that MSBUILD did not define the SolutionBuild property that Visual Studio does.&amp;#160; So where did that leave us?&lt;/p&gt;  &lt;p&gt;There are a couple of basic approaches:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Create a Custom Action (this would involve Custom Code) that walked up the directory structure and found the SLN file and then used that directory to create the SolutionDir.&lt;/li&gt;    &lt;li&gt;Use the command line option /Property:SolutionDir=&amp;lt;sln Dir&amp;gt; to set the value.&amp;#160; This way it is controlled in one place.&lt;/li&gt;    &lt;li&gt;Change all of the pathing to be relative.&amp;#160; In most groups it is relatively infrequent to be moving projects up and down the directory hierarchy.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Just thought I would share incase this comes up for someone else.&lt;/p&gt;  &lt;p&gt;Zach&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8967086" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pfedev/archive/tags/Zach/default.aspx">Zach</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/VSTS/default.aspx">VSTS</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/.NET/default.aspx">.NET</category></item><item><title>All the Ways to Capture a Dump...</title><link>http://blogs.msdn.com/pfedev/archive/2008/09/26/all-the-ways-to-capture-a-dump.aspx</link><pubDate>Fri, 26 Sep 2008 02:06:58 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8965715</guid><dc:creator>zakramer</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/pfedev/comments/8965715.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pfedev/commentrss.aspx?PostID=8965715</wfw:commentRss><description>&lt;p&gt;Frequently when troubleshooting a problem we capture a memory dump.&amp;#160; Memory dumps are a great tool because they are a complete snapshot of what a process is doing at the time the dump is captured.&amp;#160; It can be a great forensic tool.&amp;#160; There are however an abundance of tools to capture memory dumps (*.dmp).&amp;#160; In talking with some new members on our team we were reviewing the dump capture techniques and the benefits/drawbacks.&amp;#160; If you have your own thoughts please feel free to comment.&lt;/p&gt;  &lt;p&gt;Memory dumps are captured under two categories of problems: The first category is hang dump captured when the application is non-responsive or when you just want a snapshot of the current state of the application. The second category is a crash dump captured when exceptions occur. The debugging purpose, the actions we would instruct the debugger to take would be different for both types of dump. &lt;/p&gt;  &lt;p&gt;For hang dumps, we would instruct debugger to attach to the process (if there is no debugger attached) and initiate the dumping immediately. For crash dumps, we would like to attach a debugger to a process first and then set up the instruction to monitor the type of exceptions we are interested in and generate a memory dump upon the exception is raised. We will discuss different ways to generate memory dumps.&lt;/p&gt;  &lt;p&gt;First let's take a look at some of more specific scenarios when capturing a dump file (these are grouped for the most part into crash or hang based on what they relate to.&amp;#160; There are definitely a lot more variants but these are some basic ones that we can use to compare the different debuggers:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;Crash&lt;/strong&gt;&lt;/li&gt;    &lt;ol&gt;     &lt;li&gt;Create a dump file when an application &lt;strong&gt;crashes &lt;/strong&gt;(an exception has occurred that causes the process to terminate) &lt;/li&gt;      &lt;li&gt;Creating a dump file from an application that fails during &lt;b&gt;startup&lt;/b&gt;&lt;/li&gt;   &lt;/ol&gt;    &lt;li&gt;&lt;strong&gt;Hang&lt;/strong&gt;&lt;/li&gt;    &lt;ol&gt;     &lt;li&gt;Create a dump file when an application &lt;b&gt;hangs&lt;/b&gt; (stops responding but does not actually crash) &lt;/li&gt;      &lt;li&gt;Creating a dump file while an application is &lt;b&gt;running normally&lt;/b&gt;&amp;#160; &lt;/li&gt;   &lt;/ol&gt;    &lt;li&gt;&lt;strong&gt;First Chance &lt;/strong&gt;- Creating a dump file when an application encounters any &lt;strong&gt;exception &lt;/strong&gt;during the run of the application&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Smaller Dump &lt;/strong&gt;- Shrinking an existing dump file to reduce the amount of information in the dump file&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;For each of these scenarios how do the debuggers measure up:&lt;/p&gt;  &lt;table cellspacing="0" cellpadding="2" width="497" border="2"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" align="center" width="180"&gt;&lt;strong&gt;Debsuggers/Scenarios&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" align="center" width="82"&gt;&lt;strong&gt;Crash&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" align="center" width="78"&gt;&lt;strong&gt;Hang&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" align="center" width="81"&gt;&lt;strong&gt;First Chance&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" align="center" width="72"&gt;&lt;strong&gt;Smaller Dump&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="182"&gt;DebugDiag&lt;/td&gt;        &lt;td valign="top" width="83"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="79"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="83"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="75"&gt;No&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="183"&gt;ADPlus&lt;/td&gt;        &lt;td valign="top" width="83"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="79"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="84"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="77"&gt;No&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="183"&gt;CDB/Windbg&lt;/td&gt;        &lt;td valign="top" width="82"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="78"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="84"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="79"&gt;Yes&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="182"&gt;Dr. Watson&lt;/td&gt;        &lt;td valign="top" width="82"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="78"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="84"&gt;No&lt;/td&gt;        &lt;td valign="top" width="80"&gt;No&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="181"&gt;UserDump&lt;/td&gt;        &lt;td valign="top" width="82"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="78"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="84"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="81"&gt;No&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="183"&gt;NTSD&lt;/td&gt;        &lt;td valign="top" width="81"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="77"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="84"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="81"&gt;Yes&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="183"&gt;Visual Studio&lt;/td&gt;        &lt;td valign="top" width="81"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="77"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="84"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="81"&gt;No&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="183"&gt;Vista Crash Dump Features&lt;/td&gt;        &lt;td valign="top" width="81"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="77"&gt;Yes&lt;/td&gt;        &lt;td valign="top" width="84"&gt;No&lt;/td&gt;        &lt;td valign="top" width="81"&gt;No&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Next let’s take a quick look at how you might use each one and then we will explore a bit more:&lt;/p&gt;  &lt;table cellspacing="0" cellpadding="0" width="663" border="1"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="bottom" width="214"&gt;&amp;#160;&lt;/td&gt;        &lt;td valign="bottom" width="221"&gt;         &lt;p&gt;&lt;b&gt;Crash&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="bottom" width="226"&gt;         &lt;p&gt;&lt;b&gt;Hang&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="bottom" width="214"&gt;         &lt;p&gt;&lt;b&gt;ADPlus&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="bottom" width="221"&gt;         &lt;p&gt;Adplus –crash –quiet -o c:\dumps –pn &amp;lt;processname.exe&amp;gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="bottom" width="226"&gt;         &lt;p&gt;adplus -hang -quiet -o c:\dumps -pn &amp;lt;processName.exe &lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="bottom" width="214"&gt;         &lt;p&gt;&lt;b&gt;Dr. Watson&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="bottom" width="221"&gt;&amp;#160;&lt;/td&gt;        &lt;td valign="bottom" width="226"&gt;&amp;#160;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="bottom" width="214"&gt;         &lt;p&gt;&lt;b&gt;CDB and WinDbg&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="bottom" width="221"&gt;         &lt;p&gt; .dump /ma c:\w3wp.dmp&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="bottom" width="226"&gt;         &lt;p&gt; .dump /ma c:\w3wp.dmp&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="bottom" width="214"&gt;         &lt;p&gt;&lt;b&gt;UserDump&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="bottom" width="221"&gt;         &lt;p&gt;&lt;em&gt;see &lt;/em&gt;&lt;u&gt;Additional Details&lt;/u&gt; &lt;em&gt;below&lt;/em&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="bottom" width="226"&gt;         &lt;p&gt;Userdump PID&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="bottom" width="214"&gt;         &lt;p&gt;&lt;b&gt;DebugDiag&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="bottom" width="221"&gt;         &lt;p&gt;Create a Crash Rule with Wizard&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="bottom" width="226"&gt;         &lt;p&gt;Right click on the process in Processes and select Full Memory Dump.&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="bottom" width="214"&gt;         &lt;p&gt;&lt;b&gt;MiniDumpWriteDump&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="bottom" width="221"&gt;         &lt;p&gt;&lt;em&gt;see &lt;/em&gt;&lt;u&gt;Additional Details&lt;/u&gt; &lt;em&gt;below&lt;/em&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="bottom" width="226"&gt;         &lt;p&gt;&lt;em&gt;see &lt;/em&gt;&lt;u&gt;Additional Details&lt;/u&gt; &lt;em&gt;below&lt;/em&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="bottom" width="214"&gt;         &lt;p&gt;&lt;b&gt;Visual Studio&lt;/b&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="bottom" width="221"&gt;         &lt;p&gt;Debug | Save Dump As...&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="bottom" width="226"&gt;Debug | Save Dump As…&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;There are many ways to capture a memory dump as you can see above. Depending on the nature of the problem, a hang or crash dump can be captured using different tools. &lt;/p&gt;  &lt;p&gt;For quick and easy hang dump in production environment that installing tools might be an issue, using NTSD debugger that is distributed with Windows XP/Server 2003 can be easy. &lt;/p&gt;  &lt;p&gt;However we frequently recommend to our customers to have the Debugging Tools for Windows and DebugDiag available for their servers.&amp;#160; ADPlus has a very low footprint and can be great to capture memory dumps with.&amp;#160; DebugDiag is super easy and great for setting up rules to generate dumps.&amp;#160; Unless there is a special case DebugDiag is the way to go. &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;h3&gt;Additional Details&lt;/h3&gt;  &lt;p&gt;Below are some details for most of the tools that we outlined above and when they might come in handy.&lt;/p&gt;  &lt;h3&gt;&lt;u&gt;External Tools&lt;/u&gt;&lt;/h3&gt;  &lt;h4&gt;DebugDiag.exe from Debug Diagnostic Tool&lt;/h4&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Where do I get it?&lt;/u&gt;&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;DebugDiag is another free downloadable tool from Microsoft. To download, search for “Debug Diagnostic Tool v1.1” from &lt;a href="http://www.microsoft.com/downloads"&gt;http://www.microsoft.com/downloads&lt;/a&gt; or specifically &lt;a title="http://www.microsoft.com/downloads/details.aspx?FamilyID=28bd5941-c458-46f1-b24d-f60151d875a3&amp;amp;displaylang=en" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=28bd5941-c458-46f1-b24d-f60151d875a3&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyID=28bd5941-c458-46f1-b24d-f60151d875a3&amp;amp;displaylang=en&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;How do I use it?&lt;/u&gt;&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Hang&lt;/strong&gt; - In “Processes” tab, select the process with right mouse, select “Create Full User Dump”. The memory dump will be located at under Logs\Misc folder under the installation folder of DebugDiag.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Crash - &lt;/strong&gt;Select Rules tab. Click “Add Rule” button. Select “Crash” as the rule type. Click “Next” button. Select target type, for instance, “A Specific Process”. Click “Next” buttons to finish. DebugDiag will monitor crashes and when a memory dump is captured, it will show the number in the “UserDump” column of the Rules panel. &lt;/p&gt;  &lt;p&gt;DebugDiag supports multiple crash rules to monitor multiple processes. It also supports many other configurations. For more information, please refer to the help file that is installed with DebugDiag. &lt;/p&gt;  &lt;p&gt;Also see the DebugDiag blog for additional information – &lt;a href="http://blogs.msdn.com/debugdiag/"&gt;http://blogs.msdn.com/debugdiag/&lt;/a&gt; &lt;/p&gt;  &lt;h4&gt;Debugging Tools for Windows (WinDBG, CDB, ADPlus)&lt;/h4&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Where do I get it?&lt;/u&gt;&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;This set of tools is downloadable for free from &lt;a href="http://www.microsoft.com/whdc/devtools/debugging/default.mspx"&gt;http://www.microsoft.com/whdc/devtools/debugging/default.mspx&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;How do I use it?&lt;/u&gt;&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;Assuming it will be installed to C:\Debuggers folder, we will use that folder for examples. &lt;/p&gt;  &lt;blockquote&gt;   &lt;h5&gt;Catch a hang dump using ADPLUS.vbs&lt;/h5&gt;    &lt;p&gt;Adplus.vbs is a vbsript that makes your life easy to use cdb debugger. To capture a hang dump to c:\dumps folder from a running instance of NOTEPAD.exe that has process ID 1806, type: &lt;/p&gt;    &lt;p&gt;C:\debuggers&amp;gt;adplus -hang -quiet -o c:\dumps -p 1806 &lt;/p&gt;    &lt;p&gt;To capture hang dumps to c:\dumps for all instances of NOTEPAD.exe, type: &lt;/p&gt;    &lt;p&gt;C:\debuggers&amp;gt;adplus -hang -quiet -o c:\dumps -pn notepad.exe &lt;/p&gt;    &lt;h4&gt;&lt;/h4&gt;    &lt;h5&gt;Catch a crash dump using ADPLUS.vbs&lt;/h5&gt;    &lt;p&gt;To catch a crash dump from a running instance of NOTEPAD with process ID 1806, type: &lt;/p&gt;    &lt;p&gt;C:\debuggers&amp;gt;adplus -crash -quiet -o c:\dumps –p 1806 &lt;/p&gt;    &lt;p&gt;To catch crash dumps on all instances of NOTEPAD.exe, type: &lt;/p&gt;    &lt;p&gt;C:\debuggers&amp;gt;adplus -crash -quiet -o c:\dumps -pn notepad.exe &lt;/p&gt;    &lt;p&gt;Note that after starting adplus, it will quickly exit since all it does is setting up CDB debugger for the work. After adplus command window exits, you will notice CDB command window come up(minimized by default). Just wait till the CDB finishes. The command windows will close. &lt;/p&gt;    &lt;h4&gt;&lt;/h4&gt;    &lt;h5&gt;Catch a crash dump on any crashing process using CDB.exe&lt;/h5&gt;    &lt;p&gt;Since adplus utility can only catch crash dumps for targeted process, it cannot be used system wide to capture crash dump for any crashing process. If we want to overcome the limitation of Dr. Watson, we can use CDB debugger for this purpose. To do this, type: &lt;/p&gt;    &lt;p&gt;C:\debuggers&amp;gt; cdb -iaec &amp;quot;-c \&amp;quot;.dump /u /ma c:\dumps\av.dmp;q\&amp;quot;&amp;quot; &lt;/p&gt;    &lt;p&gt;This will configure CDB debugger as the default handler for crash by AeDebug registry key. You can verify the setting by browsing to registry key: &lt;/p&gt;    &lt;p&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug &lt;/p&gt;    &lt;p&gt;And see these two values: &lt;/p&gt;    &lt;p&gt;Value name: Auto Value data: 1 &lt;/p&gt;    &lt;p&gt;Value name: Debugger Value data: “c:\debuggers\cdb.exe” -p %ld -e %ld -g -c “.dump /ma /u c:\av.dmp;q” &lt;/p&gt;    &lt;p&gt;Except for a different debugger, this configuration is identical to the configuration described above for using NTSD.exe. Since NTSD.exe does not have the feature to configure AeDebug registry key, we have to do it manually in the previous scenario. &lt;/p&gt;    &lt;p&gt;The advantage of using CDB as system wide crash handler is that it can capture crash dumps for any process on Windows XP/Server 2003/Vista.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;There are a lot more features to discuss about the Debugging Tools for Windows and there are a lot of resources out there.&lt;/p&gt;  &lt;p&gt;Before we leave this topic another cool feature of both CDB and WinDBG is that you can load a dump file into them for analysis and if you want to generate a smaller dump file to share the callstacks or something basic with another person via e-mail for instance.&amp;#160; You can generate a minidump using this command while debugging the dump:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;.dump /m c:\smallerDump.dmp&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This can be very helpful for providing a bit of information without having to transfer a huge DMP file.&lt;/p&gt;  &lt;h4&gt;UserDump.exe&lt;/h4&gt;  &lt;p&gt;Crash Dumps and hang dumps can be taken with the User Dump tool.&amp;#160; For all of the details and download information check out &lt;a href="http://support.microsoft.com/kb/241215"&gt;http://support.microsoft.com/kb/241215&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;&lt;u&gt;Dumps and Development Time&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;Now when you are developing there are a couple of cases where you want to look at dump generation.&lt;/p&gt;  &lt;h4&gt;Visual Studio&lt;/h4&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Where do I get it?&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;You purchase it.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;How do I use it?&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;To generate dump files you need to have the C++ tools installed which will enable you to do Native Debugging.&amp;#160; Once you enable Native Debugging then whenever you have “broken” into the debugger you can go to to the &lt;strong&gt;Debug&lt;/strong&gt; menu and select &lt;strong&gt;Save Dump As…&lt;/strong&gt; and that will allow you to save a dump file.&amp;#160; This can be very helpful on a developers machine when they encounter a problem in an application they are debugging and want to save it for later analysis.&amp;#160; Also, I have used this to capture dumps of Visual Studio when it is going weird.&amp;#160; Just pop open a second instance of VS and attach to the first and take a memory dump.&lt;/p&gt;  &lt;h4&gt;MiniDumpWriteDump&lt;/h4&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;Where do I get it?&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This is an API that you would have to build into your application to enable your application to generate a dump file.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;u&gt;How do I use it?&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This is an API to generate dumps so it cannot be used directly but would have to be coded into a tool or application.&amp;#160; So customers will actually bake this into their Native Unhandled Exception filter.&amp;#160; MiniDumpWriteDump can have a dump taken using the following code: &lt;/p&gt;  &lt;pre class="csharpcode"&gt;#include &amp;lt;dbghelp.h&amp;gt;
#include &amp;lt;shellapi.h&amp;gt;
#include &amp;lt;shlobj.h&amp;gt;

&lt;span class="kwrd"&gt;int&lt;/span&gt; GenerateDump(EXCEPTION_POINTERS* pExceptionPointers)
{
    BOOL bMiniDumpSuccessful;
    WCHAR szPath[MAX_PATH]; 
    WCHAR szFileName[MAX_PATH]; 
    WCHAR* szAppName = L&lt;span class="str"&gt;&amp;quot;AppName&amp;quot;&lt;/span&gt;;
    WCHAR* szVersion = L&lt;span class="str"&gt;&amp;quot;v1.0&amp;quot;&lt;/span&gt;;
    DWORD dwBufferSize = MAX_PATH;
    HANDLE hDumpFile;
    SYSTEMTIME stLocalTime;
    MINIDUMP_EXCEPTION_INFORMATION ExpParam;

    GetLocalTime( &amp;amp;stLocalTime );
    GetTempPath( dwBufferSize, szPath );
    StringCchPrintf( szFileName, MAX_PATH, L&lt;span class="str"&gt;&amp;quot;%s%s&amp;quot;&lt;/span&gt;, szPath, szAppName );
    CreateDirectory( szFileName, NULL );

    StringCchPrintf( szFileName, MAX_PATH, L&lt;span class="str"&gt;&amp;quot;%s%s\\%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp&amp;quot;&lt;/span&gt;, 
               szPath, szAppName, szVersion, 
               stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay, 
               stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond, 
               GetCurrentProcessId(), GetCurrentThreadId());

    hDumpFile = CreateFile(szFileName, GENERIC_READ|GENERIC_WRITE, 
                FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);

    ExpParam.ThreadId = GetCurrentThreadId();
    ExpParam.ExceptionPointers = pExceptionPointers;
    ExpParam.ClientPointers = TRUE;

    bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), 
                    hDumpFile, MiniDumpWithDataSegs, &amp;amp;ExpParam, NULL, NULL);

    &lt;span class="kwrd"&gt;return&lt;/span&gt; EXCEPTION_EXECUTE_HANDLER;
}&lt;/pre&gt;

&lt;p&gt;From &lt;a href="http://msdn2.microsoft.com/en-us/library/bb204861.aspx"&gt;http://msdn2.microsoft.com/en-us/library/bb204861.aspx&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Existing tools for Windows XP/Server 2003&lt;/u&gt;&lt;/h3&gt;

&lt;h4&gt;Dr. Watson &lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Where do I get it?&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is found at %SystemRoot%\system32\drwtsn32.exe and is distributed with Windows XP/Server 2003 and earlier versions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;How do I use it?&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Configure Dr. Watson by typing:&lt;/p&gt;

&lt;p&gt;c:\windows\system32&amp;gt;drwtsn32&lt;/p&gt;

&lt;p&gt;You can configure the location of the memory dump (the default location is C:\Documents and Settings\All Users\Application Data\Microsoft\Dr Watson\user.dmp), the type of memory dump (for dump analysis purpose, select “Full” for Crash Dump Type. The default type is Mini). The problem with Dr. Watson is that it overwrites the user.dmp file. If you have more than one process crash or the same process crash due to different reasons, you have to make sure to move the user.dmp file before it is overwritten.&lt;/p&gt;

&lt;h4&gt;NTSD.exe&lt;/h4&gt;

&lt;p&gt;&lt;b&gt;&lt;u&gt;Where do I get it?&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;From %SystemRoot%\System32 folder and is a debugger distributed with Windows XP/Server 2003 and earlier versions. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;How do I use it?&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It’s a command line debugger and can be used to capture crash dump as well as hang dumps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Crash Dump - &lt;/strong&gt;To set up NTSD as system wide handler for crash, add two values under under AeDebug registry key:&lt;/p&gt;

&lt;p&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug&lt;/p&gt;

&lt;p&gt;Value name: Auto Value data: 1&lt;/p&gt;

&lt;p&gt;Value name: Debugger Value data: “ntsd.exe” -p %ld -e %ld -g -c “.dump /ma /u c:\av.dmp;q” &lt;/p&gt;

&lt;p&gt;Make sure to include the quotes in Value data.&lt;/p&gt;

&lt;p&gt;Upon process crash, OS will invoke NTSD.exe which will in turn attach to the process and capture a memory dump by executing the .dump debugger command.&lt;/p&gt;

&lt;p&gt;If you are curious what the command line means, the “-c” switch is for the debug command to be executed by NTSD debugger. The command “.dump” is for generating the memory dump. The switch “/ma” is for mini dump with all data streams. The “/u” switch is for the debugger to use a unique file name based on timestamp. The “;” delimits the first command. The second command “q” is for debugger to terminate the process and exit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hang Dump - &lt;/strong&gt;NTSD is a full featured debugger. It can be used to capture a hang dump given the process ID. For example, if NOTEPAD.exe is running with process ID 1806 (process ID can be obtained from task manager), you can type this command to capture a hang dump:&lt;/p&gt;

&lt;p&gt;C:\&amp;gt;ntsd -c “.dump /ma /u c:\hang.dmp;qd” -p 1806&lt;/p&gt;

&lt;p&gt;If you don’t like to type the whole command line again and again, you can create a batch file: HangDump.bat with this command:&lt;/p&gt;

&lt;p&gt;ntsd -c “.dump /ma /u c:\hang.dmp;qd” -p %1&lt;/p&gt;

&lt;p&gt;To use the batch file, type: &lt;/p&gt;

&lt;p&gt;C:\&amp;gt;HangDump 1806&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Generating dumps with Vista&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;Vista does not ship with Dr. Watson or NTSD. Instead, Vista has “Problem Reports and Solutions” which is located under Control Panel-&amp;gt;System and Maintenance.&lt;/p&gt;

&lt;h4&gt;Capture a hang dump in Vista&lt;/h4&gt;

&lt;p&gt;Inside Task Manager, select the process , right mouse click “Create Dump File”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogs.msdn.com/blogfiles/pfedev/WindowsLiveWriter/AlltheWaystoCaptureaDump_8D95/clip_image002_2.jpg"&gt;&lt;img title="clip_image002" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="122" alt="clip_image002" src="https://blogs.msdn.com/blogfiles/pfedev/WindowsLiveWriter/AlltheWaystoCaptureaDump_8D95/clip_image002_thumb.jpg" width="244" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;Capture a crash dump in Vista&lt;/h4&gt;

&lt;p&gt;For process crash, Windows Error Reporting (WER) will try to analyze the crash first and then display this message box(where BADAPP is the crashing application):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blogs.msdn.com/blogfiles/pfedev/WindowsLiveWriter/AlltheWaystoCaptureaDump_8D95/clip_image004_2.jpg"&gt;&lt;img title="clip_image004" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="124" alt="clip_image004" src="https://blogs.msdn.com/blogfiles/pfedev/WindowsLiveWriter/AlltheWaystoCaptureaDump_8D95/clip_image004_thumb.jpg" width="244" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When clicking “Close program”, the process will exit. By default no crash dump file will be kept on the local system. However, if you wish to retain it, you can modify this registry value ForceQueue to 1, which is located at: &lt;/p&gt;

&lt;p&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting&lt;/p&gt;

&lt;p&gt;For dump files running in system context or elevated are located at:&lt;/p&gt;

&lt;p&gt;%ALLUSERSPROFILE%\Microsoft\Windows\WER\[ReportQueue | ReportArchive]&lt;/p&gt;

&lt;p&gt;Dump files from other processes are located at:&lt;/p&gt;

&lt;p&gt;%LOCALAPPDATA%\Microsoft\Windows\WER\[ReportQueue | ReportArchive]&lt;/p&gt;

&lt;p&gt;Starting with Vista SP1 and Windows Server 2008, more features for crash dumps will be supported. For more information, see &lt;a href="http://msdn2.microsoft.com/en-us/library/bb787181(VS.85).aspx"&gt;Collecting User-Mode Dumps&lt;/a&gt; at &lt;a href="http://msdn2.microsoft.com/en-us/library/bb787181(VS.85).aspx"&gt;http://msdn2.microsoft.com/en-us/library/bb787181(VS.85).aspx&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Credits&lt;/h3&gt;

&lt;p&gt;A lot of people contributed thoughts comments and work to this so I just want to provide them with credit:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Linkai Yu &lt;/strong&gt;who did the bulk of the work. (I will introduce you to him in a subsequent post!)

  &lt;br /&gt;&lt;strong&gt;Michael Wiley, &lt;strong&gt;Pierre Donyegro&lt;/strong&gt;&lt;/strong&gt;, &lt;strong&gt;David Wu&lt;/strong&gt;, &lt;strong&gt;Greg Varveris, Sean Thompson&lt;/strong&gt; and &lt;strong&gt;Aaron Barth &lt;/strong&gt;who contributed and helped review.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8965715" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pfedev/archive/tags/Zach/default.aspx">Zach</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/WinDBG/default.aspx">WinDBG</category></item><item><title>ASP.NET and Unit Tests</title><link>http://blogs.msdn.com/pfedev/archive/2007/11/12/asp-net-and-unit-tests.aspx</link><pubDate>Mon, 12 Nov 2007 07:01:15 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6126203</guid><dc:creator>pfedevblog</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/pfedev/comments/6126203.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pfedev/commentrss.aspx?PostID=6126203</wfw:commentRss><description>&lt;p&gt;I was onsite the other day and the customer wanted to use Visual Studio 2005 to auto generate the Unit Test stubs for their ASP.NET application.&amp;#xA0; They have a lot of rules tied up in the ASP.NET application project.&amp;#xA0; When we tried to generate the Unit tests we kept getting the following error:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Source Code cannot be sufficiently parsed for code generation.&amp;#xA0; Please try to compile your project and fix any issues.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Well, needless to say the project compiled fine (and had been for a while) and ran fine.&amp;#xA0; We could not find any issues to fix.&amp;#xA0; My first thought was that this was a limitation because of the way they created their ASP.NET project.&amp;#xA0; So we got some details:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Originally Created in VS.NET 2003&lt;/li&gt;    &lt;li&gt;Migrated to VS 2005&lt;/li&gt;    &lt;li&gt;They did not convert to the new Page Model with App_Code and such.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;After doing some digging I found out that the Unit Test Generation for some reason expects that the project has at least an empty &amp;quot;Settings.&amp;quot;&amp;#xA0; So we opened the properties on the project and clicked Settings.&amp;#xA0; Sure enough there was nothing there.&amp;#xA0; So we clicked the link to create the &amp;quot;Settings&amp;quot; and got the grid that would enable us to add settings.&amp;#xA0; We just left it blank and rebuilt.&amp;#xA0; At that point we retried the generation of the Unit Tests and everything went smoothly.&lt;/p&gt;  &lt;p&gt;Thanks,   &lt;br /&gt;Zach&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6126203" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pfedev/archive/tags/Zach/default.aspx">Zach</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/Unit+Test/default.aspx">Unit Test</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/VSTS/default.aspx">VSTS</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>Welcome...</title><link>http://blogs.msdn.com/pfedev/archive/2007/11/12/welcome.aspx</link><pubDate>Mon, 12 Nov 2007 06:53:29 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6126069</guid><dc:creator>pfedevblog</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/pfedev/comments/6126069.aspx</comments><wfw:commentRss>http://blogs.msdn.com/pfedev/commentrss.aspx?PostID=6126069</wfw:commentRss><description>&lt;p&gt;Just a quick note about the team that is doing the blogging!&lt;/p&gt;  &lt;p&gt;We are a group of engineers that do onsite support of Microsoft customers that are developing applications (internal to their company and ones that are shipped externally) that are based on Microsoft technologies.&amp;#xA0; This means a lot of debugging and troubleshooting. We are actually the team that is responsible that owns the Advanced Win32 Debugging and Advanced .NET Debugging courses that are taught to Microsoft's Premier Customers.&lt;/p&gt;  &lt;p&gt;In posts on this blog we hope to share some of those experiences with the community to hopefully make things easier for others out there.&amp;#xA0; This will be a team effort so we will be introducing bloggers as they make their debut!&lt;/p&gt;  &lt;p&gt;Since I am kicking off this post I will do my obligatory introduction.&amp;#xA0; My name is Zach Kramer.&amp;#xA0; I have been at Microsoft for about 6 years and on the PFE team for the past 2 years.&amp;#xA0; I focus on C++, ASP.NET, Visual Studio and other developer products.&amp;#xA0; I spend a lot of time debugging issues and I am an instructor both of the debug courses.&amp;#xA0; I have worked with customers all over the US and even some in Europe.&amp;#xA0; I will be following this up with a couple of technical posts so it is not all just fluff. ;-)&lt;/p&gt;  &lt;p&gt;Thanks,   &lt;br /&gt;Zach&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6126069" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/pfedev/archive/tags/Zach/default.aspx">Zach</category><category domain="http://blogs.msdn.com/pfedev/archive/tags/Business/default.aspx">Business</category></item></channel></rss>