<?xml version="1.0" encoding="utf-8"?>
<feed xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom">
  <title>Benjamin Nitschke's Blog about Game Development and .NET</title>
  <link rel="alternate" type="text/html" href="http://benjaminnitschke.com/" />
  <link rel="self" href="http://benjaminnitschke.com/SyndicationService.asmx/GetAtom" />
  <icon>favicon.ico</icon>
  <updated>2009-07-01T18:53:29.6257769+02:00</updated>
  <author>
    <name>BenjaminNitschke.com</name>
  </author>
  <subtitle>About .NET and Game Development</subtitle>
  <id>http://benjaminnitschke.com/</id>
  <generator uri="http://www.dasblog.net" version="2.0.7180.0">DasBlog</generator>
  <entry>
    <title>XNA MVP once again in 2009</title>
    <link rel="alternate" type="text/html" href="http://BenjaminNitschke.com/2009/07/01/XNAMVPOnceAgainIn2009.aspx" />
    <id>http://benjaminnitschke.com/PermaLink,guid,daab3bda-348d-49d7-af30-26e7d7638bc5.aspx</id>
    <published>2009-07-01T18:53:29.6257769+02:00</published>
    <updated>2009-07-01T18:53:29.6257769+02:00</updated>
    <category term="All" label="All" scheme="http://benjaminnitschke.com/CategoryView,category,All.aspx" />
    <category term="Development" label="Development" scheme="http://benjaminnitschke.com/CategoryView,category,Development.aspx" />
    <category term="Game Development" label="Game Development" scheme="http://benjaminnitschke.com/CategoryView,category,Game%2BDevelopment.aspx" />
    <category term="Other" label="Other" scheme="http://benjaminnitschke.com/CategoryView,category,Other.aspx" />
    <category term="Racing Game" label="Racing Game" scheme="http://benjaminnitschke.com/CategoryView,category,Racing%2BGame.aspx" />
    <category term="Reviews" label="Reviews" scheme="http://benjaminnitschke.com/CategoryView,category,Reviews.aspx" />
    <category term="XNA" label="XNA" scheme="http://benjaminnitschke.com/CategoryView,category,XNA.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <img src="http://benjaminnitschke.com/images/MVP.jpg" style="float:right;margin-left:10px" /> Buyaa,
I'm Microsoft MVP once again in the XNA/DirectX category for one more year (2009/2010).
I have been an XNA MVP since 2006 and I'm still very proud of it :)<br /><br />
I was pretty busy this year with our current game project "Fireburst" at exDream (a
racing game for Xbox 360, PS3 and PC using the Unreal3 engine, more about it soon)
and theirfore I did not do many other things (except writing some iPhone games, starting
to develop my own dynamic language and some tools). But once that project is done
in 1-2 months, I will do lots more XNA fun stuff and hopefully XNA Community Games
(now called Indie Games on the Xbox 360, I really hate that term) will be available
in Germany so I can finally review and submit some games myself. I'm still pretty
fit in XNA 3.1 and DirectX 11 (played around with it a lot in March), but for XNA
I'm still waiting for availablilty in Germany and for DirectX 11 I'm really waiting
for some cool hardware at the end of this year.<br /><br />
At exDream we recently also had some interesting discussions about using .NET for
PS3 (recently possible thanks to Novell), Xbox 360 (hello XNA) and PC or even more
dynamic script languages for upcoming projects. Maybe also including some other promising
platforms such as iPhone (also .NET able thanks to Unity), Android, PSP Go, WII, whatever,
but that all should depend more on the game and if we are able to manage so many platforms.
Working with XNA was almost no extra work to make a game run on the Xbox 360 plus
the PC, the game just has to fit and you obviously should allow control with the Xbox
360 controller. Our multiplatform game Fireburst is also not that bad to develop for
because most issues are handled by the great Unreal3 engine (except the fact of course
that it is all ugly C++ and UnrealScript code, which just looks like C++ anyway and
even has to be compiled), but it is still quite a lot more work than just doing a
PC only game, especially because of optimizations and testing required for all platforms.<br /><br />
Enough rambling, I'm going to celebrate this day by installing Windows 2008 server
(omg) because our pre-release version we had on there just ran out (warg) .. stupid
thing has to be completely reinstalled, no upgrade option ..<br /><p></p><img width="0" height="0" src="http://benjaminnitschke.com/aggbug.ashx?id=daab3bda-348d-49d7-af30-26e7d7638bc5" /></div>
    </content>
  </entry>
  <entry>
    <title>Fixing old DirectX 2D Games in Windows 7 like StarCraft</title>
    <link rel="alternate" type="text/html" href="http://BenjaminNitschke.com/2009/06/25/FixingOldDirectX2DGamesInWindows7LikeStarCraft.aspx" />
    <id>http://benjaminnitschke.com/PermaLink,guid,35f016fd-1b22-477c-a324-8e23f716d6a5.aspx</id>
    <published>2009-06-26T00:23:41.234+02:00</published>
    <updated>2009-06-26T00:26:27.703125+02:00</updated>
    <category term="All" label="All" scheme="http://benjaminnitschke.com/CategoryView,category,All.aspx" />
    <category term="BroodWar" label="BroodWar" scheme="http://benjaminnitschke.com/CategoryView,category,BroodWar.aspx" />
    <category term="Fun" label="Fun" scheme="http://benjaminnitschke.com/CategoryView,category,Fun.aspx" />
    <category term="Other" label="Other" scheme="http://benjaminnitschke.com/CategoryView,category,Other.aspx" />
    <category term="Reviews" label="Reviews" scheme="http://benjaminnitschke.com/CategoryView,category,Reviews.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <img src="http://media.moddb.com/cache/images/mods/1/12/11691/thumb_300x150/StarCraft_Icon.png" style="float: right; margin-left: 15px;" /> For
