<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.wintellect.com/cs/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>Wintellog</title><link>http://www.wintellect.com/cs/blogs/default.aspx</link><description /><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.2)</generator><item><title>WinDBG 6.9.3.113 Released</title><link>http://www.wintellect.com/cs/blogs/jrobbins/archive/2008/05/05/windbg-6-9-3-113-released.aspx</link><pubDate>Mon, 05 May 2008 15:27:25 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:6393</guid><dc:creator>jrobbins</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;Looks like the WinDBG team was busy over the weekend and posted a new build of WinDBG:&lt;a href="http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx"&gt; 6.9.3.113&lt;/a&gt;. The big fixes look like squashed bugs and performance improvements in symbol server portions. I bet you could drop those DLLs into your Visual Studio directories and get the benefit there as well. &lt;/p&gt;&lt;img src="http://www.wintellect.com/cs/aggbug.aspx?PostID=6393" width="1" height="1"&gt;</description></item><item><title>Silverlight Page Turning Made Simple</title><link>http://www.wintellect.com/cs/blogs/jprosise/archive/2008/05/04/silverlight-page-turning-made-simple.aspx</link><pubDate>Mon, 05 May 2008 00:26:00 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:6169</guid><dc:creator>jprosise</dc:creator><slash:comments>0</slash:comments><description>&lt;P&gt;My latest &lt;A class="" title="Silverlight Page Turning Made Simple" href="http://msdn.microsoft.com/en-us/magazine/cc507644.aspx" target=_blank&gt;Wicked Code column&lt;/A&gt; is now online at MSDN Magazine. Titled "Silverlight Page Turning Made Simple," it presents a Silverlight 1.0 framework for building slick page-turning applications. I mentioned the framework in an &lt;A class="" title="Silverlight, SOHACHTOA, and Me" href="http://www.wintellect.com/cs/blogs/jprosise/archive/2008/02/15/silverlight-sohcahtoa-and-me.aspx" target=_blank&gt;earlier blog post&lt;/A&gt; but didn't publish the source code because it needed to appear in MSDN Magazine first. Now you can download it, use it, and modify it to your heart's content.&lt;/P&gt;
&lt;P&gt;And yes, I'll port the framework to Silverlight 2.0 soon.&lt;/P&gt;&lt;img src="http://www.wintellect.com/cs/aggbug.aspx?PostID=6169" width="1" height="1"&gt;</description></item><item><title>My Beef with Vista and IE</title><link>http://www.wintellect.com/cs/blogs/jprosise/archive/2008/05/04/my-beef-with-vista-and-ie.aspx</link><pubDate>Sun, 04 May 2008 23:33:00 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:6165</guid><dc:creator>jprosise</dc:creator><slash:comments>8</slash:comments><description>&lt;P&gt;I have largely avoided problems with Vista by only running it on PCs on which it comes preinstalled. At least I avoided problems until a few weeks ago. With a total of five PCs and laptops now running Vista in my house, the constant avalanche of automatic updates seems to break something every day. The latest issue I’m fighting is one that causes ASP.NET apps launched in IE 7 from Visual Studio 2008 to sometimes start with JavaScript disabled. It’s pretty hard to teach an ASP.NET class when LinkButtons don’t work.&lt;/P&gt;
&lt;P&gt;But worse than having ASP.NET broken on my development box is what IE 7 has done to the PC in the kitchen. For more than 20 years my wife has used my hand-me-down PCs. Last week I bought her her first-ever new PC:&amp;nbsp; a Dell quad-core with 3 GB of RAM, a 500 MB hard disk, a 20-inch LCD monitor, and Vista Home Premium. (For the first time ever, I’m envious of her PC!) At first I was a little hot when Vista didn’t support my trusty USB wireless network adapter, but $70 and a new adapter later, Vista was happy and so was I.&lt;/P&gt;
&lt;P&gt;The smiles didn’t last long. My wife fired up IE 7 on her new computer and went to our high school’s parent portal to check my son’s math grade. IE, however, wouldn’t let her get past the login page; it kept insisting “Internet Explorer cannot display the webpage.” She asked if this was another Vista problem. I knowingly assured her it wasn’t, and informed her that she had been running IE 7 on XP for a long time. Just to make sure, I downloaded the latest version of Firefox and went to the parent portal. Much to my surprise, Firefox let me log in and view grades just fine! I spent the next couple of hours toggling settings in IE 7 trying to get past the problem, and a couple of hours after that doing Web searches and analyzing HTTP traffic to find out why IE 7 couldn’t display a page that Firefox had no problem with. (It has something to do with “302 Temporarily Moved” responses coming back over SSL/TLS, but that’s as far as I’ve gotten with it.)&lt;/P&gt;
&lt;P&gt;My wife can still check our son’s grades with IE 7 on her old XP PC. She can check grades with Firefox on her new Vista quad-core. But she can’t use IE 7 to check grades on Vista. She’s confused, and so am I.&lt;/P&gt;&lt;img src="http://www.wintellect.com/cs/aggbug.aspx?PostID=6165" width="1" height="1"&gt;</description></item><item><title>Vista SP1 for my 64-bit OS has fallen and it can’t get up!</title><link>http://www.wintellect.com/cs/blogs/pmehner/archive/2008/04/29/vista-sp1-for-my-64-bit-os-has-fallen-and-it-can-t-get-up.aspx</link><pubDate>Tue, 29 Apr 2008 05:15:00 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:6094</guid><dc:creator>pmehner</dc:creator><slash:comments>2</slash:comments><description>&lt;P class=MsoNormal style="MARGIN:0in 0in 10pt;"&gt;&lt;FONT face=Calibri size=3&gt;Vista SP1 for the 64-bit version of the OS has fallen on my computer, and it can’t get up! I’ve been without my primary computer now for several days due to the release of SP1 for Vista. The symptom is an infinite loop of installations and failures&amp;nbsp;of SP1 (the specific details seem to vary by people reporting to be afflicted with this problem).&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 10pt;"&gt;&lt;FONT face=Calibri size=3&gt;Nick White at Microsoft declares that the problem “&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;I style="mso-bidi-font-style:normal;"&gt;affects a small number of customers in unique circumstances&lt;/I&gt;&lt;/B&gt;” on the Windows Vista blog here:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 10pt;"&gt;&lt;A href="http://windowsvistablog.com/blogs/windowsvista/archive/2008/02/19/update-on-windows-vista-sp1-prerequisite-kb937287.aspx"&gt;&lt;FONT face=Calibri size=3&gt;http://windowsvistablog.com/blogs/windowsvista/archive/2008/02/19/update-on-windows-vista-sp1-prerequisite-kb937287.aspx&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 10pt;"&gt;&lt;FONT face=Calibri size=3&gt;but Google turns up nearly 36,000 hits for the pretty specific phrase of “&lt;B style="mso-bidi-font-weight:normal;"&gt;&lt;I style="mso-bidi-font-style:normal;"&gt;configuring updates: stage 3 of 3 vista ultimate 64 sp1&lt;/I&gt;&lt;/B&gt;”; so I have to believe there are a few more customers being negatively impacted by this than just moi.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 10pt;"&gt;&lt;FONT face=Calibri size=3&gt;This blog was helpful in resolving the infinite patch installation loop in case you happen to get caught by this nasty thing:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 10pt;"&gt;&lt;A href="http://forums.microsoft.com/technet/showpost.aspx?postid=2873378&amp;amp;isthread=false&amp;amp;siteid=17&amp;amp;authhash=7f2056e7cf93af49d9d8704602bc97be8b4c437b&amp;amp;ticks=633390464558901682&amp;amp;sb=0&amp;amp;d=1&amp;amp;at=7&amp;amp;ft=11&amp;amp;tf=0&amp;amp;pageid=5"&gt;&lt;FONT face=Calibri size=3&gt;http://forums.microsoft.com/technet/showpost.aspx?postid=2873378&amp;amp;isthread=false&amp;amp;siteid=17&amp;amp;authhash=7f2056e7cf93af49d9d8704602bc97be8b4c437b&amp;amp;ticks=633390464558901682&amp;amp;sb=0&amp;amp;d=1&amp;amp;at=7&amp;amp;ft=11&amp;amp;tf=0&amp;amp;pageid=5&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 10pt;"&gt;&lt;FONT face=Calibri size=3&gt;It doesn’t “solve” the problem, but it will at least make your computer useable again for awhile so that you can backup your important files, etc.&amp;nbsp;In my case whenever I install a new IIS feature, the pattern of installing/failing SP1 starts all over as soon as I reboot my machine. Everything having to do with&amp;nbsp;attempting to resolve this problem seems to take hours of time (SP1 itself takes nearly an hour to install and then another hour after it aborts to rewind itself). KB937287 has been installed on my machine 5 times now! After SP1 fails in its installation, KB937287 shows back up again in Windows Update. KB937287 is apparently a pre-requisite patch to prepare your computer for the slaughter that is SP1.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 10pt;"&gt;&lt;FONT face=Calibri size=3&gt;I spent nearly two hours on an IM with Microsoft tech support this evening where they took remote control of my computer and declared that the problem was with my Norton 360 antivirus interfering with the service pack installation (even though my anti-virus had already been disabled per the SP instructions). They asked me to remove my anti-virus and re-install SP1 again and then scheduled me for a call back tomorrow. Unfortunately the results were an unsuprising&amp;nbsp;repeat of the “configuring updates: state 3 of 3“ hell that was my weekend (it’s like groundhogs day all over again)!&amp;nbsp;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;At this point &lt;/SPAN&gt;I’m thinking I would be better off simply burning my computer to the ground and reinstalling the OS without the automatic patch feature disabled until MS can get this sorted out. In point of fact, this is exactly what many customers seem to be blogging that they did. It may only be affecting a small number of customers, but&amp;nbsp;the impact to those minority customers seems severe.&lt;/FONT&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;&lt;img src="http://www.wintellect.com/cs/aggbug.aspx?PostID=6094" width="1" height="1"&gt;</description><category domain="http://www.wintellect.com/cs/blogs/pmehner/archive/tags/VISTA+64+SP1/default.aspx">VISTA 64 SP1</category></item><item><title>Instrumentation, Your App, and You - Part II: Eventing</title><link>http://www.wintellect.com/cs/blogs/ahopper/archive/2008/04/28/instrumentation-your-app-and-you-part-ii-eventing.aspx</link><pubDate>Tue, 29 Apr 2008 00:19:00 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:6091</guid><dc:creator>ahopper</dc:creator><slash:comments>2</slash:comments><description>&lt;P&gt;This is a continuation of my inaugural blog series on instrumentation (see part one &lt;A class="" title="Part One" href="http://www.wintellect.com/cs/blogs/ahopper/archive/2008/04/28/instrumentation.aspx"&gt;here&lt;/A&gt;).&lt;/P&gt;
&lt;P&gt;Eventing is one of those features&amp;nbsp;in the .NET Framework that is incredibly useful, especially if you are an Enterprise or Internet-facing application&amp;nbsp;developer. Proper eventing instrumentation can make the difference between an operable application and something your IT guys would&amp;nbsp;never allow in the datacenter. Unfortunately, it is also really easy to abuse.&lt;/P&gt;
&lt;P&gt;OK, this is where I&amp;nbsp;don my Pedantic Instrumentation Guy hat. Yes, I'm going to be an annoying PIG that asks you to do a bit of work in order to have good instrumentation so you don't have to pay some ex-green-beret a lot of money to wade through mini-dumps. (Not that we mind the income, mind you!)&lt;/P&gt;
&lt;P&gt;All too often, developers will use the event log as a poor man's trace log - they'll dump informational messages into the Application log or, worse yet, perform full stack dumps into the log when an exception is caught. In addition, it's just too easy to configure programmatically, which can set you up for embarrasing crashes.&lt;/P&gt;
&lt;P&gt;You see, the event log was not intended to act as a log file; instead, it is intended to be a place where you can go to see a comprehensive view of important things happening on your system. There are two magic words in there I want to emphasize: comprehensive and&amp;nbsp;important. You must understand that you are not the only application writing to the event&amp;nbsp;log. In fact, there's a phenomenon known as an "event storm" where a poorly written application can flood a computer's event log with so much useless or redundant data that other things that are really useful to see like warnings from SQL or disk I/O errors get missed. This logically brings us to event importance. You really should only be logging significant events. Things like startup, shutdown, catastrophic failures but most importantly, &lt;U&gt;recoverable&lt;/U&gt; errors.&lt;/P&gt;
&lt;P&gt;Ahhh, recoverable errors. PIG hat still on? Ah, good. This topic could (and probably will) merit a whole series of posts&amp;nbsp;dedicated to knowing/learning&amp;nbsp;how your applications&amp;nbsp;may fail.&amp;nbsp;Here's a Golden Rule of eventing: Do not log an error if all your poor sysadmin can do is see that the application has logged an error. Trust me; he's not going to appreciate the event message for its innate beauty. If there is no possible recovery action documented for a particular error event ID (or even better, included in the event's message), then all your app is doing is indicating to the sysadmin that he should seriously consider uninstalling your application. Consider this: you see the following error event:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Log Name:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Application&lt;BR&gt;Source:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyApplication&lt;BR&gt;Date:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5/8/2008 7:00:00 AM&lt;BR&gt;Event ID:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&lt;BR&gt;Task Category: (0)&lt;BR&gt;Level:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Error&lt;BR&gt;Keywords:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;User:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; N/A&lt;BR&gt;Computer:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; datacenter1&lt;BR&gt;Description:&lt;BR&gt;Object not set to an instance of an object.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Did this tell you anything about how you can prevent this error in the future? If not, why is it in the event log? If it doesn't provide me with a way to help my system be happy again, it's just noise. The best I can do is to attach a debugger and snap a minidump when I hit a NullReferenceException, and this is not something to consider lightly when you've got an Internet-facing application (Or tight purse-strings. Do you know how much it costs to hire ex-green-berets these days?).&lt;/P&gt;
&lt;P&gt;No, a much better error event would be:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Log Name:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Application&lt;BR&gt;Source:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MyApplication&lt;BR&gt;Date:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5/8/2008 7:00:00 AM&lt;BR&gt;Event ID:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1033&lt;BR&gt;Task Category: (3)&lt;BR&gt;Level:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Error&lt;BR&gt;Keywords:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;User:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; N/A&lt;BR&gt;Computer:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; datacenter1&lt;BR&gt;Description:&lt;BR&gt;Unable to retrieve customer information from the database. Please verify that the 'customer' database at server 'database2' is accessible.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;So, what's the difference here? Well, there's the obvious difference and the hidden one. The obvious difference is that the event gives you a pretty good indication of what's going on. In addition, it gave you some things to go check to help your app get back on its feet: is the database server up and running? If so, is the database available? The hidden difference is that the developer anticipated that he may not get a valid object from the call to retrieve an object from the server and wrote error-handling code to capture the information needed to troubleshoot the problem and to write the above entry. I'm not going to lie and say that it's easy to write code that anticipates failure. It's actually pretty hard to know all of the ways in which some component can fail, especially if you didn't write it yourself. Some of this will come from experience and testing, and there are also static analysis tools that can analyze your code's call stacks for exceptions that aren't handled but if you're really lucky, the developers who wrote the component will have included things like &amp;lt;exception&amp;gt; information in their XML documentation. With all of the above and some grunt-work on the developers' part, you should be able to tell your sysadmin what is wrong with your app. So what if you encounter a truly exceptional exception? Well, that falls under the category of catastrophic failure. For obvious reasons, it's your responsibility to try to minimize the scenarios where one of these can occur, but if it were to happen this is where all of the helpful advice I provided in the tracing article (you DID read that, right?) comes in.&lt;/P&gt;
&lt;P&gt;Oh, one other thing you may notice in my "new and improved" log message is that there was an event ID. This is also a pretty important concept: once you've spent the time to analyze the manner in which your application can fail, try to assign event IDs to the cause of failures you are logging. For example:&amp;nbsp;an inability to connect to the database server is 1033,&amp;nbsp;an access denied to a configuration file may be 2021, and so on.&amp;nbsp;If you do your homework here you can not only make it easier for a human being to find and correct the issue preventing your application from functioning but you can facilitate the development of auto-recovery actions in monitoring packages like &lt;A class="" title="System Center Operations Manager" href="http://www.microsoft.com/systemcenter/opsmgr/default.mspx"&gt;System Center Operations Manager&lt;/A&gt;. Spending the time to itemize your event messages also allows you to leverage the string formatting and localization capabilities of the Message Compiler (mc.exe) utility. I'll dedicate a separate post to how one can use MC.exe to generate message files and how you can register and use event sources that use message files.&lt;/P&gt;
&lt;P&gt;Finally, let's talk about event source registration. Again, this is one of those areas where things were made a wee bit too easy. A pattern you see too often in managed code is:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;if (!EventLog.SourceExists("Foo"))&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; EventLog.CreateEventSource("Foo", "Application");&lt;BR&gt;}&lt;BR&gt;EventLog.WriteEntry("Foo", "Some event", EventLogEntryType.Information);&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;In fact, I was apalled to discover this code in a Microsoft certification exam! You should never ship code like the above for a couple of reasons, but the most obvious one is that it requires elevated permissions to create an event source. If an unprivileged user account attempts to run the above you will get a SecurityException. Instead, have your installation package leverage Windows Installer's support for registering event message files and use the WriteEvent overload instead - that way, you can create an EventInstance object that contains the event message ID and supply format strings that get plugged into the appropriate place in the message.&lt;/P&gt;
&lt;P&gt;Well, there you have it. A whirlwind tour of the philosophy behind proper* event logging in your application.&lt;/P&gt;
&lt;P&gt;Whew. Now I can take this stupid thing off.&lt;/P&gt;
&lt;P&gt;* "Proper" is in the eye of the beholder. Feel free to ignore any and all of my advice. Tax, tag and title not included in the advertised sale price.&lt;/P&gt;&lt;img src="http://www.wintellect.com/cs/aggbug.aspx?PostID=6091" width="1" height="1"&gt;</description><category domain="http://www.wintellect.com/cs/blogs/ahopper/archive/tags/Instrumentation/default.aspx">Instrumentation</category><category domain="http://www.wintellect.com/cs/blogs/ahopper/archive/tags/.NET/default.aspx">.NET</category></item><item><title>Instrumentation, Your App, and You - Part I: Tracing</title><link>http://www.wintellect.com/cs/blogs/ahopper/archive/2008/04/28/instrumentation.aspx</link><pubDate>Mon, 28 Apr 2008 23:38:00 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:6090</guid><dc:creator>ahopper</dc:creator><slash:comments>1</slash:comments><description>&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face=Calibri size=3&gt;It's been a while since I've blogged about anything technical, and since I'm here in my new home at&amp;nbsp;&lt;A class="" title=Wintellect href="http://www.wintellect.com/" target=_blank&gt;Wintellect&lt;/A&gt;&amp;nbsp;I decided that I need to begin anew. So, without further ado...&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face=Calibri size=3&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face=Calibri size=3&gt;I wish I could find a way to make instrumentation sexy; every time I try to explain to someone about why they should invest in instrumentation, I see them get the “deer in the headlights” look and try to find a way to get away from this crazy bald man. It’s just so BORING… and invaluable.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face=Calibri size=3&gt;Basically, my philosophy is that attaching a debugger is well and good, but there are only a few scenarios where that’s going to be possible or acceptable. With Enterprise-facing Web or LOB applications, you have a lot of leeway – they can afford to have you (or one of their technical resources) go to a machine and attach &lt;A class="" href="http://www.microsoft.com/whdc/devtools/debugging/default.mspx" target=_blank&gt;WinDBG or CDB&lt;/A&gt; – but I hold Internet-facing sites and client-side code to a much higher bar. With a live Internet-facing site, you can’t just hit a breakpoint and dig around as it brings the app to a screeching halt. Even scripting a breakpoint that snaps a minidump and resumes is no good as it still blocks the app for an indeterminate (although admittedly pretty short) amount of time. With a client-side application, you simply cannot ask a customer to install a debugger and get that minidump to you.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face=Calibri size=3&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face=Calibri size=3&gt;So, how can you instrument your application? Well, there are three primary ways and one interesting way. You can use trace logging (which will be the core focus of this post), event logging, performance counters, and finally, WMI.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face=Calibri size=3&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face=Calibri size=3&gt;There are plenty of times where that hard-won minidump simply isn’t enough; after all, not only is it rocket science to most developers, but all you’ll see stack traces and current values for members – not HOW you got to this point. A lot of the art debugging is intuiting what path the app took to get to this crashing stack, and a good trace log can let the app do a lot of that detective work for you. Even minimal stack tracing (entry/exit) gives you a great deal of behavioral information, and this can be invaluable when you’re trying to figure out WHY you’re waiting on that Mutex again. &lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face=Calibri size=3&gt;Tracing undeniably has a non-zero overhead associated with it, and this overhead takes two forms. First, there’s the behavioral/code overhead that goes with getting people in the mindset of leaving post-it notes in their code for the unfortunate soul who has to troubleshoot their misbehaving app. Second, there’s the performance overhead that goes along with adding more calls to the application. The first is manageable, and the second is fixable.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face=Calibri size=3&gt;On the behavioral front, it’s very much an evangelism issue and it’s kinda like selling insurance for your career. Once you have an app out in the field with zero instrumentation and some high-profile customer is screaming for your head because you STILL don’t know why your app is hitting this exception, you gain a deep appreciation for how much you would have loved to know what the response from that SOAP call was. As for the amount of work it requires from the developer, it all depends upon the class of application; there’s a dial you’ll want to turn for the amount of tracing code you write. When I’m wearing my hard hat I want tracing at every decision block, every exception handler to dump the exception and logging the parameters to methods at “verbose” levels. When I’m wearing my “warm fuzzy” hat for simple LOB applications, I want tracing before and after major events in the code like network/IO calls. But in practice, it’s going to be up to the dev to understand how their code might misbehave and to leave a trail of tracing breadcrumbs to help some poor soul noodle out why some button didn’t get enabled.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;FONT face=Calibri size=3&gt;Now on to the performance overhead. Most developers don’t stop to think about the cost associated with constructing the call stack for a trace call, and when they see that their application’s runtime performance suffers because they have a bazillion trace calls that call ToString or box up a bunch of integers, they’re quick to blame tracing in general and yank it altogether (seen it happen first-hand, that). There’s no reason it has to be this expensive, though. If tracing isn’t enabled, it should just get out of the way – it’s only when we’re debugging that we want that overhead, and then we won’t care as much if we take a hit. It’s an unfortunate reality that all of the wonderful work the driver guys did on &lt;A class="" href="http://msdn2.microsoft.com/en-us/library/ms793176.aspx" target=_blank&gt;TraceWPP&lt;/A&gt; is lost in the managed world; there’s no (publicly available, that is) tool for preprocessing managed code and wrapping trace calls with runtime-evaluated conditionals to shortcut the construction of the call stack if tracing is not enabled.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;So, if we can't use TraceWPP, what can we do, then? Well, for the time being (hint, hint), we're stuck with hand-generating conditional blocks to detect whether tracing is enabled for a particular trace level. However, I hope to remedy that situation here in this blog: we'll walk through the implementation of a preprocessor in the style of TraceWPP and use it for our managed apps.&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&lt;/FONT&gt;&lt;/o:p&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;Well, this post has become long enough for now. We'll take a look at the other ways your application can help you debug itself later.&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://www.wintellect.com/cs/aggbug.aspx?PostID=6090" width="1" height="1"&gt;</description><category domain="http://www.wintellect.com/cs/blogs/ahopper/archive/tags/Instrumentation/default.aspx">Instrumentation</category><category domain="http://www.wintellect.com/cs/blogs/ahopper/archive/tags/.NET/default.aspx">.NET</category></item><item><title>Vista x64 is Now Officially Supported on Mac Hardware!</title><link>http://www.wintellect.com/cs/blogs/jrobbins/archive/2008/04/25/vista-x64-is-now-officially-supported-on-mac-hardware.aspx</link><pubDate>Fri, 25 Apr 2008 16:31:47 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:6043</guid><dc:creator>jrobbins</dc:creator><slash:comments>2</slash:comments><description>&lt;p&gt;You all know my &lt;a href="http://www.wintellect.com/cs/blogs/jrobbins/archive/2008/03/18/installing-windows-server-2003-r2-x64-on-a-mac-pro.aspx"&gt;geek&lt;/a&gt;
		&lt;a href="http://www.wintellect.com/cs/blogs/jrobbins/archive/2007/02/15/vista-x64-on-a-mac-pro-totally-awesome-dude.aspx"&gt;love&lt;/a&gt; for Apple hardware. Yesterday Apple &lt;a href="http://www.apple.com/support/downloads/bootcampupdate21forwindowsvista64.html"&gt;released&lt;/a&gt; the official drivers for Vista x64 support! You'll need to download and install Boot Camp Update 2.1 and you'll be set. Totally and completely excellent news!&lt;/p&gt;&lt;img src="http://www.wintellect.com/cs/aggbug.aspx?PostID=6043" width="1" height="1"&gt;</description></item><item><title>Easily Downloading and Installing the Sysinternals Suite</title><link>http://www.wintellect.com/cs/blogs/jrobbins/archive/2008/04/20/easily-downloading-and-installing-the-sysinternals-suite.aspx</link><pubDate>Sun, 20 Apr 2008 23:18:00 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:5980</guid><dc:creator>jrobbins</dc:creator><slash:comments>4</slash:comments><description>&lt;P&gt;Everyone uses Mark Russinovich's and Bryce Cogswell's excellent &lt;A href="http://technet.microsoft.com/en-us/sysinternals/default.aspx"&gt;Sysinternals&lt;/A&gt; Tools. Tools like Process Explorer and Process Monitor have helped solve some of the toughest bugs I've ever worked on. I've been surprised how many people didn't know that all the tools available in a single download: the &lt;A href="http://technet.microsoft.com/en-us/sysinternals/bb842062.aspx"&gt;Sysinternals Suite&lt;/A&gt;. &lt;/P&gt;
&lt;P&gt;Whenever I see that one of the tools is updated, I find it easiest to grab the Suite .ZIP file and unzip it to my utility directory. After having done the manual updating a couple of times, I wrote a PowerShell script to do the download and unzipping automatically. I thought others might find it useful. Note that you'll need the excellent and free &lt;A href="http://www.7-zip.org/"&gt;7z&lt;/A&gt; archive tool in your path. &lt;/P&gt;
&lt;P&gt;As I'm still a PowerShell &lt;A href="http://www.wintellect.com/cs/blogs/jrobbins/archive/2008/02/17/eight-weeks-of-powershell.aspx"&gt;novice&lt;/A&gt;, please don't be afraid to point out anything I can do better. &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;################################################################## &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;# Get-SysInternalsSuite.ps1 - John Robbins - john@wintellect.com&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;# &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;# Note that this script requires the excellent 7Z.EXE in the &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;# PATH environment variable. You can get 7Z.EXE, which is free, &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;# at &lt;A href="http://www.7-zip.org/"&gt;http://www.7-zip.org/&lt;/A&gt;. &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;################################################################# &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:blue;"&gt;param&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; ( [&lt;/SPAN&gt;&lt;SPAN style="COLOR:teal;"&gt;string&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;] &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$Extract&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; , &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:black;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;/SPAN&gt;&lt;SPAN style="COLOR:teal;"&gt;string&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;] &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$Save&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; ) &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:black;"&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;# Always make sure all variables are defined. &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:cadetblue;"&gt;&lt;STRONG&gt;Set-PSDebug&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:cadetblue;"&gt;&lt;EM&gt;-Strict&lt;/EM&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:blue;"&gt;function&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; Usage &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Courier New;"&gt;{ &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:maroon;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ""&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:maroon;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Downloads and extracts all the tools from Sysinternals"&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:maroon;"&gt;""&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:maroon;"&gt;"Usage: Get-SysInternalsSuite -extract &amp;lt;directory&amp;gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:maroon;"&gt;"&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [-save &amp;lt;directory&amp;gt;]"&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;&amp;nbsp;&lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:maroon;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;"Required Parameter :"&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:maroon;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; " -extract &amp;lt;directory&amp;gt; : The directory where the SysinternalsSuite.zip"&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:maroon;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tools are extracted."&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:maroon;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Optional Parameters :"&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:maroon;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; " -save &amp;lt;directory&amp;gt; : Saves SysinternalsSuite.zip to the specified"&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:maroon;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; directory. If not specified, the .ZIP file "&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:maroon;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; "&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; is not saved."&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:maroon;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; " -? : Display this usage information"&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:maroon;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ""&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:maroon;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ""&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; exit&amp;nbsp;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Courier New;"&gt;} &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:blue;"&gt;function&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; CreateDirectoryIfNeeded ( [&lt;/SPAN&gt;&lt;SPAN style="COLOR:teal;"&gt;string&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;] &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$directory&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; ) &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Courier New;"&gt;{ &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; ( &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;!&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; ( &lt;/SPAN&gt;&lt;SPAN style="COLOR:cadetblue;"&gt;&lt;STRONG&gt;Test-Path&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$directory&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; -type &lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;"Container"&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; ) )&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Courier New;"&gt;{&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:cadetblue;"&gt;&lt;STRONG&gt;New-Item&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; -type directory &lt;/SPAN&gt;&lt;SPAN style="COLOR:cadetblue;"&gt;&lt;EM&gt;-Path&lt;/EM&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$directory&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &amp;gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$null&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Courier New;"&gt;} &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;################################################################## &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;# Main execution starts here. &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;&lt;BR&gt;# Check for the help request. &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:blue;"&gt;if&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; ( ( &lt;/SPAN&gt;&lt;SPAN style="COLOR:navy;"&gt;$Args&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;-eq&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;'-?'&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;) &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;-or&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; ( &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;!&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$Extract&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; ) ) &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Courier New;"&gt;{&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Courier New;"&gt;Usage &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Courier New;"&gt;}&amp;nbsp;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:purple;"&gt;&lt;BR&gt;$paramLog&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;@" &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:Courier New;"&gt;Param Extract&amp;nbsp;&amp;nbsp; = $Extract &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:Courier New;"&gt;Param Save&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = $Save &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:maroon;FONT-FAMILY:Courier New;"&gt;"@ &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:cadetblue;"&gt;&lt;STRONG&gt;Write-Debug&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$paramLog&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:black;"&gt;&lt;BR&gt;[&lt;/SPAN&gt;&lt;SPAN style="COLOR:teal;"&gt;string&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;]&lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$sevenZName&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;"7Z.EXE"&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;# Verify I can find UNZIP.EXE in the path. &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:black;"&gt;[&lt;/SPAN&gt;&lt;SPAN style="COLOR:teal;"&gt;string&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;]&lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$sevenZPath&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; $(&lt;/SPAN&gt;&lt;SPAN style="COLOR:cadetblue;"&gt;&lt;STRONG&gt;Get-Command&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$sevenZName&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;).Definition &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:blue;"&gt;if&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; ( &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$sevenZPath&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;.Length &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;-eq&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; 0 ) &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Courier New;"&gt;{ &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:cadetblue;"&gt;&lt;STRONG&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Write-Error&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;"Unable to find $sevenZName in the path."&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Courier New;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; exit &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Courier New;"&gt;} &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;&lt;BR&gt;# If the extract directory does not exist, create it. &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:black;"&gt;CreateDirectoryIfNeeded ( &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$Extract&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; ) &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;# If there's a save directory set, us that otherwise, use the %TEMP% directory. &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:black;"&gt;[&lt;/SPAN&gt;&lt;SPAN style="COLOR:teal;"&gt;Boolean&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;]&lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$deleteZipFile&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;$TRUE&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:black;"&gt;[&lt;/SPAN&gt;&lt;SPAN style="COLOR:teal;"&gt;String&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;]&lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$downloadFile&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;""&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:blue;"&gt;if&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; ( &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$Save&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;.Length &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;-gt&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; 0 ) &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Courier New;"&gt;{&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:black;"&gt;CreateDirectoryIfNeeded ( &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$Save&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; ) &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:purple;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $downloadFile&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$Save&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:purple;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $deleteZipFile&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;$FALSE&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Courier New;"&gt;} &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:blue;"&gt;else&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Courier New;"&gt;{&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:green;"&gt;# Use the %TEMP% path for the user. &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:purple;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $downloadFile&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$env:temp&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Courier New;"&gt;} &lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;# Build up the full location and filename. &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:purple;"&gt;$downloadFile&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; $(&lt;/SPAN&gt;&lt;SPAN style="COLOR:cadetblue;"&gt;&lt;STRONG&gt;Get-item&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$downloadFile&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;).FullName &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:purple;"&gt;$downloadFile&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:cadetblue;"&gt;&lt;STRONG&gt;Join-Path&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:cadetblue;"&gt;&lt;EM&gt;-path&lt;/EM&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$downloadFile&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:cadetblue;"&gt;&lt;EM&gt;-childpath&lt;/EM&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;"SysinternalsSuite.zip"&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;&amp;nbsp;&lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;&amp;nbsp;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;# Let the download begin! &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:cadetblue;"&gt;&lt;STRONG&gt;Write-Output&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;"Starting download of the Sysinternals Suite"&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:purple;"&gt;$webClient&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:cadetblue;"&gt;&lt;STRONG&gt;New-Object&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; System.Net.WebClient &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:purple;"&gt;$webClient&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;.DownloadFile(&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;"http://download.sysinternals.com/Files/SysinternalsSuite.zip"&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; , &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:purple;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $downloadFile&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;) &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:cadetblue;"&gt;&lt;STRONG&gt;Write-Output&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;"Sysinternals suite downloaded to $downloadFile"&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;&lt;BR&gt;# I don't like to see all the output from 7z unless there's a problem so I'll &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;# redirect to a temporary file and if there's any problems, I'll show it. &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:purple;"&gt;$temp7zOutput&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; [&lt;/SPAN&gt;&lt;SPAN style="COLOR:teal;"&gt;System.IO.Path&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;]::&lt;/SPAN&gt;&lt;SPAN style="COLOR:saddlebrown;"&gt;GetTempFileName&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;()&amp;nbsp;&lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;&lt;BR&gt;# Since the -o option to 7Z.EXE cannot have a space between it and the &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;# directory there's a bit of a problem. PowerShell does not expand the &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;# line -o$Extract if passed directly on the command line. &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:purple;"&gt;$outputOption&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;"-o$Extract"&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:cadetblue;"&gt;&lt;STRONG&gt;Write-Output&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;"Extracting files into $Extract"&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:black;"&gt;&amp;amp;&lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$sevenZPath&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; x -y &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$outputOption&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$downloadFile&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &amp;gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$temp7zOutput&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:blue;"&gt;if&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; ( &lt;/SPAN&gt;&lt;SPAN style="COLOR:navy;"&gt;$LASTEXITCODE&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;-ne&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; 0 ) &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Courier New;"&gt;{&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:green;"&gt;# There was a problem extracting.&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:cadetblue;"&gt;&lt;STRONG&gt;Get-Content&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$temp7zOutput&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:green;"&gt;# Don't delete the download file.&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:purple;"&gt;$deleteZipFile&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;$FALSE&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:cadetblue;"&gt;&lt;STRONG&gt;Write-Error&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;"Error extracting the .ZIP file"&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:cadetblue;"&gt;&lt;STRONG&gt;Write-Error&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;"The downloaded .ZIP file is at $downloadFile and will not be deleted."&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Courier New;"&gt;} &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;# Delete the file that held the extraction output. &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:cadetblue;"&gt;&lt;STRONG&gt;del&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$temp7zOutput&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:green;FONT-FAMILY:Courier New;"&gt;# Delete the downloaded .ZIP file if I'm supposed to. &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:blue;"&gt;if&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; ( &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$deleteZipFile&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;-eq&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;$TRUE&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; ) &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Courier New;"&gt;{ &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:Courier New;"&gt;&lt;SPAN style="COLOR:cadetblue;"&gt;&lt;STRONG&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Remove-Item&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR:purple;"&gt;$downloadFile&lt;/SPAN&gt;&lt;SPAN style="COLOR:black;"&gt; &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Courier New;"&gt;} &lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://www.wintellect.com/cs/aggbug.aspx?PostID=5980" width="1" height="1"&gt;</description></item><item><title>Paraffin 1.03 – Couple of Bug Fixes</title><link>http://www.wintellect.com/cs/blogs/jrobbins/archive/2008/04/19/paraffin-1-03-couple-of-bug-fixes.aspx</link><pubDate>Sat, 19 Apr 2008 23:19:08 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:5971</guid><dc:creator>jrobbins</dc:creator><slash:comments>5</slash:comments><description>&lt;p&gt;Last year I released a tool to help make maintaining WiX 2.0-based installations easier called &lt;a href="http://www.wintellect.com/cs/blogs/jrobbins/archive/2007/10/21/wix-a-better-tallow-paraffin.aspx"&gt;Paraffin&lt;/a&gt;. I've fixed the following two issues:
&lt;/p&gt;&lt;ol&gt;&lt;li&gt;I was relying on the short name of the file when generating an updated .PARAFFIN file. Sadly, it looks like the short file names are essentially random. I now only rely on the File element, Source attribute when looking for existing files.
&lt;/li&gt;&lt;li&gt;I had swapped INSTALLDIR and TARGETDIR when generating the fragment.
&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Hope you find it useful! Get the latest source code &lt;a href="http://www.wintellect.com/cs/files/folders/4332/download.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://www.wintellect.com/cs/aggbug.aspx?PostID=5971" width="1" height="1"&gt;</description></item><item><title>Finding an Object’s GC Generation in the Visual Studio Debugger</title><link>http://www.wintellect.com/cs/blogs/jrobbins/archive/2008/04/18/finding-an-object-s-gc-generation-in-the-visual-studio-debugger.aspx</link><pubDate>Fri, 18 Apr 2008 19:05:16 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:5967</guid><dc:creator>jrobbins</dc:creator><slash:comments>1</slash:comments><description>&lt;p&gt;As a .NET developer, your top three concerns are 1) Memory, 2) Memory, and the last one is the toughest, 3) Memory. While .NET takes away the pain of manual memory management if you aren't constantly worrying about what's in your Gen 2 heap, you're going to suffer with bad performance or worse, unexplained OutOfMemoryExceptions. The garbage collection system in .NET is fantastic, but when you trigger a garbage collection, &lt;em&gt;none of your code is executing&lt;/em&gt;. That's why it's so important to have that feel for which of your objects are sitting in which generation.
&lt;/p&gt;&lt;p&gt;While you can use &lt;a href="http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx"&gt;WinDBG&lt;/a&gt; and Steve Johnson's excellent &lt;a href="http://www.wintellect.com/cs/blogs/jrobbins/archive/2007/06/18/great-sosex-a-phenomenal-net-debugging-extension-to-see-the-hard-stuff-steve-johnson-is-my-hero.aspx"&gt;SOSEX&lt;/a&gt; extension to look up your objects, it's a bit painful. My ultimate dream would be that the CLR team would expose a heap walking functionality in the debugging API so this was a natural part of the Visual Studio debugger. While that may happen in a future version, I wanted to show you a way you can get this today. While I'll show this with Visual Studio 2008, everything should work exactly the same in Visual Studio 2005.
&lt;/p&gt;&lt;p&gt;Finding an object's generation in your code is easy with the &lt;a href="http://msdn2.microsoft.com/en-us/library/h28z0ez9.aspx"&gt;GC.GetGeneration&lt;/a&gt; function. Just pass the object as a parameter and the return value will be 0, 1, or 2. Since the debugger has supported calling functions from the debugger Watch window forever, there's nothing stopping you from calling GC.GetGeneration on your own. In fact, the debugger &lt;em&gt;wants&lt;/em&gt; you call functions from the Watch window so they provide Intellisense and tool tip support to make it easy.
&lt;/p&gt;&lt;p&gt;&lt;img src="http://www.wintellect.com/cs/blogs/jrobbins/041808_1908_FindinganOb1.png" alt="" /&gt;
	&lt;/p&gt;&lt;p&gt;If I wanted to find out what generation the sb variable is in, just pass it as the parameter.
&lt;/p&gt;&lt;p&gt;&lt;img src="http://www.wintellect.com/cs/blogs/jrobbins/041808_1908_FindinganOb2.png" alt="" /&gt;
	&lt;/p&gt;&lt;p&gt;If the object you want to look at is in scope, calling GC.GetGeneration on it works great. The bigger question is how can you look at those objects that are not in scope? That's probably the case that you're most interested in seeing. Fortunately, there's a barely &lt;a href="http://msdn2.microsoft.com/en-us/library/ms164903.aspx"&gt;mentioned&lt;/a&gt; technique you can use to observe your interesting objects: Make Object ID.
&lt;/p&gt;&lt;p&gt;In any debugger window where the expression evaluator is used, such as the Watch, Me/This, Locals, Quick Watch, and Data Tips, you can right click on the variable to bring up the context menu where you can access the Make Object ID command.
&lt;/p&gt;&lt;p&gt;&lt;img src="http://www.wintellect.com/cs/blogs/jrobbins/041808_1908_FindinganOb3.png" alt="" /&gt;
	&lt;/p&gt;&lt;p&gt;After selecting Make Object ID, you'll see that in the Value column or Data Tip display, there will be a decimal integer followed by the number (#) sign. That's the ID applied to that object. Note that Make Object ID will not add a reference to the object inside the debuggee. Think of Make Object ID as watching the object, but not referencing it.
&lt;/p&gt;&lt;p&gt;In the screen shot below, I created an Object ID for the XmlDocument variable doc. That added the &lt;span style="font-family:Courier New;"&gt;{1#}&lt;/span&gt; in the value column after the type. What's nice is that the Object ID can be viewed directly. In the second row, I typed in &lt;span style="font-family:Courier New;"&gt;1#&lt;/span&gt; so I could continue to observe that XmlDocument no matter where I stop later in the debugger. The important point of Make Object ID is that you can observe objects even when they are not in scope!
&lt;/p&gt;&lt;p&gt;&lt;img src="http://www.wintellect.com/cs/blogs/jrobbins/041808_1908_FindinganOb4.png" alt="" /&gt;
	&lt;/p&gt;&lt;p&gt;You might be wondering what happens if you add an Object ID to a second object in your program. What happens is that the second Object ID will be 2#, the third 3# and so on. If you want to observe thirty or forty objects, you'll need to put everything down in a table so you can keep them straight. I would love to see the ability to provide your own names to Object IDs in a future version of the debugger.
&lt;/p&gt;&lt;p&gt;What I especially like about making an Object ID is that if the object you're watching is garbage collected, you'll see the that when you stop in the debugger. You may need to click the green recycle icon on the right hand side of the Value column if the line is grayed out when you stop.
&lt;/p&gt;&lt;p&gt;&lt;img src="http://www.wintellect.com/cs/blogs/jrobbins/041808_1908_FindinganOb5.png" alt="" /&gt;
	&lt;/p&gt;&lt;p&gt;While Make Object ID lets you observe objects outside of the current scope and see if its garbage collected, how does that help with determining the generation? The good news is that it helps tremendously as the expression evaluator in Visual Studio seems to know about the Object ID values and can parse them. 
&lt;/p&gt;&lt;p&gt;The documentation does not explicitly state that using the Object ID in different types of expressions is supported but in the discussion of Make Object ID, it says that you can use Make Object ID to set per instance breakpoints. Unlike native code, you don't have any object addresses while debugging in .NET. In native code, you'd set a per instance breakpoint with a condition of &lt;span style="font-family:Courier New;"&gt;this == 0x1234567&lt;/span&gt;, where 0x1234567 is the address of the instance pointer. For .NET, add an Object ID to the this/Me of the object you want to stop on. In the breakpoint condition, you, if the Object ID is 5#, you'd enter &lt;span style="font-family:Courier New;"&gt;this == 5# &lt;/span&gt;or &lt;span style="font-family:Courier New;"&gt;Me = 5#&lt;/span&gt; for C# or VB, respectively.
&lt;/p&gt;&lt;p&gt;I figured it could not hurt to try passing the Object ID to GC.GetGeneration to see what would happen.
&lt;/p&gt;&lt;p&gt;&lt;img src="http://www.wintellect.com/cs/blogs/jrobbins/041808_1908_FindinganOb6.png" alt="" /&gt;
	&lt;/p&gt;&lt;p&gt;Excellent! The expression evaluator does the correct parsing and you now have a way to watch what generation an object while using Visual Studio even if it's not in scope. While it's still a manual process, it might let you stay in Visual Studio a bit longer before you have to do the deep spelunking with SOSEX. Hopefully future versions of Visual Studio will make it easy to determine our object's generation, but at least you have a tip that works with today's debugger.&lt;/p&gt;&lt;img src="http://www.wintellect.com/cs/aggbug.aspx?PostID=5967" width="1" height="1"&gt;</description></item><item><title>Control Interop, Silverlight-Style</title><link>http://www.wintellect.com/cs/blogs/jprosise/archive/2008/04/12/control-interop-silverlight-style.aspx</link><pubDate>Sat, 12 Apr 2008 04:16:00 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:5850</guid><dc:creator>jprosise</dc:creator><slash:comments>5</slash:comments><description>&lt;P&gt;A number of people have asked me in recent weeks whether two Silverlight 2 controls hosted in the same page can communicate with each other, and if so, how. I tell them they need to build a JavaScript bridge between the controls and then the controls can talk to each other just fine.&lt;/P&gt;
&lt;P&gt;Tonight I built a sample app to demonstrate. Here's what it looks like:&lt;/P&gt;
&lt;P&gt;&lt;IMG title="Control Interop Demo" style="WIDTH:466px;HEIGHT:480px;" height=480 alt="Control Interop Demo" src="http://www.wintellect.com/cs/photos/prosise/images/5848/466x480.aspx" width=466&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You drag the red ball in the upper rectangle and the blue rectangle in the lower rectangle mirrors the red ball's moves. The interesting aspect of this application is that each rectangle represents a different Silverlight control instance. In other words, the page hosts two Silverlight controls, and the red ball lives in one control while the blue ball lives in the other.&lt;/P&gt;
&lt;P&gt;Here are the OBJECT tags used to instantiate two Silverlight controls:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;div&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:red;"&gt;id&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="silverlightControlHost1"&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;object&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:red;"&gt;data&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="data:application/x-silverlight,"&lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="application/x-silverlight-2-b1"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;width&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="400"&lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;height&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="300"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;id&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="SourceControl"&amp;gt;&lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;param&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:red;"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="source"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;value&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="ClientBin/InteropDemo.xap"/&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;param&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:red;"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="onerror"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;value&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="onSilverlightError"&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;/&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;param&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:red;"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="background"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;value&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="white"&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;/&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;object&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;div&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;div&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:red;"&gt;id&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="SilverlightControlHost2"&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;object&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:red;"&gt;data&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="data:application/x-silverlight,"&lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="application/x-silverlight-2-b1"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;width&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="400"&lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;height&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="300"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;id&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="TargetControl"&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;param&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:red;"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="source"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;value&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="ClientBin/OtherControl.xap"/&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;param&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:red;"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="onerror"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;value&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="onSilverlightError"&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;/&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;param&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:red;"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="background"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;value&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="white"&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;/&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;object&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;div&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;
&lt;P&gt;Each control has its own DIV, and each loads a different XAP file. How did I get Visual Studio to build two XAP files, each containing a separate control assembly? I just added a&amp;nbsp;second Silverlight Application project to the solution. If you already have a Web project in the solution, Visual Studio asks if you want the new project linked to the existing Web project:&lt;/P&gt;
&lt;P&gt;&lt;IMG title="Add Project Dialog" style="WIDTH:443px;HEIGHT:375px;" height=375 alt="Add Project Dialog" src="http://www.wintellect.com/cs/photos/prosise/images/5849/443x375.aspx" width=443&gt;&lt;/P&gt;
&lt;P&gt;Visual Studio obligingly adds the Silverlight project to the solution and configures the build settings so that building the project creates a second XAP file that, like the XAP file from the first project, is copied into the Web site's ClientBin directory.&lt;/P&gt;
&lt;P&gt;To link&amp;nbsp;the two Silverlight controls together, I began by converting the code-behind class for the second control (the one containing the blue ball) into a scriptable class and adding a scriptable method named MoveBall:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;[&lt;SPAN style="COLOR:#2b91af;"&gt;ScriptableType&lt;/SPAN&gt;]&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;public&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:blue;"&gt;partial&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;Page&lt;/SPAN&gt; : &lt;SPAN style="COLOR:#2b91af;"&gt;UserControl&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;public&lt;/SPAN&gt; Page()&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;InitializeComponent();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;HtmlPage&lt;/SPAN&gt;.RegisterScriptableObject(&lt;SPAN style="COLOR:#a31515;"&gt;"other"&lt;/SPAN&gt;, &lt;SPAN style="COLOR:blue;"&gt;this&lt;/SPAN&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;[&lt;SPAN style="COLOR:#2b91af;"&gt;ScriptableMember&lt;/SPAN&gt;]&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; MoveBall(&lt;SPAN style="COLOR:blue;"&gt;double&lt;/SPAN&gt; x, &lt;SPAN style="COLOR:blue;"&gt;double&lt;/SPAN&gt; y)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Ball.SetValue(&lt;SPAN style="COLOR:#2b91af;"&gt;Canvas&lt;/SPAN&gt;.LeftProperty, x);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Ball.SetValue(&lt;SPAN style="COLOR:#2b91af;"&gt;Canvas&lt;/SPAN&gt;.TopProperty, y);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;
&lt;P&gt;Then I added the following JavaScript function (the "bridge") to the HTML page:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;var&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; _target = &lt;SPAN style="COLOR:blue;"&gt;null&lt;/SPAN&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;function&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; moveBall(x, y)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;if&lt;/SPAN&gt; (_target == &lt;SPAN style="COLOR:blue;"&gt;null&lt;/SPAN&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;_target = document.getElementById(&lt;SPAN style="COLOR:#a31515;"&gt;'TargetControl'&lt;/SPAN&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;_target.content.other.MoveBall(x, y);&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Finally, I added the following statement to the MouseMove handler in the first control (the one with the red ball):&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 10pt;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#2b91af;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;HtmlPage&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;.Window.Invoke(&lt;SPAN style="COLOR:#a31515;"&gt;"moveBall"&lt;/SPAN&gt;, x, y);&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;LINE-HEIGHT:115%;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;The X and Y coordinates passed in represent the current position of the red ball--the position I just moved it to in response to the latest mouse move.&lt;/P&gt;
&lt;P&gt;See how it works? You move the red ball. The MouseMove handler that moves the ball also calls the JavaScript moveBall function, which in turn calls the second control's MoveBall method. The red ball moves and the blue ball moves, too. This sample takes advantage of Silverlight 2's rich DOM integration features which allow C# methods to call JavaScript functions, JavaScript functions to call C# methods, and a whole lot more.&lt;/P&gt;
&lt;P&gt;I'll&amp;nbsp;post the source code this weekend. For now, it has been a long week, it's late, and I'll be locked away in a hotel all weekend building slides for my &lt;A class="" title="Silverlight Precon" href="https://www.msteched.com/dev/public/precons.aspx" target=_blank&gt;Silverlight precon&lt;/A&gt; at TechEd and taking care of other jobs that have piled up in my to-do list. Time to get some sleep.&lt;/P&gt;
&lt;P&gt;&lt;U&gt;UPDATE&lt;/U&gt;: The source code has been posted and you can &lt;A class="" title="Interop Demo Source Code" href="http://www.wintellect.com/Downloads/SilverlightInterop.zip"&gt;download it here&lt;/A&gt;. In addition, I posted a new version of SilverLife that uses DispatcherTimer rather a Storyboard to drive cell animations. You can &lt;A class="" title="SilverLife Source Code" href="http://www.wintellect.com/Downloads/SilverLife_2.0.zip"&gt;download the new version here&lt;/A&gt;.&lt;/P&gt;&lt;img src="http://www.wintellect.com/cs/aggbug.aspx?PostID=5850" width="1" height="1"&gt;</description></item><item><title>Reading XAML from a Silverlight Application Assembly</title><link>http://www.wintellect.com/cs/blogs/jprosise/archive/2008/04/08/reading-xaml-from-a-silverlight-application-assembly.aspx</link><pubDate>Tue, 08 Apr 2008 04:54:00 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:5821</guid><dc:creator>jprosise</dc:creator><slash:comments>1</slash:comments><description>&lt;P&gt;I was having dinner with &lt;A class="" title="WPF Wonderland" href="http://wpfwonderland.wordpress.com/" target=_blank&gt;Walt Ritscher&lt;/A&gt; tonight&amp;nbsp;when he posed an interesting question: how can a Silverlight app load its own XAML from an application assembly?&lt;/P&gt;
&lt;P&gt;I thought I knew the answer, because I had just finished doing a lot of research into the various ways to package code and resources in Silverlight 2.0. And I knew that the XAML files in a Silverlight 2.0 app get embedded as resources in the application assembly, which in turn gets embedded in the application package (the application's XAP file). But when I got back to my hotel and tried it, it didn't work. So I played around some and found the secret incantation.&lt;/P&gt;
&lt;P&gt;Here's the Page.xaml file in the test app that I wrote:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;UserControl&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:red;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; x&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;:&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:red;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;Class&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;="SilverlightTestApp.Page"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;xmlns&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="http://schemas.microsoft.com/client/2007"&lt;/SPAN&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;xmlns&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;x&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="http://schemas.microsoft.com/winfx/2006/xaml"&lt;/SPAN&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;Width&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="400"&lt;/SPAN&gt;&lt;SPAN style="COLOR:red;"&gt; Height&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="300"&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;Grid&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:red;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; x&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;:&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:red;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;="LayoutRoot"&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:red;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; Background&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;="White"&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;TextBlock&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:red;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; x&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;:&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:red;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;="Output" /&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;Grid&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;UserControl&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;And here's the output from the program:&lt;/P&gt;
&lt;P&gt;&lt;IMG title="XAML Output" style="WIDTH:500px;HEIGHT:285px;" height=285 alt="XAML Output" src="http://www.wintellect.com/cs/photos/prosise/images/5820/500x285.aspx" width=500&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Finally, here's the code in Page.xaml.cs that produces the output by loading Page.xaml from the application assembly and assigning it to a TextBlock object:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#2b91af;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;StreamResourceInfo&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; sri = &lt;SPAN style="COLOR:#2b91af;"&gt;Application&lt;/SPAN&gt;.GetResourceStream&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;(&lt;SPAN style="COLOR:blue;"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;Uri&lt;/SPAN&gt;(&lt;SPAN style="COLOR:#a31515;"&gt;"SilverlightTestApp;component/Page.xaml"&lt;/SPAN&gt;, &lt;SPAN style="COLOR:#2b91af;"&gt;UriKind&lt;/SPAN&gt;.Relative));&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#2b91af;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;StreamReader&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; reader = &lt;SPAN style="COLOR:blue;"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;StreamReader&lt;/SPAN&gt;(sri.Stream);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;Output.Text = reader.ReadToEnd();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;The trick is to include "&lt;EM&gt;assemblyname&lt;/EM&gt;;component" in the URI passed to GetResourceStream, even though the assembly you're loading from is the application assembly and not a library assembly. Normally you don't have to include the assembly name if you're targeting the application assembly, but this is obviously an exception--at least in Beta 1.&lt;/P&gt;
&lt;P&gt;I don't know how useful this information is, but it ought to make a good icebreaker at a Silverlight party.&lt;/P&gt;&lt;img src="http://www.wintellect.com/cs/aggbug.aspx?PostID=5821" width="1" height="1"&gt;</description></item><item><title>Silverlight Deep Zoom</title><link>http://www.wintellect.com/cs/blogs/jprosise/archive/2008/04/01/silverlight-deep-zoom.aspx</link><pubDate>Tue, 01 Apr 2008 22:25:00 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:5762</guid><dc:creator>jprosise</dc:creator><slash:comments>1</slash:comments><description>&lt;P&gt;Like a lot of folks, I was pretty impressed the first time I saw Silverlight 2.0's new Deep Zoom feature at work. So I downloaded &lt;A class="" title="Deep Zoom Composer" href="http://blogs.msdn.com/expression/archive/2008/03/05/download-the-preview-of-the-deep-zoom-composer.aspx" target=_blank&gt;Deep Zoom Composer&lt;/A&gt; and starting building apps to see what makes Deep Zoom tick. Deep Zoom Composer is cool, but what really makes Deep Zoom shine is the MultiScaleImage control. It is amazing how much you can do with so little code.&lt;/P&gt;
&lt;P&gt;I built an app that incorporates some of my favorite travel photos:&lt;/P&gt;
&lt;P&gt;&lt;IMG title="Deep Zoom" style="WIDTH:460px;HEIGHT:480px;" height=480 alt="Deep Zoom" src="http://www.wintellect.com/cs/photos/prosise/images/5763/460x480.aspx" width=460&gt;&lt;/P&gt;
&lt;P&gt;You can zoom in and out with the mousewheel or pan around by dragging with the left mouse button down. Some of the photos I used are higher-res than others, but in most of them you can zoom in enough to reveal quite a lot of detail.&lt;/P&gt;
&lt;P&gt;You can &lt;A class="" title="Deep Zoom Demo" href="http://www.wintellect.com/silverlight/deepzoom/" target=_blank&gt;view the app online&lt;/A&gt;,&amp;nbsp;and you can &lt;A class="" title="Deep Zoom Demo Source Code" href="http://www.wintellect.com/Downloads/DeepZoom.zip" target=_blank&gt;download the source code&lt;/A&gt;. The download doesn't include the images because&amp;nbsp;the images comprise more than 30 MB. But you can generate your own images and metadata with Deep Zoom Composer and plug them into my demo. All you have to do is copy the output folder created by&amp;nbsp;Composer into DeepZoom_Web's ClientBin folder and point the MultiScaleImage control declared in Page.xaml to the info.bin or items.bin file in the output folder. Then fire up the app and zoom away.&lt;/P&gt;
&lt;P&gt;When I exported from Deep Zoom Composer, I checked the "Create Collection" box to export a collection of images rather than one monolithic image. Although my code currently doesn't take advantage of it, exporting a collection allows you to use the SubImages property of the MultiScaleImage control to addess the individual images and even to change their position, aspect ratio, opacity, and Z-index. It appears (though I haven't tried it yet) that you can also change the zoom factor of individual images. Look for an updated demo in the near future that demonstrates some of these enticing capabilities.&lt;/P&gt;&lt;img src="http://www.wintellect.com/cs/aggbug.aspx?PostID=5762" width="1" height="1"&gt;</description></item><item><title>Updated Deep Dive CSS code</title><link>http://www.wintellect.com/cs/blogs/rrobinson/archive/2008/04/01/updated-deep-dive-css-code.aspx</link><pubDate>Tue, 01 Apr 2008 21:25:35 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:6003</guid><dc:creator>r2 musings - rants, raves, and research (mostly on .NET topics) from rik robinson</dc:creator><slash:comments>0</slash:comments><description>Thanks to all the folks that came to my Deep Dive CSS for the ASP.NET Developer session at this past weekend's Atlanta Code Camp. I got some really great feedback from the evaluations and will definitely incorporate some suggestions into this presentation in the future. The abstract, updated code and slides are available here: Deep Dive CSS for the ASP.NET Developer...(&lt;a href="http://www.wintellect.com/cs/blogs/rrobinson/archive/2008/04/01/updated-deep-dive-css-code.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://www.wintellect.com/cs/aggbug.aspx?PostID=6003" width="1" height="1"&gt;</description><category domain="http://www.wintellect.com/cs/blogs/rrobinson/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category><category domain="http://www.wintellect.com/cs/blogs/rrobinson/archive/tags/CSS/default.aspx">CSS</category><category domain="http://www.wintellect.com/cs/blogs/rrobinson/archive/tags/Presentations/default.aspx">Presentations</category></item><item><title>Threading and Marshaling in Silverlight 2.0</title><link>http://www.wintellect.com/cs/blogs/jprosise/archive/2008/03/26/threading-and-marshaling-in-silverlight-2-0.aspx</link><pubDate>Wed, 26 Mar 2008 23:45:00 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:5728</guid><dc:creator>jprosise</dc:creator><slash:comments>5</slash:comments><description>&lt;P&gt;Quick: can you spot what's wrong with this code?&lt;/P&gt;&lt;SPAN style="FONT-SIZE:10pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';"&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;COLOR:#2b91af;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;Thread&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; thread = &lt;SPAN style="COLOR:blue;"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;Thread&lt;/SPAN&gt;(&lt;SPAN style="COLOR:blue;"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;ThreadStart&lt;/SPAN&gt;(RunClock));&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;thread.Start();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:9pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;...&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;private&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; RunClock()&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;while&lt;/SPAN&gt; (&lt;SPAN style="COLOR:blue;"&gt;true&lt;/SPAN&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;Clock.Text = &lt;SPAN style="COLOR:#2b91af;"&gt;DateTime&lt;/SPAN&gt;.Now.ToLongTimeString();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;mso-fareast-font-family:Calibri;mso-ansi-language:EN-US;mso-fareast-theme-font:minor-latin;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;"&gt;}&lt;/SPAN&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The intent is to launch a thread and have that thread run an infinite loop updating a XAML TextBlock object that shows the current time of day. Aside from the questionable design (there are much more efficient ways to keep a time-of-day display up to date), there's something seriously wrong with this code. In fact, if you run it you'll find that the time-of-day display never updates at all. And therein lies a story.&lt;/P&gt;
&lt;P&gt;I was&amp;nbsp;surprised last year when I saw that&amp;nbsp;the Silverlight 1.1 alpha had a System.Threading namespace complete with all the classes I needed to launch threads, synchronize threads, acquire threads from a thread pool, etc. Silverlight 2.0 Beta 1 contains all these classes and more. I'm still amazed that I can write multithreaded apps that run in a browser, and I've been doing a lot of that lately--not because I need to, but just because I can. Silverlight 2.0's BackgroundWorker class simplifies the process of running tasks on background threads, and DispatchTimer is a handy alternative to empty Storyboards for programmable game timers. But you don't have to use either of them; you can&amp;nbsp;use Thread.Start, ThreadPool.QueueUserWorkItem, asynchronous delegates, and other mechanisms familiar to .NET developers to relegate tasks&amp;nbsp;to background threads.&lt;/P&gt;
&lt;P&gt;There is one nuance to Silverlight threading that you should be aware of, however: controls and other XAML objects can only be updated by the UI thread (the main thread that drives a Silverlight app). The reason the attempt to set the TextBlock's Text property in the example above fails is that we're attempting to set it from a background thread. For the sample to work, you need to modify it as follows:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;private&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:blue;"&gt;delegate&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;UpdateUIDelegate&lt;/SPAN&gt;();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:9pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;...&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;COLOR:#2b91af;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;Thread&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; thread = &lt;SPAN style="COLOR:blue;"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;Thread&lt;/SPAN&gt;(&lt;SPAN style="COLOR:blue;"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;ThreadStart&lt;/SPAN&gt;(RunClock));&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;thread.Start();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:9pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/SPAN&gt;...&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;private&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; RunClock()&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:9pt;COLOR:#2b91af;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;UpdateUIDelegate&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; action = &lt;SPAN style="COLOR:blue;"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR:#2b91af;"&gt;UpdateUIDelegate&lt;/SPAN&gt;(UpdateUI));&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;while&lt;/SPAN&gt; (&lt;SPAN style="COLOR:blue;"&gt;true&lt;/SPAN&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;Clock.Dispatcher.BeginInvoke(action);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;"&gt;&lt;SPAN style="FONT-SIZE:9pt;LINE-HEIGHT:115%;FONT-FAMILY:'Courier New';"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;private&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; UpdateUI()&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Clock.Text = &lt;SPAN style="COLOR:#2b91af;"&gt;DateTime&lt;/SPAN&gt;.Now.ToLongTimeString();&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:9pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;In the&amp;nbsp;corrected code, the background&amp;nbsp;thread marshals the call back to the UI thread by calling UpdateUI through a delegate invoked&amp;nbsp;via the&amp;nbsp;TextBlock object's Dispatcher property. Dispatcher is inherited from DependencyObject and is therefore present in all UI objects. For old folks like me who used to program Windows, this is analagous to using PostMessage to post a message to another thread. You don't have to use the Dispatcher property of the object you intend to update; you can use Dispatcher on any UI object to marshal the call to the UI thread.&lt;/P&gt;
&lt;P&gt;Programmers who have written multithreaded WPF apps won't be surprised by any of this because WPF also requires UI objects to be updated by UI threads. And of course there are ways to avoid using Dispatcher altogether.&amp;nbsp;The BackgroundWorker class, for example, fires events on UI threads, so there's no need to do any marshaling before updating a UI object. But there are times in Silverlight when you simply can't avoid marshaling from a background thread to a UI thread, and when those circumstances arise, it's useful to know about Dispatcher.&lt;/P&gt;&lt;img src="http://www.wintellect.com/cs/aggbug.aspx?PostID=5728" width="1" height="1"&gt;</description></item><item><title>Mousewheel Zooms in Silverlight 2.0</title><link>http://www.wintellect.com/cs/blogs/jprosise/archive/2008/03/18/mousewheel-zooms-in-silverlight-2-0.aspx</link><pubDate>Wed, 19 Mar 2008 00:11:00 GMT</pubDate><guid isPermaLink="false">c9b5046a-91b6-4822-a57a-d848b8cb6435:5679</guid><dc:creator>jprosise</dc:creator><slash:comments>6</slash:comments><description>&lt;P&gt;A few weeks ago I posted a short code sample demonstrating how to do mousewheel zooms in Silverlight 1.1. They're easier to do in Silverlight 2.0 and can be done without calling out of managed code, thanks to the new HtmlWindow class (and the HtmlPage.Window property, which returns a reference to an HtmlWindow).&lt;/P&gt;
&lt;P&gt;Here's a summary. First, assume you have a ScaleTransform that facilitates zooms:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff&gt;&amp;lt;&lt;/FONT&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#a31515;FONT-FAMILY:'Courier New';mso-no-proof:yes;mso-bidi-font-size:14.0pt;"&gt;ScaleTransform&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;mso-bidi-font-size:14.0pt;"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:red;FONT-FAMILY:'Courier New';mso-no-proof:yes;mso-bidi-font-size:14.0pt;"&gt;x:Name&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;mso-bidi-font-size:14.0pt;"&gt;=&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;mso-bidi-font-size:14.0pt;"&gt;"&lt;SPAN style="COLOR:blue;"&gt;ZoomTransform&lt;/SPAN&gt;"&lt;SPAN style="COLOR:blue;"&gt; /&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Next, when the page loads, use HtmlWindow.AttachEvent to register a managed handler for mousewheel events:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#2b91af;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;HtmlPage&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;.Window.AttachEvent(&lt;SPAN style="COLOR:#a31515;"&gt;"DOMMouseScroll"&lt;/SPAN&gt;, OnMouseWheelTurned);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#2b91af;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;HtmlPage&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;.Window.AttachEvent(&lt;SPAN style="COLOR:#a31515;"&gt;"onmousewheel"&lt;/SPAN&gt;, OnMouseWheelTurned);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:#2b91af;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;HtmlPage&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;.Document.AttachEvent(&lt;SPAN style="COLOR:#a31515;"&gt;"onmousewheel"&lt;/SPAN&gt;, OnMouseWheelTurned);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;
&lt;P&gt;Here's the event handler that responds to mousewheel events by manipulating the ScaleTransform:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;private&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt; &lt;SPAN style="COLOR:blue;"&gt;void&lt;/SPAN&gt; OnMouseWheelTurned(&lt;SPAN style="COLOR:#2b91af;"&gt;Object&lt;/SPAN&gt; sender, &lt;SPAN style="COLOR:#2b91af;"&gt;HtmlEventArgs&lt;/SPAN&gt; args)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;double&lt;/SPAN&gt; delta = 0;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;SPAN style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR:#2b91af;"&gt;ScriptObject&lt;/SPAN&gt; e = args.EventObject;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN:0in 0in 0pt;LINE-HEIGHT:normal;mso-layout-grid-align:none;"&gt;&lt;SPAN style="FONT-SIZE:10pt;FONT-FAMILY:'Courier New';mso-no-proof:yes;"&gt;&lt;o