some time I had problems with StarCraft in Windows 7, after playing for 20-30min Windows
7 completely freezes keyboard, mouse and video (background programs and even Skype
still work, but a hard reset was always the only way to get out of it). Since I was
not playing much (just a few games a week) and it did not happen to me that much,
I did not worry at first. But after starting to play <a href="http://www.iccup.com/">ICCUP</a> a
few weeks ago with some friends, it just got annoying when I was crashing every 2-3
games. At first I was thinking maybe I overclocked way too much with my 4 Ghz, so
I tried playing with normal 2.6 Ghz, but that did not make any difference. I also
removed one of my graphic cards and tried playing on my primary screen instead of
my third one. Nothing did help. It seems when closing all programs and making sure
StarCraft only ran on one core (using the processor affinity setting in the task manager)
the crashes occured less often, but I could not really fix this issue.<br /><br />
In Windows 7 Beta I also had some crashes (but usually not blue screens or whole computer
freezes) with some games and applications, e.g. some Half-Life2 games like Garry's
Mod or Left 4 Dead crashed a few times for me, but with WIndows 7 RC this did not
happen anymore. In fact other than testing my overclocking settings I never had any
crash or bluescreen in Windows 7 RC except for playing StarCraft.<br /><br />
After reading a bit on some forums (<a href="http://www.teamliquid.net/">TeamLiquid</a>, <a href="http://classic.battle.net/forums.shtml">Blizzard</a>,
random Boards on the Internet) I saw many other people having the exact same problem:
Windows 7 RC x64 + StarCraft does not work well together. In fact any other 2D DirectX
from that time (like Age Of Empires 2, Worms Armageddon, etc.) seems also to cause
random crashes in Windows 7 RC, especially on a quad core system. Some people also
had another issue with the 256 colors, the trick here was to keep the Screen Resolution
dialog open in Windows and then start the game.<br /><br />
Well, the solution is kinda retarded, but it seems to work (many people reported it
and I did not have any problems since yesterday when I started using this trick):
Kill the Explorer.exe process before starting StarCraft.exe and restart it only after
closing StarCraft.exe again.<br /><br />
Since I also wanted to use the ICCUP Launcher, I wrote a little cmd script for this
job. I also had to disable some of my programs like WallRotate to prevent the 256
colors messing up in StarCraft every time my desktop changes. Here is the .cmd file
I use for starting StarCraft via the ICCUP  Launcher.exe plus all the additional
tricks like waiting 2 seconds for the update check of Launcher.exe, killing WallRotate.exe
(I commented it out, replace it with any other program you might want to close too)
and Explorer.exe and restarting everything after closing StarCraft again.<br /><br /><pre><span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;">rem
First start the ICCUP launcher (it won't work without Explorer.exe) cmd.exe /C start
C:\Games\Starcraft\Launcher.exe rem Wait a bit <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">for</span> ICCUP
Launchers update check! Use ping trick to wait 2 sec! ping 127.0.0.1 -n 2 rem First
kill Explorer.exe, which messes up our colors <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">in</span> StarCraft
taskkill /f /IM explorer.exe rem Also kill our desktop changer, which messes up the
colors <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">in</span> game
rem taskkill /f /IM WallRotate.exe rem Change to the StarCraft directory to make sure
we run normally! cd C:\Games\Starcraft\ rem And launch StarCraft ourselfs since we
can't see the ICCUP launcher without Explorer.exe rem Please note that /affinity 1
makes sure we only use our first core rem Using all cores <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">for</span> StarCraft.exe
can lead to crashes <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">in</span> Windows
7 :( cmd.exe /C start /affinity 1 C:\Games\Starcraft\StarCraft.exe rem Some early
tests: rem C:\Games\Starcraft\StarCraft.exe rem C:\Games\Starcraft\Launcher.exe rem
Wait <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">for</span> the
game to quit, press Enter to <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">continue</span> pause
rem Restart Explorer.exe and WallRotate, that's it! start explorer.exe rem start C:\code\WallRotate\bin\Release\WallRotate.exe
exit</span></pre><br /><br /><p></p><img width="0" height="0" src="http://benjaminnitschke.com/aggbug.ashx?id=35f016fd-1b22-477c-a324-8e23f716d6a5" /></div>
    </content>
  </entry>
  <entry>
    <title>Only work at one task at a time</title>
    <link rel="alternate" type="text/html" href="http://BenjaminNitschke.com/2009/06/24/OnlyWorkAtOneTaskAtATime.aspx" />
    <id>http://benjaminnitschke.com/PermaLink,guid,aea4144e-510d-4485-ac94-ad2dbae45fe4.aspx</id>
    <published>2009-06-24T20:00:40.515625+02:00</published>
    <updated>2009-06-24T20:00:40.515625+02:00</updated>
    <category term="All" label="All" scheme="http://benjaminnitschke.com/CategoryView,category,All.aspx" />
    <category term="Development" label="Development" scheme="http://benjaminnitschke.com/CategoryView,category,Development.aspx" />
    <category term="Fun" label="Fun" scheme="http://benjaminnitschke.com/CategoryView,category,Fun.aspx" />
    <category term="Game Development" label="Game Development" scheme="http://benjaminnitschke.com/CategoryView,category,Game%2BDevelopment.aspx" />
    <category term="Other" label="Other" scheme="http://benjaminnitschke.com/CategoryView,category,Other.aspx" />
    <category term="Programming" label="Programming" scheme="http://benjaminnitschke.com/CategoryView,category,Programming.aspx" />
    <category term="Reviews" label="Reviews" scheme="http://benjaminnitschke.com/CategoryView,category,Reviews.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">I want to quote from this great article
I just read: <a href="http://webworkerdaily.com/2009/06/19/singletasking-the-next-trend-in-web-working/">Singletasking:
The Next Trend in Web Working?</a><br /><br />
"Singletasking is just what it sounds like: approaching and tackling one task at a
time, sequentially, instead of trying to do a whole bunch of things at once, as has
become <em>de rigeur</em> in our modern multitasking age. If you’re like me, the thought
is probably at least a little refreshing, and maybe more than a little appealing right
off the bat.<br /><br />
The principle is sound. Take on one task at a time, and don’t begin another until
the one you’ve already started is complete. It sounds simple, but you know as well
as I do that actually implementing that kind of thing in real life will take a lot
more effort than you might first think. For one, it means ignoring any urge to procrastinate,
and making sure that you prioritize very carefully in advance, lest you realize too
late that what you thought was most urgent actually could’ve taken a back seat to
something else."<br /><br />
The article goes on with tools used to track work tasks and even ideas on only use
one Tab in Firefox and only using one monitor. I can hardly agree with that, I currently
have 10 tabs open (after reading all emails and stuff on the web) because I don't
have time right now to finish reading those sites or because some things are still
pending (waiting for a response and keeping the tab open as a reminder). I also currently
look at 3 monitors. Well not really, I only write this on my right monitor, but I
have my main task (some optimization work) on my main screen in the center in Visual
Studio. I really hate putting anything above Visual Studio because then I won't focus
on writing code, but do other stuff instead. I only do it if I have to write some
document, have to do some web research or reading some documentation.<br /><br />
While I totally agree with doing (and finishing) one task at a time (that's actually
how my TODO list works that I use in every single project for the last 6+ years),
I just can't agree with just having one monitor (or just using one at a time like
the writer of the article proposes). For example when opening an editor like for our
Unreal3 game, you absolutely need 2+ monitors because else you just have 5 overlapping
windows and spend half of your time moving them around trying to see whats behind
them.<br /><br />
In Visual Studio I only have the Solution Explorer sometimes and some Find Results
or Console Windows on my secondary screen, but all the screens are filled with useful
stuff anyway. I also have basically 2 screens at once at my primary screen anyway
because I always look at 2 concurrent tabs in Visual Studio (really can't live without
it). That does not mean that I really multitask. I ALWAYS only work on one tab, but
I can quickly look over, see all the variables and methods that I need and I can code
much faster that way.<br /><br />
If you want to have some distractions when working I suggest only checking them out
after completing a task. I usually do it as a reward kinda thing, like playing a game
I wanted to test out only after I finished my current task. And then continue with
the next task.<br /><p></p><img width="0" height="0" src="http://benjaminnitschke.com/aggbug.ashx?id=aea4144e-510d-4485-ac94-ad2dbae45fe4" /></div>
    </content>
  </entry>
  <entry>
    <title>TestDriven.Net for VS 2010</title>
    <link rel="alternate" type="text/html" href="http://BenjaminNitschke.com/2009/06/08/TestDrivenNetForVS2010.aspx" />
    <id>http://benjaminnitschke.com/PermaLink,guid,aa065c2b-3930-4e8a-b898-8b5eae56d863.aspx</id>
    <published>2009-06-08T02:27:17.370125+02:00</published>
    <updated>2009-06-08T02:27:17.370125+02:00</updated>
    <category term="All" label="All" scheme="http://benjaminnitschke.com/CategoryView,category,All.aspx" />
    <category term="Development" label="Development" scheme="http://benjaminnitschke.com/CategoryView,category,Development.aspx" />
    <category term="DLR" label="DLR" scheme="http://benjaminnitschke.com/CategoryView,category,DLR.aspx" />
    <category term="Fun" label="Fun" scheme="http://benjaminnitschke.com/CategoryView,category,Fun.aspx" />
    <category term="Game Development" label="Game Development" scheme="http://benjaminnitschke.com/CategoryView,category,Game%2BDevelopment.aspx" />
    <category term="Other" label="Other" scheme="http://benjaminnitschke.com/CategoryView,category,Other.aspx" />
    <category term="Reviews" label="Reviews" scheme="http://benjaminnitschke.com/CategoryView,category,Reviews.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <img src="http://www.baboo.com.br/absolutenm/articlefiles/33246-visual_studio_2010_logo.png" style="float:right; margin-left:10px; margin-bottom:5px" /> As
Jamie Cansdale posted in my comments ^^:<br /><br /><b>There's now a version of TestDriven.Net what works with VS 2010</b>:<br /><a href="http://weblogs.asp.net/nunitaddin/archive/2009/06/03/testdriven-net-2-22-support-for-visual-studio-2010-beta-1.aspx">http://weblogs.asp.net/nunitaddin/archive/2009/06/03/testdriven-net-2-22-support-for-visual-studio-2010-beta-1.aspx</a><br /><br />
Finally time to use VS2010 a little bit more, without TestDriven.Net it was just unusable
before.<br /><br />
I worked all weekend on AI and game logic scripts in Lua and UnrealScript .. would
like to talk about it, but since our game project is still not announced yet, I'm
not allowed to .. grr ..<br /><br />
Also reading (or hearing) right now: <a href="http://www.brainrules.net/">http://www.brainrules.net/</a><br />
And working through the great new release of the DLR and the new example script language
Sympl: <a href="http://www.codeplex.com/dlr">http://www.codeplex.com/dlr</a><br /><p></p><img width="0" height="0" src="http://benjaminnitschke.com/aggbug.ashx?id=aa065c2b-3930-4e8a-b898-8b5eae56d863" /></div>
    </content>
  </entry>
  <entry>
    <title>Most distracting addin ever for Visual Studio: Changing background images</title>
    <link rel="alternate" type="text/html" href="http://BenjaminNitschke.com/2009/06/02/MostDistractingAddinEverForVisualStudioChangingBackgroundImages.aspx" />
    <id>http://benjaminnitschke.com/PermaLink,guid,6c7b4413-e836-46e2-90cc-00cca8908c6d.aspx</id>
    <published>2009-06-03T01:57:31.375+02:00</published>
    <updated>2009-06-03T01:57:31.375+02:00</updated>
    <category term="All" label="All" scheme="http://benjaminnitschke.com/CategoryView,category,All.aspx" />
    <category term="Development" label="Development" scheme="http://benjaminnitschke.com/CategoryView,category,Development.aspx" />
    <category term="Fun" label="Fun" scheme="http://benjaminnitschke.com/CategoryView,category,Fun.aspx" />
    <category term="Game Development" label="Game Development" scheme="http://benjaminnitschke.com/CategoryView,category,Game%2BDevelopment.aspx" />
    <category term="Other" label="Other" scheme="http://benjaminnitschke.com/CategoryView,category,Other.aspx" />
    <category term="Programming" label="Programming" scheme="http://benjaminnitschke.com/CategoryView,category,Programming.aspx" />
    <category term="Reviews" label="Reviews" scheme="http://benjaminnitschke.com/CategoryView,category,Reviews.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <img src="http://benjaminnitschke.com/content/binary/VSBlackBackgroundSmall.jpg" style="float: right; margin-left: 10px; margin-bottom: 5px;" />
        <a href="http://vsbackgroundchanger.codeplex.com/">Download
link for CR_RandomBackgroundChanger now at CodePlex.</a>
        <br />
        <br />
I used several tools over the years to change my background image automatically every
few minutes. I even collected over 50k desktop images over the years ^^ While this
is great and always fun to watch at changing backgrounds every few minutes, most of
the time I do not even notice because all my screens are completely covered by windows. 
<br /><br />
As a programmer I have Visual Studio open most of the time, especially at work, where
distractions like changing background images would have the biggest impact. Luckily
Visual Studio has a boring white (or black for me) background and will not distract
us that much. It would be terrible if Visual Studio would have changing background
images that even make it harder to look at code and could be distracting having a
background image changing every 5 minutes. Let's explore that! 
<br /><br />
First of all: <b>How to even change or set a background image directly in the Visual
Studio code window?</b><br />
There is a great collection of gadgets from the SlickEdit guys, called <a href="http://www.slickedit.com/content/view/441">Free
SlickEdit Gadgets</a>, which are completely free to use and include a feature to set
a background image in the code editor. Searching for this on a search engine like
Google isn't that easy, it is easier to find if you search for "Visual Studio Dancing
Banana" :) 
<br /><br />
After you have installed the SlickEdit Gadgets (which currently only work on VS2005/VS2008,
not on VS2010 yet), you should see a SlickEdit menu item. From there you can select
Editor Gadgets, which just opens the Visual Studio Options dialog. There you can go
to the Editor graphic tab and select a background image to be displayed in the editor.
I use the following settings: 
<ul><li>
Display an image: Checked 
</li><li>
Image textbox: The selected image 
</li><li>
Tile Radiobutton checked (use bottom left if you just want a small transparent image
there, IMO not distracting enough!) 
</li><li>
Lock the image location checked 
</li><li>
Transparency checked and set to 75% (which means 25% visibility, 75% of your background
color remains). 
</li></ul>
Now your code window might look like the following:<br /><img src="http://benjaminnitschke.com/content/binary/VSWhiteBackgroundImage1.jpg" border="0" /><br /><br />
While this is kinda fun, it is not distracting enough yet. We need changing background
images and preferably a way to quickly change the editor background image with a click
at anytime in case it doesn't fit. First of all we need to find out where SlickEdit
saves this background image. After searching for some SlickEdit setting file and not
able to find any, I checked the registry and found this key: <b>HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\SlickEdit\EditorGadgets\ImageFilename</b> This
is where the image name is saved. Just for fun I changed it to "<b>C:\Users\Public\Pictures\Sample
Pictures\Penguins.jpg</b>", but obviously nothing happend because there was no reason
for Visual Studio to reload and apply any new settings from the Options dialog. So
how to we force that to happen? 
<br /><br />
Well, after trying to find some solution for that for a while, I gave up. There is
no event I can trigger to update this and there is simply no functionality in the
SlickEdit Gadgets to get this update working. 
<br /><br />
Since I would need to write something to set a new background image every few minutes
anyway and this won't be easy or even impossible with my little Wallpaper Changer
app I decided to write a VS addin myself. I started a new CodeRush plugin (which also
runs on the free DXCore framework) and called it <b>CR_RandomBackgroundChanger</b> (a
little bit too long for CodePlex, so there it is just called <b>VSBackgroundChanger</b>).
Next I used the EditorPaint event and wrote the following code to display an image
in the code editor:<br /><br /><pre><span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;"> private</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">void</span> BackgroundChangerPlugIn_EditorPaint(EditorPaintEventArgs
ea) { <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//Log.Write("BackgroundChangerPlugIn_EditorPaint");</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//tst:
ea.DrawLine(1, 1, 50, Color.Red);</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">if</span> (currentBackgroundImage
== <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">null</span>)
currentBackgroundImage <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> Bitmap.FromFile( <span style="color: rgb(102, 102, 102); background-color: rgb(228, 228, 228); font-family: Courier New; font-size: 11px;">@"C:\Users\Public\Pictures\Sample
Pictures\Desert.jpg"</span>); ea.Graphics.DrawImage(backgroundImage, 0, 0); } <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
BackgroundChangerPlugIn_EditorPaint(ea)</span></span></pre>
This produced terrible results. The image got displayed for a fraction of a second
and then was replaced by the default background color. Using other events from the
StandardPlugIn class in the CodeRush framework like EditorPaintBackground, EditorPaintForeground,
EditorPaintLanguageElement, EditorvalidateClipRegion, etc. also did not help much,
the background image was usually not displayed and even if it was flickering terribly
and disappearing all the time. 
<br /><br />
So CodeRush was not very helpful in this particular instance, but no reason to give
up. Actually I gave up that day after trying out so many things for many frustrating
hours. The next day I tried something different: Use the NativeWindow class to intercept
any event that is send to the Visual Studio code editor window (called View in CodeRush
btw). Basically you derive from NativeWindow and then call the AssignHandle method
to set the window handle (I just do it in the constructor). From then on you will
get all WndProc events and you can decide whether to pass it on to the original WndProc
or do something yourself. 
<br /><pre><span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">public</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">class</span> ActiveViewBackgroundHelper
: NativeWindow { <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">#region</span> Constructor <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
&lt;summary&gt;</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
Create active view background helper class, each document view</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
will get an instance of this class to handle the background drawing!</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
&lt;/summary&gt;</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">public</span> ActiveViewBackgroundHelper(IntPtr
windowHandle) { <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">base</span>.AssignHandle(windowHandle);
} <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
ActiveViewBackgroundHelper(windowHandle)</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">#endregion</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">#region</span> WndProc <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
&lt;summary&gt;</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
WndProc, we are only interested at the WM_PAINT event!</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
If a paint happens and we got a valid we will call DrawBackgroundImage</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
&lt;/summary&gt;</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
&lt;param name="m"&gt;&lt;/param&gt;</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">protected</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">override</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">void</span> WndProc(<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">ref</span> Message
m) { <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Your own code goes here</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">base</span>.WndProc(<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">ref</span> m);
} <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
WndProc()</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">#endregion</span> } <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
class ActiveViewBackgroundHelper</span></span></pre><br />
Now I was able to intercept all WM_ERASEBKGND and WM_PAINT messages. WM_ERASEBKGND
turned out to be non-relevant because all the rendering happens in WM_PAINT. Otherr
events like WM_NCPAINT and all the code rush events happened between a single WM_PAINT
event anyway. So I had to dig deeper into WM_PAINT. I could not render a background
image at the very start of WM_PAINT and if I aborted rendered right there, it would
be displayed in the editor. But there was no text anymore making VS just useless.
I had to figure out how to render text on top of my image by copying all the VS editor
content to a bitmap and then later drawing it on top of my background image. To make
all the flickering go away by drawing into a targetBitmap and then displaying that
at once to the window (everything else flickers). There is also a lot of other optimizations
and tricks in there. We will get back to the code in a little bit. 
<br /><br />
After working on this for the better part of the last weekend, I finally got it working
and put some extra features in this CR_RandomBackgroundChanger addin, which you can
see in this nice option screen for it. Note that I have a black background in Visual
Studio, if you have a white one the preview image would be white with black text and
it would have 25% of the background image mixed in.<br /><br /><img src="http://benjaminnitschke.com/content/binary/CR_RandomBackgroundChanger_Options.jpg" border="0" /><br /><br /><a href="http://vsbackgroundchanger.codeplex.com/">You can download the addin and
the source code at http://vsbackgroundchanger.codeplex.com/</a><br /><br />
I'm trying out CodePlex for this addin. I will probably improve it a little in the
future and upgrade it to VS2010. I will also put up other projects on CodePlex like
CR_Commenter and maybe some of my XNA games. I also plan to work a little bit more
on my language and then put it on CodePlex too when I got a alpha version working
with all basic features.<br /><br />
In the option screen of CR_RandomBackgroundChanger you can specify 5 settings: 
<ul><li>
Enabled: Whether to use this addin at all. This allows you to quickly disable the
addin and keeping all your previous settings once you need more distractions again. 
</li><li>
Directory: All images in this directory and all images in all the sub directories
will be used for displaying random background images in your Visual Studio code editor.
Please note that searching for 100 000+ images can take a few seconds (I tested it
with that many), but the subsequent VS startups and every background image change
will be very fast because of all the caching involved. The disadvantage of all the
caching is that if you add new images or even delete the whole images folder, you
need to update this directory to get all those changes reflected by the addin by either
deleting the cached ImageFilenames.txt in your %TEMP% directory or by just selecting
the same directory again. 
</li><li>
Transparency (default: 25% opacity): This is the most important setting because having
colorful background images at 100% opacity can often make the already colorful editor
text unreadable. If you know that your background images have mostly the same color
as your code background you can use higher settings (for example I used some black
only images with some stuff on the right in the beginning, while this was cool at
first, it got boring after a while because I'm used to changing background images
every few minutes). If you have photos or other images that do not really fit to having
text on top of them use even lower opacity settings (e.g. 10%) to make Visual Studio
text easier to read. You can mostly still see the background image if your code window
is big enough and you have some empty lines in there :) 
</li><li>
Change image every x seconds: Use this setting to allow the addin to change the background
images every 5 minutes (or use whatever number of minutes you like). Note that using
0 minutes will result in constantly changing backgrounds while you are typing and
scrolling, not really sure if this is useful, but was good for testing ^^ 
</li><li>
And finally the last settings is to use different background images for different
document windows. If you have 20 documents opened in Visual Studio, every one of them
will get a different background image (which can then change every 5 minutes too).
This even makes it easier to figure out where you are, I probably need to improve
the Tab-Rendering too to make it more useful like the ColorfulTabs addin for Firefox.
And this is of course great fun, usually I get annoyed by having too many documents
open so I often close them all after I get 50, but now I really like having many different
background images open. 
</li></ul>
The option screen also features the Preview box, which lets you see your selected
background images and tweak the transparency setting until it looks right for you.
Once you close the Options screen all settings will be applied to your VS code editor.
Please note that this addin only works whenever a WM_PAINT event happens. This is
usually only in the active document you are working on. Most of the time the background
image will stay even if you change to another tab on the other side (if you use 2
tabs at once, else you will never notice this anyway). Sometimes you see some black
or white background lines drawn on top of your background image because just some
text was updated, but this happens very rarely. I hope you enjoy the addin, I will
probably use it for a long time and I will port it to VS2010 once CodeRush runs there
or I'm using VS2010 (still waiting for a working TestDriven.net version). Hopefully
implementing this addin with the MEF (Managed Extensibility Framework) is not hard. 
<br /><br />
Let's go back to the code. Last time I stopped talking about the WndProc method, which
is most important for catching and handling the WM_PAINT event. From here we can call
our DrawBackgroundImage method, which does all the magic. Please note that the source
code for the addin is a lot more complex than the code presented here. This is mostly
because of heavy optimizations and a lot of caching to make the code run as fast as
possible (one of the most important things about this addin, it would be unusable
if it makes VS slow).<br /><pre><span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">#region</span> WndProc <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
&lt;summary&gt;</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
WndProc, we are only interested at the WM_PAINT event!</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
If a paint happens and we got a valid we will call DrawBackgroundImage</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
&lt;/summary&gt;</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
&lt;param name="m"&gt;&lt;/param&gt;</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">protected</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">override</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">void</span> WndProc(<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">ref</span> Message
m) { <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Just make sure we mark the erase background message as handled.</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Will not do anything anyway (all painting done in WM_PAINT).</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">if</span> (m.Msg
== (<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">int</span>)WindowsMessages.WM_ERASEBKGND)
{ <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Mark event is already handled</span> m.Result <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> (IntPtr)1;
} <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
if</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Handle the paint event</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">if</span> (m.Msg
== (<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">int</span>)WindowsMessages.WM_PAINT
&amp;&amp; <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Are we currently drawing our own background? Then make sure we do</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
not handle this and use the default message handling instead!</span> drawingBackground
== <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">false</span> &amp;&amp; <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Make sure we got a view, else we don't have a windows handle!</span> CodeRush.TextViews.Active
!<span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">null</span> &amp;&amp; <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Check for invalid hwnd, then we can't paint backgroundImage!</span> (<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">int</span>)CodeRush.TextViews.Active.Handle
!<span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> 0)
{ TextView view <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> CodeRush.TextViews.Active;
IntPtr activeWindowHandle <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> view.Handle;
Rectangle rect <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">new</span> Rectangle();
Win32.GetUpdateRect(activeWindowHandle, <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">ref</span> rect, <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">false</span>); <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Only proceed if we have a valid rect</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">if</span> (Win32.IsRectEmpty(<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">ref</span> rect)
== <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">false</span>)
{ <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Make sure we mark this flag so subsequent calls to WM_PAINT</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
will actually just paint the normal stuff, not just our</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
background rendering!</span> drawingBackground <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">true</span>;
DrawBackgroundImage(activeWindowHandle, rect); drawingBackground <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">false</span>; <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Mark event is already handled</span> m.Result <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> (IntPtr)1; <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Do not call base.WndProc, we don't want to process it here!</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Instead we invalidate inside DrawBackgroundImage and force</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
a new WM_PAINT event inside there, which will be executed</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
because drawingBackground is still true while in there.</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">return</span>;
} <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
if (rect)</span> } <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
if (WM_PAINT)</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">base</span>.WndProc(<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">ref</span> m);
} <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
WndProc()</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">#endregion</span></span></pre>
And finally the DrawBackgroundImage method, which copies the current editor text as
an image, applies transparency to it. Then we draw our background image and the now
transparent editor text on top into a helper targetBitmap, which is finally displayed
on the screen at once (else we would get flickering issues). Please note that in the
source code you can download there is a some testing code, e.g. for drawing bitmaps
with transparency using ImageAttributes and SetColorMatrix, which works great, but
is just too slow. Our approach is to pre-calculate the opacity in the backgroundImage
and use that over and over again (3-4 times faster). There is still a performance
penalty for all this painting, but any future optimizations will be hard. I recommend
using 2 tabs, rendering is twice as fast (because only one side is updated when you
type or scroll) and you should have a fast PC :)<br /><br /><pre><span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">#region</span> DrawBackgroundImage <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
&lt;summary&gt;</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
This method draws the background and is called from WndProc whenever</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
it intercepts a WM_PAINT message. Again, some caching and confusing</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
optimized code is in here too, again for getting good performance.</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
&lt;/summary&gt;</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">private</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">void</span> DrawBackgroundImage(IntPtr
activeWindowHandle, Rectangle rect) { <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Create an image for storing the orginal editor screen.</span> Bitmap sourceImage <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">new</span> Bitmap(rect.Width,
rect.Height); <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Always create new graphics object, else we won't have current data</span> Graphics
sourceImageGraphics <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> Graphics.FromImage(sourceImage); <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
And grab current editor window content and copy it to it!</span> IntPtr hdc <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> sourceImageGraphics.GetHdc();
Win32.PrintWindow(activeWindowHandle, hdc, 1); sourceImageGraphics.ReleaseHdc(hdc); <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Next find the color on the bottom right and use it as the</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
transparent color! Note: Antialasing will cause artifacts, make sure</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
the backgroundImage fits to the background color, e.g. by using a</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
lot of alpha transparency (&lt;25% visibility)!</span> backgroundColorPixel <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> sourceImage.GetPixel(rect.Width <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">-</span> 1,
rect.Height <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">-</span> 1);
sourceImage.MakeTransparent(backgroundColorPixel); <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Create target image where we wanna paint to, this is important</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
because drawing directly to the VS window will produce flickering!</span> Bitmap targetBitmap <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">new</span> Bitmap(rect.Width,
rect.Height); Graphics targetBitmapGraphics <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> Graphics.FromImage(targetBitmap); <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Clear background with pixel color</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//not
required, we draw solid image now (use this for transparent drawing):</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//targetBitmapGraphics.Clear(backgroundColorPixel);</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Draw background image (tiled and transparent if specified)</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">float</span> transparency <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> Options.transparency <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">/</span> 100.0f;
Image backgroundImage <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> GetBackgroundImage((<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">int</span>)activeWindowHandle,
backgroundColorPixel, transparency); <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Do the drawing as many times as we need to tile to fill everything!</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">for</span> (<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">int</span> y <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> 0;
y &lt; rect.Height; y+=backgroundImage.Height) <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">for</span> (<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">int</span> x <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> 0;
x &lt; rect.Width; x += backgroundImage.Width) { targetBitmapGraphics.DrawImage(backgroundImage,
x, y); } <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
for for</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Now draw source image on top (text and foreground stuff), else we</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
would only see our distracting background image and while that is</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
fun, we sometimes still need to be productive and see the editor</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
text ^^</span> targetBitmapGraphics.DrawImage(sourceImage, 0, 0); <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Finally draw on the VS window, but only do one single draw here</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
to make sure we do not have any flickering!</span> Graphics graphics <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> Graphics.FromHwnd(activeWindowHandle);
graphics.DrawImage(targetBitmap, 0, 0); <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
This is important: Validate the rect so all this can now be</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
displayed! All WM_PAINT calls during this method will</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
be handled normally (without our background painting), which is</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
used for normal updates because we mess everything up ^^</span> Win32.ValidateRect(activeWindowHandle, <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">ref</span> rect); <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Dispose everything we do not need anymore</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Note: We always have to create new graphics and dispose them here,</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
else updating sourceImage, targetBitmap, etc. does not work!</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">if</span> (graphics
!<span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">null</span>)
graphics.Dispose(); <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">if</span> (sourceImageGraphics
!<span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">null</span>)
sourceImageGraphics.Dispose(); <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">if</span> (targetBitmapGraphics
!<span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">null</span>)
targetBitmapGraphics.Dispose(); } <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
DrawBackgroundImage(activeWindowHandle, rect)</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">#endregion</span></span></pre><br />
For more information check out the source code, the important code for the addin is
in ActiveViewBackgroundHelper.cs and the Options and PlugIn classes. The rest of the
classes are just helpers for logging, string operations, random methods and Win32
helpers for some calls. 
<br /><br /><a href="http://vsbackgroundchanger.codeplex.com/">Download this addin at http://vsbackgroundchanger.codeplex.com/</a><br /><br />
I hope you will enjoy this addin. Here are 2 more screens from using this addin with
different background colors and images:<br /><br />
White background theme (25% opacity):<br /><img src="http://benjaminnitschke.com/content/binary/VSWhiteBackgroundImage2.jpg" border="0" /><br /><br />
Black background theme (25% opacity):<br /><img src="http://benjaminnitschke.com/content/binary/VSBlackBackgroundImage1.jpg" border="0" /><img width="0" height="0" src="http://benjaminnitschke.com/aggbug.ashx?id=6c7b4413-e836-46e2-90cc-00cca8908c6d" /></div>
    </content>
  </entry>
  <entry>
    <title>Playing around with VS2010 and the Parallel Extensions</title>
    <link rel="alternate" type="text/html" href="http://BenjaminNitschke.com/2009/05/26/PlayingAroundWithVS2010AndTheParallelExtensions.aspx" />
    <id>http://benjaminnitschke.com/PermaLink,guid,c0188e30-be4c-4e3d-93f8-1f228d2f7f5c.aspx</id>
    <published>2009-05-27T01:28:45.859375+02:00</published>
    <updated>2009-05-27T01:28:45.859375+02:00</updated>
    <category term="All" label="All" scheme="http://benjaminnitschke.com/CategoryView,category,All.aspx" />
    <category term="Development" label="Development" scheme="http://benjaminnitschke.com/CategoryView,category,Development.aspx" />
    <category term="Fun" label="Fun" scheme="http://benjaminnitschke.com/CategoryView,category,Fun.aspx" />
    <category term="Game Development" label="Game Development" scheme="http://benjaminnitschke.com/CategoryView,category,Game%2BDevelopment.aspx" />
    <category term="Other" label="Other" scheme="http://benjaminnitschke.com/CategoryView,category,Other.aspx" />
    <category term="Programming" label="Programming" scheme="http://benjaminnitschke.com/CategoryView,category,Programming.aspx" />
    <category term="Reviews" label="Reviews" scheme="http://benjaminnitschke.com/CategoryView,category,Reviews.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <img src="http://www.baboo.com.br/absolutenm/articlefiles/33246-visual_studio_2010_logo.png" style="float: right; margin-left: 10px; margin-bottom: 6px;" /> Last
week when I installed VS2010 I played around with it for a few minutes, but I've been
very busy at work because our game is at its final stage and we got a lot of heat
going on (this is not a hint, no no, no hint from me, I'm not allowed to talk about
it. Damn it, this could be a hint). 
<br /><br />
Currently the most interesting new feature besides the cool VS2010 IDE is the Parallel
Extensions for me. Sadly the IDE still unusable for real work IMO because all the
addins just don't work, there isn't even a fix for <a href="http://TestDriven.net">TestDriven.net</a> yet, <a href="http://weblogs.asp.net/nunitaddin/">Jamie
Cansdale</a> is probably busy too ^^ 
<br /><br />
VS2010 support for parallel programming goes beyond just adding a few extra classes
in .NET 4.0: You also got a great IDE implementation which lots of useful features
and new tool debugging and profiling windows for checking out parallel tasks, threads
and the scheduling. Next there are native C++ libraries that work with Parallel Extensions
too (using lambda functions) and work good together with STL. <a href="http://www.microsoft.com/visualstudio/en-us/products/2010/default.mspx">You
can check out all the new features at the official VS2010 page!</a><br /><br />
Let's take a quick look on how to use these Parallel Extensions. I wrote this in a
few minutes last week, I was just too lazy (I mean busy of course) to post it yet,
it is obviously very simple stuff, but was still useful to test out some of the new
parallel IDE features and check out some new .NET 4.0 classes. First of all let's
do a boring foreach loop, which displays numbers from 0 to 9, which get added to expectedTotalNum.
This should obviously be 45 because sum(0..9)=45. Later we will do some parallel foreach
adding and check if we got the same result. Since it does not matter in which order
we add these numbers, it is also a good test to just start a bunch of parallel tasks
and let them do their work. Obviously you would never write parallel code just to
add some numbers, but this should illustrate the point and it does not hurt your performance
much anyway (as long as you have a few lines of code executing that take more than
a few instructions).<br /><pre><span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Initialize a list for some parallel testing :)</span><br />
List&lt;<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">int</span>&gt;
someInts <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">new</span> List&lt;<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">int</span>&gt;();<br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">for</span> (<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">int</span> num <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> 0;
num &lt; 10; num++)<br />
someInts.Add(num);<br /><br /><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Print out numbers sequentially</span><br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">int</span> expectedTotalNum <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> 0;<br /><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">foreach</span> (<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">int</span> num <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">in</span> someInts)<br />
{<br />
Console.WriteLine(<span style="color: rgb(102, 102, 102); background-color: rgb(228, 228, 228); font-family: Courier New; font-size: 11px;">"sequential
num="</span><span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">+</span> num);<br />
expectedTotalNum += num;<br />
}<br /><br />
Console.WriteLine(<span style="color: rgb(102, 102, 102); background-color: rgb(228, 228, 228); font-family: Courier New; font-size: 11px;">"expectedTotalNum="</span><span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">+</span> expectedTotalNum);<br /></span></pre>
This outputs the obvious sequential adding of 0 to 9 to expectedTotalNum, which is
45 at the end of the loop:<br /><pre><span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;">sequential
num=0 sequential num=1 sequential num=2 sequential num=3 sequential num=4 sequential
num=5 sequential num=6 sequential num=7 sequential num=8 sequential num=9 expectedTotalNum=45</span></pre>
Now let's do the same in parallel, just by replacing <b>foreach</b> with <b>Parallel.ForEach</b>:<br /><pre><span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;"> //
And do it with the new Parallel Programming classes in .NET 4</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">int</span> totalNum <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> 0;
System.Threading.Parallel.ForEach(someInts, num =&gt; { Console.WriteLine(<span style="color: rgb(102, 102, 102); background-color: rgb(228, 228, 228); font-family: Courier New; font-size: 11px;">"parallel
num="</span><span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">+</span> num);
totalNum += num; }); Console.WriteLine(<span style="color: rgb(102, 102, 102); background-color: rgb(228, 228, 228); font-family: Courier New; font-size: 11px;">"totalNum="</span><span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">+</span> totalNum);</span><span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"></span></pre>
While the result is still the same because totalNum is 45 at the end of this loop,
we get there in a different way. As you can see this is a little bit confusing at
first because the adding does not happen sequentially anymore, but in parallel instead.
Also note that this output can change when you execute it again and can even be much
different on different platforms with different number of CPUs:<br /><pre><span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;">parallel
num=0 parallel num=2 parallel num=5 parallel num=7 parallel num=8 parallel num=9 parallel
num=6 parallel num=3 parallel num=4 parallel num=1 totalNum=45</span></pre>
Okay, good stuff so far, but you might not always have a foreach loop and you might
not want to wait for it to complete anyway. Maybe you just have some work tasks that
need to be executed, no matter in what order and you might not even care if they complete
their work right away or in a little bit. A method could just add some work that has
to be done and then return while the work tasks are executed in the background. This
is when you would have used the <b>Thread</b> or <b>ThreadPool</b> classes in the
past, which are great on their own, but you always have some setup code and it was
hard to test and you could not use them all over the place because setting up threads
is a costly operation and if your work is just few lines of code, it was always a
better idea to execute it right away. But fear no more, now you can just create new
tasks with the new <b>Task</b> class in the <b>System.Threading</b> namespace. This
is a much easier job and has many advantages because .NET 4.0 handles all the thread
creation for you, will reuse threads once they are completed with their task and all
this works in a very performant way. Setting up tasks is a little bit more work than
just executing Parallel.ForEach, but it allows much greater flexibility and you can
add more tasks from whereever you are. Tasks can even have children and you can have
a lot of complex code using all these tasks. Testing multi-threaded code is obviously
harder than just writing sequential code, but with all the great additions to the
IDE, it is now easier than ever with the new Parallel Tasks window and by checking
out the Parallel Stacks, which shows you all the running threads and were all the
task code is.<br /><br />
The following code will create 10 tasks and do the same thing as above, but with several
additions. To be able to wait for all the tasks to finish we will add all 10 tasks
to the allTasks list. We also have to make sure that our local foreach variable does
not change while we are executing tasks because the foreach loop will quickly create
all tasks, but might not execute them right away theirfore using num can cause problems.
Instead we just create a local copy of num and use that instead, which can't change
because we never increase it like we do with num. Finally we add some boring thread
sleeping to make it easier to debug this code and check out whats going on by adding
breakpoints. Without the sleep the code still works, but checking out the Parallel
Tasks and Parallel Stacks windows will most likely give us no results or only the
last few tasks that are still being executed at the end of the foreach loop because
the tasks are so simple and executed very quickly. We even wait a little after the
foreach to make sure all the tasks have been added and are being executed right now
or are scheduled (waiting for execution).<br /><pre><span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;"> //
And finally some tasks, yeah!</span> totalNum <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> 0;
var allTasks <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">new</span> List&lt;Task&gt;(); <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">foreach</span> (<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">int</span> num <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">in</span> someInts)
{ <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
We need a local variable for num because num itself can change</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
at the end of this loop before the task might even be executed!</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">int</span> numToBeAdded <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> num;
allTasks.Add(Task.Factory.StartNew(<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">delegate</span> {
totalNum += numToBeAdded; Console.WriteLine(<span style="color: rgb(102, 102, 102); background-color: rgb(228, 228, 228); font-family: Courier New; font-size: 11px;">"Adding
"</span><span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">+</span> numToBeAdded <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">+</span><span style="color: rgb(102, 102, 102); background-color: rgb(228, 228, 228); font-family: Courier New; font-size: 11px;">"
in task with id="</span><span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">+</span> Task.Current.Id); <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Wait a little for checking out the tasks in the new Tasks window in VS2010!</span> Thread.Sleep(1000);
})); } <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
foreach</span> Console.WriteLine(<span style="color: rgb(102, 102, 102); background-color: rgb(228, 228, 228); font-family: Courier New; font-size: 11px;">"Done
with foreach loop. Tasks might still be pending"</span>); <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Wait a little for all tasks to start</span> Thread.Sleep(100); Task.WaitAll(allTasks.ToArray()); <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
And finally return the result (45 again if everything worked)</span> Console.WriteLine(<span style="color: rgb(102, 102, 102); background-color: rgb(228, 228, 228); font-family: Courier New; font-size: 11px;">"totalNum="</span><span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">+</span> totalNum);</span></pre>
First of all the results again, which is 45 again. This only work with numToBeAdded,
if you use num instead it will sometimes give you different results because at the
time you execute a task num already might have changed, especially if you have more
tasks than CPUs used for execution and time consuming code like Console.Writeline
or even a Thread.Sleep is in there!<br /><pre><span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;">Adding
1 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">in</span> task
with id=1 Adding 7 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">in</span> task
with id=6 Adding 8 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">in</span> task
with id=7 Adding 6 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">in</span> task
with id=5 Adding 4 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">in</span> task
with id=3 Adding 3 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">in</span> task
with id=4 Done with <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">foreach</span> loop.
Tasks might still be pending Adding 9 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">in</span> task
with id=8 Adding 0 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">in</span> task
with id=10 Adding 5 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">in</span> task
with id=2 Adding 2 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">in</span> task
with id=9 totalNum=45</span></pre>
As you can see this even looks more confusing than the way Parallel.ForEach added
those numbers because while we might create those tasks sequentially (number 1-10)
it does not mean there are also executed in exactly that way. To make it easier to
check these things out there is the Parallel Tasks window, which shows the following
after starting all 10 tasks by adding a breakpoint after <b>Thread.Sleep(100)</b> just
before we wait for all tasks to complete:<br /><br /><img src="http://benjaminnitschke.com/content/binary/TasksInVS2010.png" border="0" /><br /><br />
Not only do we see all over our 10 tasks here, we also see right away that 8 of them
are currently being executed (because I have 8 CPUs with my hyper-threaded i7) and
all of them are waiting because of our stupid <b>Thread.Sleep(1000)</b> we added for
each of those tasks. A second later those tasks are done and the last 2 are also executed,
most likely with 2 thread ids already created earlier. You can click on each task
and see where it is currently executing in the source code and you can also check
out all the thread information in the normal Threads window. But even more useful
than the Parallel Tasks window is the Parallel Stacks, which shows how all this code
is related, which task or thread created which new task and so on:<br /><br /><img src="http://benjaminnitschke.com/content/binary/TaskStacksInVS2010.png" border="0" /><br /><br />
All good stuff. While I already have some ideas how to use this on some of my current
projects, I have not ported anything to .NET 4.0 / VS2010 yet because of the many
issues I have with the IDE (no addins, color theme not really working, I always have
to reset it when starting VS2010, also I don't like that the project and solution
formats have changed so I cannot easily switch back to VS2008, etc.). But hopefully
more and more addins will work for VS2010 and some of the issues are fixed, then it
will be great to use all this new .NET 4.0 stuff (dynamics, parallel extensions, MEF,
etc.).<br /><img width="0" height="0" src="http://benjaminnitschke.com/aggbug.ashx?id=c0188e30-be4c-4e3d-93f8-1f228d2f7f5c" /></div>
    </content>
  </entry>
  <entry>
    <title>Early Visual Studio 2010 experiences</title>
    <link rel="alternate" type="text/html" href="http://BenjaminNitschke.com/2009/05/18/EarlyVisualStudio2010Experiences.aspx" />
    <id>http://benjaminnitschke.com/PermaLink,guid,a4886e1d-6ed2-4913-9efd-f3f275c3af01.aspx</id>
    <published>2009-05-19T01:39:33.749+02:00</published>
    <updated>2009-05-19T02:53:52.07725+02:00</updated>
    <category term="All" label="All" scheme="http://benjaminnitschke.com/CategoryView,category,All.aspx" />
    <category term="Development" label="Development" scheme="http://benjaminnitschke.com/CategoryView,category,Development.aspx" />
    <category term="Game Development" label="Game Development" scheme="http://benjaminnitschke.com/CategoryView,category,Game%2BDevelopment.aspx" />
    <category term="Other" label="Other" scheme="http://benjaminnitschke.com/CategoryView,category,Other.aspx" />
    <category term="Reviews" label="Reviews" scheme="http://benjaminnitschke.com/CategoryView,category,Reviews.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <img src="http://www.baboo.com.br/absolutenm/articlefiles/33246-visual_studio_2010_logo.png" style="float: right; margin-left: 10px;" />VS2010
beta came out a few hours ago, installing it took way too long (over an hour, VS2008
takes less than 10 min for me) and it seems some addins don't install or just don't
work, but other than that everything else seems to work great:<br /><ul><li><a href="http://www.testdriven.net/">TestDriven.NET</a> provides an VS2010 option
and it will appear in Addins, but the Menu Items will not appear anywhere. Just use
keyboard shortcuts and everything still works :) .. at least it worked for a short
while (see below). Hopefully Jamie Cansdale fixes this soon because without TestDriven.NET
I can't really use VS2010 right now. MS provides its own unit testing framework, which
is implemented into VS2010 and even available in the Pro edition now (was only in
more advanced versions before), but I still don't like it. It does not output anything
to the console except exceptions; it is not possible to just start some Ad-Hoc unit
test and for all my functional tests it is also useless. For just "normal" unit test
projects VS test integration is quite ok, but I would suggest trying out NUnit or
xUnit together with TestDriven.NET, which is just more flexible, easier to use and
improves productivity IMO.<br /></li><li>
Completely unable to install any <a href="http://www.devexpress.com/Products/Visual_Studio_Add-in/Coding_Assistance/index.xml">CodeRush </a>version
(neither 2, 3, 9.1, Xpress), so I'm also unable to use my CR_Commenter :( hopefully
DevExpress provides a version soon, they always were very quick with early VS2005
and VS2008 support!</li><li>
Most other addins I tried also did not install or just do not appear anywhere (only
in VS2008)</li><li>
One of my own addins I wrote 2 years ago for VS2008 also does not appear, it probably
needs to be configured to appear in the VisualStudio/10 reg key!</li></ul>
Most annoying:<br /><ul><li>
Even though <a href="http://blogs.msdn.com/ricom/">Rico Mariani (the .NET performance
god)</a> is helping out the VS team to give VS2010 better performance, it currently
lags all over the place. I had 10 second delays in Options, Add References and Renaming
dialogs already. Seems to be always an issue with opening up stuff for the first time.
After a while everything seems to be fast, but I would not say this is faster than
VS2008 yet.</li><li>
Only tried this at my home PC till now, but everytime I close VS2010 I cannot open
it up again until I restart (or at least log off/log on) again, which is REALLY annoying.
I will just keep VS2010 open now all the time and hope it never crashes ^^ The start
splash-screen is also messed up and completely black. Maybe this is only on my home
PC because I tried to install so many addins, will try this tomorrow at work too.<br /><b>Update 2009-05-18</b>: I just found out what was causing this. Some addins tried
to load, but failed for some reasons and then the addin loading code locks up or whatever
and VS never finishes starting up (the process devenv.exe is still there, but you
just don't see any IDE window, they are never created). It seems to be related to
the <b>TestDriven.NET-2.21.2448</b> version, I also tried <b>TestDriven.NET-2.20.2438</b> -
same problem :( (<a href="http://weblogs.asp.net/nunitaddin/">Jamie Cansdale, the
creator of TestDriven.NET was also recently blogging about this</a>). Then I used
, which also already has VS2010 support and that seems to work fine (no menus, but
keyboard shortcuts work fine). <a href="http://weblogs.asp.net/nunitaddin/archive/2009/04/30/testdriven-net-2-21-now-includes-nunit-2-5-rc.aspx#comments">I
posted more details on Jamie's blog</a>!<br /></li></ul>
Every project I have opened, had to be converted to the new VS 10 format, which is
kinda stupid because it seems nothing has changed. All the code works just fine and
no changes were required. I will start using some .NET 4.0 features and test out stuff
in the next days, especially using Parallel Programming and MEF (Managed Extensibility
Framework). Probably will play around with the C# 4.0 dynamic keyword a bit also,
but can't think of anything yet where I would really need it. Maybe to talk easier
to IronPython or my own DLR language ..<br /><br />
Cool features:<br /><ul><li>
Start page is pretty good, easily customizable, but I will probably never see it as
I setup my VS to always load the last solution (like my Firefox ^^)</li><li>
It is easy to drag tabs around and move them to different screens. Finally I can use
some multi-monitoring.</li><li>
Old exported VS2008 settings also work just fine in VS2010, even coloring :) For some
strange reason the background color is always white when I start VS2010 for the first
time, then after going to options and closing it, it will be the correct color (black
for me).</li><li>
Overall the IDE is very nice and fits perfectly into my color theme. Its also a lot
easier to see whats going on, which tab is selected and positioning tool windows all
over the place is better than ever before.</li></ul><br />
Go check out VS2010 yourself, available on MSDN right now and on MS site on Wednesday
for everyone else.<br /><br /><p></p><img width="0" height="0" src="http://benjaminnitschke.com/aggbug.ashx?id=a4886e1d-6ed2-4913-9efd-f3f275c3af01" /></div>
    </content>
  </entry>
  <entry>
    <title>Most Recently Used Tab Tweak for Visual Studio</title>
    <link rel="alternate" type="text/html" href="http://BenjaminNitschke.com/2009/05/18/MostRecentlyUsedTabTweakForVisualStudio.aspx" />
    <id>http://benjaminnitschke.com/PermaLink,guid,24e96761-a364-4b70-aff0-151ac0957ae6.aspx</id>
    <published>2009-05-18T16:31:59.171+02:00</published>
    <updated>2009-05-19T01:56:04.186625+02:00</updated>
    <category term="All" label="All" scheme="http://benjaminnitschke.com/CategoryView,category,All.aspx" />
    <category term="Development" label="Development" scheme="http://benjaminnitschke.com/CategoryView,category,Development.aspx" />
    <category term="Fun" label="Fun" scheme="http://benjaminnitschke.com/CategoryView,category,Fun.aspx" />
    <category term="Game Development" label="Game Development" scheme="http://benjaminnitschke.com/CategoryView,category,Game%2BDevelopment.aspx" />
    <category term="Other" label="Other" scheme="http://benjaminnitschke.com/CategoryView,category,Other.aspx" />
    <category term="Programming" label="Programming" scheme="http://benjaminnitschke.com/CategoryView,category,Programming.aspx" />
    <category term="Reviews" label="Reviews" scheme="http://benjaminnitschke.com/CategoryView,category,Reviews.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <img src="http://www.baboo.com.br/absolutenm/articlefiles/33246-visual_studio_2010_logo.png" style="float: right; margin-left: 10px;" />While
I'm waiting for VS2010 beta today (refreshing blogs and MSDN every few minutes :D),
I just found out that you can have your Visual Studio Tabs be automatically ordered
by adding the following registry key in <b>HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0</b>:<br /><ul><li>
UseMRUDocOrdering: 1 (DWORD)</li></ul>
Now when you select any tab in Visual Studio it will automatically move to the very
front thus keeping your recent documents at the start. It is kinda weird at first,
but it seems to be a very useful feature. I like it already :)<br /><br /><img src="http://benjaminnitschke.com/content/binary/VSMoveMRUTab.png" border="0" /><br /><br />
In case you don't want to create the registry key yourself and want me to help you
out modifying your registry (always a safe idea), just execute this file to do the
job:<br /><p></p><ul><li><a href="http://benjaminnitschke.com/content/binary/VS9UseMRUDocOrdering.reg">VS9UseMRUDocOrdering.reg
(.26 KB)</a></li><li><b>Update</b>: Does not seem to work yet in VS2010, maybe use /10.0_Config key instead?: <a href="http://benjaminnitschke.com/content/binary/VS10UseMRUDocOrdering.reg">VS10UseMRUDocOrdering.reg
(.26 KB)</a></li></ul><br />
PS: Since my brother is running a <a href="http://en.wikipedia.org/wiki/Tor_%28anonymity_network%29">TOR
exit node server</a> Google does not like when I do searches anymore because it thinks
I search too much stuff now and might be infected with viruses and trojans (yeah,
sure ..). I could use Google Custom Search sites like <a href="http://blackle.com/">Blackle.com</a>,
which return the exact same results as Google, but for now I'm trying out Yahoo once
again (was using it a lot almost 15 years ago, when there was no Google). Sometimes
Yahoo is stupid and does not give good answers, e.g. searching for "year yahoo was
launched" gives you random answers on Yahoo, but google returns the Yahoo Questions
link with the correct answer as the first result, wtf? 
<br /><br />
However, most of the time you do not get stupid <a href="http://en.wikipedia.org/wiki/Search_engine_optimization">SEO</a> optimized
search results and totally messed up product searches you get when using Google or
Live Search. As an Microsoft MVP I also get asked a lot why I would not use Live Search
and Microsoft is constantly trying to get more people (and MVPs) using Live Search,
but the results are very close to Google most of the time anyway and the interface
is just strange if you are used to Google for 10 years (the English Live Search is
actually nice with a new image every day, but the German version is totally messed
up, just white boxes??). Yahoo at least gives different results, which are sometimes
better, sometimes worse .. Maybe we all should switch search engines from time to
time, its really stupid Google has 95% market share here in Germany almost and it
returns so crappy results so often (finding drivers has become 10 times as hard in
the last years, searching files or torrents is impossible, because you only get SEO
sites, no real results, product searches are totally messed up, Google groups is not
used much anymore, etc.). Okay, enough ranting about search engines .. time to refresh
MSDN again.<a href="http://benjaminnitschke.com/content/binary/VS10UseMRUDocOrdering.reg"></a><img width="0" height="0" src="http://benjaminnitschke.com/aggbug.ashx?id=24e96761-a364-4b70-aff0-151ac0957ae6" /></div>
    </content>
  </entry>
  <entry>
    <title>VS2010 coming soon .. and a little tool: KillEmptyDirectories</title>
    <link rel="alternate" type="text/html" href="http://BenjaminNitschke.com/2009/05/14/VS2010ComingSoonAndALittleToolKillEmptyDirectories.aspx" />
    <id>http://benjaminnitschke.com/PermaLink,guid,fab86f86-f514-463c-8f21-f26f35c98f13.aspx</id>
    <published>2009-05-14T16:17:28.612+02:00</published>
    <updated>2009-05-14T16:17:28.612+02:00</updated>
    <category term="All" label="All" scheme="http://benjaminnitschke.com/CategoryView,category,All.aspx" />
    <category term="Development" label="Development" scheme="http://benjaminnitschke.com/CategoryView,category,Development.aspx" />
    <category term="Fun" label="Fun" scheme="http://benjaminnitschke.com/CategoryView,category,Fun.aspx" />
    <category term="Other" label="Other" scheme="http://benjaminnitschke.com/CategoryView,category,Other.aspx" />
    <category term="Programming" label="Programming" scheme="http://benjaminnitschke.com/CategoryView,category,Programming.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <img src="http://benjaminnitschke.com/content/binary/KillEmptyDirectories.png" style="margin-left: 10px; float: right;" border="0" />
        <a href="http://blogs.zdnet.com/microsoft/?p=2769">Visual
Studio 2010 beta is apparently coming soon.</a> Since I used VS2005 beta and VS2008
beta when they came out, I will be an early adopter once again. I really want to use
the cool <a href="http://msdn.microsoft.com/en-us/concurrency/default.aspx">Parallel
APIs</a> in VS2010 and <a href="http://video.google.de/videosearch?q=c%23+4.0">C#
4.0 dynamic stuff</a> :) 
<br /><br />
Another topic: I try to synchronize several of my servers at different locations every
day. This way it does not matter where I download or create a file, I still can use
it the next day wherever I am (home, work, different work ^^). I use <a href="http://www.2brightsparks.com/syncback/sbse.html">SyncBackSE</a> for
that job, great tool, but the problem with it is that on slow internet connections
(e.g. slow DSL at work right now) it takes forever to even scan the directories. Its
about 30000 directories that have to be synchronized and this takes a lot of hours,
especially if the internet connection is already doing something else. Obviously uploading
and downloading a few GB can also take a lot of time, but in 95% of the cases nothing
or just a few MB change every day.<br /><br />
Because searching sub directories is so slow I tried to make it faster by removing
directories when not necessary (just compressing 100 directories into a zip file,
removing empty directories or old files, etc.). But this is obviously a lot of work
for this many directories and I can easily overlook that in sub directory 3592 there
is 1500 empty folders of some crap from some years ago no one will ever need again.
For this reason I quickly wrote this little tool called KillEmptyDirectories, you
can see a picture on the right! It only took me an hour to write, so there is no rocket
science here and it is very straight forward. I did not even unit test it, I just
tested it by executing on several directories. It also can remove hidden and read-only
files by changing the file attributes (otherwise File.Delete will always throw UnauthorizedAccessException).
I tested it on around 30000 directories and was able to kill around 8000 of those
(deleting a lot of old stuff) ^^ with some additional compression of unused older
directories I was able to get it down to around 3000 directories (from 30000), so
the scanning process is now about 10 times faster.<br /><br />
If you want to try it out, you can download it here. But use with care, you can obviously
kill directories with it and by using the "Always kill these directories" options
you can even delete directories with files in it. An extra confirmation message will
appear if you try to use that feature. 
<ul><li><a href="http://benjaminnitschke.com/content/binary/KillEmptyDirectories.exe">KillEmptyDirectories.exe
(12.5 KB)</a></li><li><a href="http://benjaminnitschke.com/content/binary/KillEmptyDirectories.zip">KillEmptyDirectories.zip
(11.83 KB)</a></li></ul>
And this is the main function that does all the directory killing:<br /><pre><span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
&lt;summary&gt;</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
Recursively kill directories, will be called as many times as we have</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
sub directories (can be many thousand times). Will always go through</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
all subdirectories first in case we can remove them, which makes it</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
much easier to delete directories with just empty sub directories.</span><span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">///
&lt;/summary&gt;</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">private</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">int</span> RecursivelyKillDirectories(<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">string</span> directory,
    <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">string</span>[]
includeFiles, <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">string</span>[]
alwaysKillDirectories,     <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">bool</span> alwaysKillThisDirectory)
{     <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">int</span> directoriesKilled <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> 0;
    <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">string</span>[]
subDirectories <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> Directory.GetDirectories(directory);
    <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Only delete this directory if there are no useful files in here!</span>     <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Note: GetFileName will give us the last part of the directory! </span>     <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">if</span> (alwaysKillDirectories.Contains(Path.GetFileName(directory)))
        alwaysKillThisDirectory <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span><span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">true</span>;
    <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Handle subdirectories always first (maybe we can kill them too)</span>     <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">foreach</span> (<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">string</span> subDir <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">in</span> subDirectories)
        directoriesKilled += RecursivelyKillDirectories(subDir,
includeFiles,             alwaysKillDirectories,
alwaysKillThisDirectory);     <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Get all files here and count how many of those we can ignore</span>     <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">string</span>[]
files <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> Directory.GetFiles(directory);
    <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">int</span> ignoreFileCount <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> 0;
    <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">foreach</span> (<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">string</span> file <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">in</span> files)
        <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">if</span> (includeFiles.Contains(Path.GetFileName(file)))
            ignoreFileCount++;
    <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Only found ignored files (or no files at all) or do we want to kill</span>     <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
this directory anyway?</span>     <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">if</span> (files.Length
== ignoreFileCount ||         alwaysKillThisDirectory)
    {         <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Check again if we don't have any sub directories left here</span>         <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Maybe the subdirectories above were already killed now!</span>         subDirectories <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> Directory.GetDirectories(directory);
        <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">if</span> (subDirectories.Length
== 0 ||             alwaysKillThisDirectory)
        {             <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">try</span>             {
                <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Kill all files in it (only ignored files anyway)</span>                 <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">foreach</span> (<span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">string</span> file <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">in</span> files)
                {
                    <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Make sure we can delete hidden and readonly files</span>                     FileAttributes
attributes <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> File.GetAttributes(file);
                    <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">if</span> ((attributes
&amp; FileAttributes.ReadOnly) !<span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> 0
||                         (attributes
&amp; FileAttributes.Hidden) !<span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">=</span> 0)
                        File.SetAttributes(file,
FileAttributes.Normal);                     File.Delete(file);
                } <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
foreach</span>                 Directory.Delete(directory);
                <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
We killed something, yeah</span>                 directoriesKilled++;
            } <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
try</span>             <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">catch</span> (Exception
ex)             {                 MessageBox.Show(<span style="color: rgb(102, 102, 102); background-color: rgb(228, 228, 228); font-family: Courier New; font-size: 11px;">"Failed
to delete "</span><span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">+</span> directory <span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">+</span><span style="color: rgb(102, 102, 102); background-color: rgb(228, 228, 228); font-family: Courier New; font-size: 11px;">":
"</span><span style="color: Red; background-color: transparent; font-family: Courier New; font-size: 11px;">+</span>                     ex.ToString());
            } <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
catch</span>         } <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
if</span>     } <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
if</span>     <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
Most of the time nothing was killed</span>     <span style="color: Blue; background-color: transparent; font-family: Courier New; font-size: 11px;">return</span> directoriesKilled;
} <span style="color: Green; background-color: transparent; font-family: Courier New; font-size: 11px;">//
RecursivelyKillDirectories(directory, includeFiles)</span></span></pre><br /><img width="0" height="0" src="http://benjaminnitschke.com/aggbug.ashx?id=fab86f86-f514-463c-8f21-f26f35c98f13" /></div>
    </content>
  </entry>
  <entry>
    <title>Moved a lot of websites today</title>
    <link rel="alternate" type="text/html" href="http://BenjaminNitschke.com/2009/05/11/MovedALotOfWebsitesToday.aspx" />
    <id>http://benjaminnitschke.com/PermaLink,guid,3dfce7e4-4b43-4af5-84d7-7529bcb58819.aspx</id>
    <published>2009-05-11T22:37:28.737+02:00</published>
    <updated>2009-05-11T22:37:28.737+02:00</updated>
    <category term="All" label="All" scheme="http://benjaminnitschke.com/CategoryView,category,All.aspx" />
    <category term="Development" label="Development" scheme="http://benjaminnitschke.com/CategoryView,category,Development.aspx" />
    <category term="DLR" label="DLR" scheme="http://benjaminnitschke.com/CategoryView,category,DLR.aspx" />
    <category term="iPhone" label="iPhone" scheme="http://benjaminnitschke.com/CategoryView,category,iPhone.aspx" />
    <category term="Programming" label="Programming" scheme="http://benjaminnitschke.com/CategoryView,category,Programming.aspx" />
    <category term="Reviews" label="Reviews" scheme="http://benjaminnitschke.com/CategoryView,category,Reviews.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">Hi Guys, sorry for not updating much here
last week. I have been quite busy with all the iPhone projects going on (at <a href="http://mobile-bits.de">mobile-bits.de</a>)
and of course our big game project at exDream (btw: we made a new cool team photo
today with 15 people from exDream, it will be up soon at <a href="http://www.exdream.com/company.html">http://www.exdream.com/company.html</a>).
I also worked a lot on the DLR language I started a month ago and I'm quite happy
with the current state, everything works very well right now and the very basic language
functionality (only some very simple commands) is already there and very fast and
easy to use. I will improve the language hopefully this month to a useable state,
but it will probably take a long time (maybe a year) until everything is done for
this language. More on that in a few weeks maybe ..<br /><br />
Because we also lost one of our main website servers at exDream last week because
the old publisher didn't want to pay for it anymore, I had to move a lot of websites
to a much slower server today (sites for ArenaWars, Rocket Commander, Mods, EuroVernichter,
Xna Racing Game, other Xna Projects, some internal sites, etc.). We will get a better
internet connection in the next few weeks for that, but for now it is very slow and
not very enjoyable to surf on there. The most annoying thing while moving all the
wwwroot directories to the new slow server was the fact that the ACL permissions were
totally screwed up. I had this happen to me before, but today it was very annoying.
Dunno exactly why this happens, but it seems when you extract files into wwwroot your
existing directory permissions are more or less ignored. This only happend to me on
that Win2003 server, I tried reproducing the same thing with Windows 7 at home, but
directory permissions are correctly set when extracting more sub directories there.
I could just set those permissions again for some folders, which is kinda strange
because the base directory already had the permissions for the exact same user. But
for other directories I could just see that the web user permissions are set (so I
could not add them again), but still once accessing the website I would just get:<br /><br /><b>HTTP Error 401 401.3 Unauthorized: Unauthorized due to ACL on resource</b><br /><br />
or this other error once I allowed my user to access the aspx files, which is pretty
confusing too:<br /><br /><b><font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">Parser Error
Message: An error occurred loading a configuration file: Failed to start monitoring
changes to 'C:\inetpub\wwwroot\dummywebapp\web.config' because access is denied.</font></b><br /><br />
Since I had set the ACL permissions and they looked correctly I was very confused
and tried a lot of other stuff like changing the Web Application Pool, recreating
the web apps, using all kinds of different users for those web apps, etc. But all
that did not really help. Only after I just made sure all permissions for all files
plus all directories for this web app were set correctly, it finally worked. I would
say this problem should be fixed and the error messages should be better, but in Windows
2008 and Windows 7 it is already so much better, I was easily able to extract the
exact same .rar file on my Windows 7 and everything just worked as expected as opposed
to the Win2003 server ..<br /><p></p><img width="0" height="0" src="http://benjaminnitschke.com/aggbug.ashx?id=3dfce7e4-4b43-4af5-84d7-7529bcb58819" /></div>
    </content>
  </entry>
  <entry>
    <title>Visual Studio compile times on different disk drives and SSDs</title>
    <link rel="alternate" type="text/html" href="http://BenjaminNitschke.com/2009/05/03/VisualStudioCompileTimesOnDifferentDiskDrivesAndSSDs.aspx" />
    <id>http://benjaminnitschke.com/PermaLink,guid,3feb4469-ca93-410b-b06e-fd2c33b9ce9c.aspx</id>
    <published>2009-05-03T22:39:31.274+02:00</published>
    <updated>2009-05-03T23:13:24.602625+02:00</updated>
    <category term="All" label="All" scheme="http://benjaminnitschke.com/CategoryView,category,All.aspx" />
    <category term="Development" label="Development" scheme="http://benjaminnitschke.com/CategoryView,category,Development.aspx" />
    <category term="DLR" label="DLR" scheme="http://benjaminnitschke.com/CategoryView,category,DLR.aspx" />
    <category term="Fun" label="Fun" scheme="http://benjaminnitschke.com/CategoryView,category,Fun.aspx" />
    <category term="Other" label="Other" scheme="http://benjaminnitschke.com/CategoryView,category,Other.aspx" />
    <category term="Programming" label="Programming" scheme="http://benjaminnitschke.com/CategoryView,category,Programming.aspx" />
    <category term="Reviews" label="Reviews" scheme="http://benjaminnitschke.com/CategoryView,category,Reviews.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <img src="http://benjaminnitschke.com/content/binary/CompileTimes1Small.png" style="margin-left: 10px; float: right;" /> This
week I wanted to test using a Ramdisk (Ramdrive using just your main RAM) for compiling
Visual Studio projects. Playing games or doing other disk intensive stuff would be
great too, but most games are just way too big and smaller older games load pretty
quick anyway. 
<br /><br />
While copying files and benchmarking a Ramdisk is incredibly fast with 4-6 GB/s (theoretically
my ram should almost reach 10 GB/s, but well that's already way fast enough). Since
I use Windows 7 RC since Friday when it came out on MSDN I had a lot of problems finding
Ramdisk programs that actually work and do not crash every 2 seconds. Currently I
use <a href="http://www.cenatek.com/">RamdiskVE by Cenatek</a>, but the company does
not exist anymore because it was bought by <a href="http://www.dataram.com/">Dataram</a>,
which provides RamDisk on their own now. I was however unable to run Dataram's Ramdisk
on Windows 7, it constantly crashes and has also many other limitations. <a href="http://www.ocztechnologyforum.com/forum/showthread.php?t=49955">Here
is also a discussion on the Ocz Forum about Ramdisks if you want to check out some
of the products for yourself.</a><br /><br />
The Ramdisk is also useful for Temp files, IE Temp files and other Scratch Disk functionality
(e.g. Photoshop), but you should only use those for programs to stupid to use more
of your Ram (e.g. because a program is 32bit and you have way more memory in your
64bit system). It also will increase the lifetime of your hard disks or SSDs in case
you write a lot of stuff on your Ramdisk because the Ramdisk will only be loaded once
at start up and saved once when shutting down your PC. But you should be aware that
in case of a crash, you will obviously lose all the changed content on your Ramdisk. 
<br /><br />
For testing I used my new rig with a i7 920 D0 CPU and 12 GB ram, which I overclocked
from 2.66Ghz to ~4.4Ghz. This is pretty fast, for example the <a href="http://benjaminnitschke.com/2009/04/22/ForVsForeachPerformance.aspx">For
vs Foreach Performance application</a> from the last blog post is twice as fast as
my 6600 CPU from last week (all times cut in half basically, which is more than I
expected). 
<br /><br />
I also tested quite a lot of hard disks and SSDs, which was kinda interesting because
I learned that it does not matter if you mix totally different hard drives into a
Raid 0 as long both are similarly fast. For example I tried using 2 older 160 GB disks
in a Raid 0 and was only able to get around 60mb/s, which is slower than a single
Raptor hard disk, but putting a new fast Samsung 250 GB and a Raptor 150 GB together
into a Raid 0 gave me around 160mb/s. To keep things crazy I also added another Intel
x25-M SSD to the one I already had and put them into a Raid 0 too, which is amazingly
fast (&gt;450mb/s). For highest speed you should always make sure to Enable Write-Through
Cache on the Raid controller (in my case a Intel software raid with the ICH10R controller)
AND to enable write caching and finally turn off the Windows write-cache buffer flushing
(both can be found in hardware-&gt;disk-&gt;policies) for your disks. Please note
that I do not care about data redundancy since everything I do is saved on a server
with a Raid 5 anyway. If one of my Raid 0s would fail it would just be annoying to
reinstall everything, but I would not lose any of my work or files. 
<br /><br />
So lets see how much benefit you actually get from compiling several different projects
on a fast PC with those different disk configurations. The compile time is obviously
heavily dependent on your CPU speed, but I tried to measure how much the total time
changes just by using different disks. The following example shows a full recompile
of one of my bigger solutions:<br /><br /><img src="http://benjaminnitschke.com/content/binary/CompileTimes2.png" /><br /><br />
All compiles are full recompiles from scratch (no immediate files yet). For testing
the <a href="http://dlr.codeplex.com/SourceControl/ListDownloadableCommits.aspx">DLR
(change set 23173, about 25 MB in 20 C# projects)</a>, one of my solutions with 5
C# projects, 1 C++ project (~43 MB) and finally the <a href="http://www.fileshack.com/file.x?fid=7547">good
old Quake3 v1.32 source code</a> (5 MB of c code). Since I do not compile much C++
at home I was to lazy to test bigger C++ projects, but I would guess most times would
just scale and the conclusion would be the same. 
<br /><br />
4 Tests were executed: 
<ul><li>
Loading Visual Studio 2008 and opening the each solution (average time), 
</li><li>
Compiling the DLR and running the ToyConsole sample. This will generate around 25
MB of files (17 MB of those are .pdb), ~60 files. 
</li><li>
Compiling and running my own solution (~43 MB, 5 C# projects, 1 C++ project). Generates
~47 MB (lots of copying, &gt;300 files). 
</li><li>
and finally compiling Quake3 (~500 c files). 
</li></ul>
Most of the tests were done several times, but I stopped all of them with this <a href="http://www.highspheres.com/products/pc_chrono/">cool
freeware stopwatch called PC Chrono</a>. Keep that in mind, the results will not be
very accurate. Each test was done on the following drives: 
<ul><li>
Good old Raptor Hdd (one of the fastest desktop disks you can get, almost empty for
better testing) 
</li><li>
Single Ocz Ssd with 150mb/s read/write (remember that I complained about the <a href="http://benjaminnitschke.com/2009/02/25/WhyCheapSSDSucksForVisualStudio.aspx">bad
JMicron controller on it way back in February</a>) 
</li><li>
Intel X25-M Ssd Raid 0 Array with 450mb/s read, 140mb/s write (nice ^^) 
</li><li>
And finally the Ramdisk with 4500mb/s read+write (at least) 
</li></ul><a href="http://benjaminnitschke.com/2009/02/25/WhyCheapSSDSucksForVisualStudio.aspx"><br /><br /></a><table border="1"><tbody><tr><td>
Disk/Compile times</td><td>
Loading VS+solution 
</td><td>
Compiling DLR+start ToyConsole</td><td>
Compile&amp;Run own solution</td><td>
Quake3 Compile</td></tr><tr><td>
Good old Raptor Hdd</td><td>
3.75s</td><td>
9.01s</td><td>
2.95s</td><td>
17.57s</td></tr><tr><td>
Single Ocz Ssd 150mb/s</td><td>
2.96s</td><td>
10.47s</td><td>
3.24s</td><td>
22.67s</td></tr><tr><td>
Intel X25-M Sdd Raid 0 Array</td><td>
1.26s</td><td>
7.79s</td><td>
2.88s</td><td>
17.53s</td></tr><tr><td>
Ramdisk with 4500mb/s</td><td>
1.43s</td><td>
7.70s</td><td>
2.51s</td><td>
15.89s</td></tr></tbody></table><br />
With this data the following fancy graph was build. It shows that there are some improvements
in several areas, but as long as you are not limited by your disk speed or IOs (amount
of input/output operations you can do per second), you do not get much benefit from
way faster drives (the ram disk is at least 45 times faster than the hard disk I used,
but the performance improvement is maybe 10 or 20%):<br /><br /><img src="http://benjaminnitschke.com/content/binary/CompileTimes1.png" /><br /><br />
Since it is so much fun using the Intel SSD Raid 0, I will keep using it. It is also
big enough to use for all my programs and games. For example launching Left 4 Dead
levels is 2-3 times faster than before. But I will probably not continue to use the
Ramdisk for compiling. I can just keep everything on the SSD raid, which will not
run out of space as soon as my small Ramdisk. Maybe when I do some file-intensive
stuff in the future I will try out the Ramdisk idea again.<br /><br />
For now my advise for getting the fastest Visual Studio experience would be getting
the fastest CPU you can (i7 920 is pretty nice, overclocking is important too, without
it my tests would be 40% slower, 8 hyper-threads might also be useful in the future),
enough Ram (4-6 GB), a fast disk like the Intel X25-M and of course using Windows
7 (since everything responses much faster). Then you can really have a lot of fun
compiling big and small projects, and playing games, and doing other stuff on your
PC.<br /><br />
BTW: <a href="http://netfreak.de">My brother also just blogged about Windows 7 RC
and using RamdiskVE</a>. He also noticed that the network layer in Windows 7 is way
faster than before in Windows Vista for him, in Vista he had 30-60mb/s max, now it
is like 110mb/s copying files over the network:<br /><br /><img src="http://benjaminnitschke.com/content/binary/Windows_7_durchsatz.png" border="0" /><img width="0" height="0" src="http://benjaminnitschke.com/aggbug.ashx?id=3feb4469-ca93-410b-b06e-fd2c33b9ce9c" /></div>
    </content>
  </entry>
</feed>