October 2005 - Posts

I knew there was something special with October 28th when I woke up this morning. Just couldn't remember what. Thanks to Bink to turn on the light in my head's built-in calendar. See it over here: http://bink.nu/Article5157.bink.Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

A couple of days ago I posted the final build number of .NET Framework v2.0 and VS2005 (starts with 8. instead of 2. but for the rest it's exactly the same). Unfortunately, a pretty heavy spam cleaning script on my database deleted some of my latest posts. Luckily SQL Server's backup functionality saved my blog except for a couple of posts, including the version numbering one. So here it is:

The official version number of .NET v2.0 is 2.0.50727.42, VS2005's one is 8.0.50727.42. You might ask yourself what the hell the number stands for. The major and minor are pretty clear I think. The rest isn't that straightforward. AFAIK the story goes back to the early days of .NET v2.0 development where the format YMMDD was chosen for version numbering. So, the build points in the direction of July 27 2005, which is the point in time the final development push was initiated. From that point on, the last number increments every build with +1. We're now three months further, which indicates there were 14 builds per month, or 3-4 builds every week.

I just ran into an interesting post on MSDN Blogs about this too: http://blogs.msdn.com/quanto/archive/2005/10/27/486052.aspx. The "Project 42" code name mentioned therein is new to me. Happy coincidence? Jason Zander has another post on the topic on http://blogs.msdn.com/jasonz/archive/2005/10/27/485922.aspx about team t-shirts decorated with the magic number 42.

So, after v1.0.3705 and v1.1.4322 comes v2.0.50727.42. Start memorizing the number now :-).

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Finally this massive release is a fact! MSDN subscribers can download the bits of .NET Framework v2.0, Visual Studio 2005 and SQL Server 2005 now from MSDN Subscriptions:

For the .NET Framework SDK and Redist lovers, find the links beneath:

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

You can find the list with most popular blog posts from my blog on http://bartdesmet.net/topblogposts.aspx?top=20 (replace the top count number with 10, 20, 50, 100 to get other stats). If you didn't read those top posts, shame on you :p.

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Wow, just ran into this. I guess the more serious post will get another (albeit short) delay :-). Watch this "We share your pain" video of Microsoft (no warranties made whatsoever, read the disclaimer at the begin).Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

The last couple of days, Larry Osterman has posted three posts on easter eggs:

I thought this is a golden opportunity to share my favorite easter egg in a recent Microsoft product:

  1. Install Virtual PC 2004 on your machine.
  2. Create a new virtual machine and install Windows (XP/2003) in the guest.
  3. On the guest OS install Microsoft Visual Studio .NET 2003 with all the stuff included.
  4. Now install the Pocket PC 2003 SDK including the emulators.
  5. Time to create a new smart device project for Pocket PC.
  6. Compile and start the debugger. It will bring up the emulator which will say: "Emulator for Windows CE will not run within another copy of Emulator for Windows CE. You just had to try, didn't you?"

The easter egg disappeared in Visual Studio 2005. Read: the bug was fixed. This really was a bug, basically the emulator and the Virtual PC environment had some shared code which made the emulator in the guest think it was running inside another instance of the emulator. Funny however. Here's a screenshot:

Notice my quote in my yesterday post "enough stupid content posts for today". I kept my promise as I'm writing this on Sunday :p. However, next post will be more interesting again.

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

It's possible to create a print screen image of the taskbar? Click on it and press Alt-PrintScreen. Just discovered this by mistake. It makes sense but I was a little amazed to see this appear instead of the intended window. Nevertheless, enough stupid content posts for today :-)Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Download time :-)

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

I intended to blog about this long time ago, but the idea died while sitting in the long long blog idea queue. Now it's here: a post about System.Reflection.Emit. Stimulans: a session on writing a managed compiler in one hour on PDC 05. Let's kick off.

 

What is it?

System.Reflection.Emit is a namespace that allows assemblies to be created from within managed code applications. Once you've created the assembly dynamically it can be called immediately or it can be saved to disk to be executed later on. In fact, you can use System.Reflection.Emit for two big scenarios:

  • compiling stuff to managed code and call that code at runtime of your application (e.g. give the user the opportunity to write logic statements or code statement - or whatever you might think of - and compile and execute it)
  • create a managed code compiler that accepts a source code file for language ABC and spits out an assembly containing the corresponding IL code

Noticed the word IL? Yes, there we go again :-).

 

Hello world +o(

Sick and tired of those hello world samples? I do, so let's create a "Yow dude" example instead (pretending to be in a funny mood).

Manual compilation

Open up a Visual Studio command prompt (e.g. VS .NET 2003, will work with version 2005 too). Write and compile a one line application as follows:

>echo class Yow { public static void Main() { System.Console.WriteLine("Yow dude"); } } > yow.cs

>csc yow.cs
Microsoft (R) Visual C# .NET Compiler version 7.10.6310.4
for Microsoft (R) .NET Framework version 1.1.4322
Copyright (C) Microsoft Corporation 2001-2002. All rights reserved.

Execute yow.exe if you doubt about the results of this application (if so, I'd recommend to quit your browser now and come back next year :o). Now ildasm.exe yow.exe and take a look at Yow::Main's definition. It should not just look like but be completely identical to the next piece of IL:

.method public hidebysig static void  Main() cil managed
{
  .entrypoint
  // Code size       11 (0xb)
  .maxstack  1
  IL_0000:  ldstr      "Yow dude"
  IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000a:  ret
} // end of method Yow::Main

 

Dynamic compilation

Now we're going to write an application that creates the same tremendously useful (*kuch*) functionality but dynamically using Reflection.Emit. Open up your favorite development environment to create a console application and compile it. One thing missing in the previous fase? Yes, the code. So here it is:

using System; using System.Reflection; using System.Reflection.Emit;

 class ReflectSample
 {
  static void Main(string[] args)
  {
   AssemblyName name = new AssemblyName();
   name.Name = "YowAgain";

   AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave);
   ModuleBuilder module = assembly.DefineDynamicModule("YowModule", "yowagain.exe");
   
   TypeBuilder someClass= module.DefineType("Yow", TypeAttributes.Public | TypeAttributes.Class);
   MethodBuilder main = someClass.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, typeof(void), new Type[] {});

   ILGenerator ilgen = main.GetILGenerator();
   ilgen.Emit(OpCodes.Ldstr, "Yow dude");
   ilgen.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
   ilgen.Emit(OpCodes.Ret);

   assembly.SetEntryPoint(someClass.CreateType().GetMethod("Main"), PEFileKinds.ConsoleApplication);
   assembly.Save(module.Name);

   AppDomain.CurrentDomain.ExecuteAssembly(module.Name);
  }
 }

Line by line overview? Here it comes (blank and curly-brace-only lines were skipped):

  1. Some namespace imports. Mandatory plumbing to boost readability of what comes next.
  2. Our class.
  3. Our entrypoint.
  4. Creating an AssemblyName instance for the assembly we're going to create.
  5. and give it a meaningful name.
  6. Next, we need something to build an assembly dynamically, which the System.Reflection.Emit team decided to call - for unclear reasons - AssemblyBuilder. To create it and execute it later on, it has to be created through the (current) application domain. We also indicate the result has to be saved and executed.
  7. Similarly, a module - that will be acting as part of the assembly - needs to be created. Straightforward chaining to the AssemblyBuilder instance encountered above.
  8. Modules contain types. Chain again, this time with a TypeBuilder. The rest of the line should read like a boring novel you can find in the local library: "define a public class type called Yow".
  9. Types contain methods. Or what predictability means in the context of Reflection.Emit: "define a public static method called Main that returns void and takes no arguments".
  10. Woohoo, ILGenerator, that sounds promising. This is where the real work is done. For the Main method, a utility class is instantiated to write the code for the method dynamically.
  11. See our IL sample, line IL_0000.
  12. See our IL sample, line IL_0005. Extra parameters extract MethodInfo through reflection (i.e. getting method invocation information for the overload of System.Console::WriteLine with one string parameter).
  13. See our IL sample, line IL_000a.
  14. Exciting things are said and done. The entry-point is set on the assembly to point to our Main method we defined above. Notice that reflection is used in here, which indicates the code (type) is "loaded" already and metadata for it is available.
  15. The assembly is saved to disk.
  16. Finally, we also decide to run it at this very moment. As you can see, the code you've created is in the current assembly domain (see line 6 too), which also means it can't be unloaded without unloading the default app domain (and therefore exiting the process).

Run. "Yow dude" should appear and a file yow_dynamic.exe should be created. Finally, the IL looks like this:

.method public hidebysig static void  Main() cil managed
{
  .entrypoint
  // Code size       11 (0xb)
  .maxstack  1
  IL_0000:  ldstr      "Yow dude"
  IL_0005:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000a:  ret
} // end of method Yow::Main

Exactly the same as the result of our manual development and compilation earlier. Certainly worth to look further at System.Reflection.Emit (tip: don't try to understand all of the OpCodes that are available, start from an existing piece of IL-code).

Have fun!

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Today I discovered a pretty nice keystroke I wasn't aware of. As the matter in fact, I'm a huuuuuuuuge keystroke fan trying to eliminate any mouse interaction whatsoever to boost productivity :d. Sometimes this results in unexpected behavior however, for instance sending a nudge in MSN 7 to a buddy because you missed one ALT-TAB while navigating to Internet Explorer, therefore arriving on a MSN conversation window and pressing ALT-D which does not put you in the address bar of IE as intended but sends a nudge in MSN :o.

Now the more serious stuff: CTRL-BACKSPACE seems to remove characters in front of your cursor word by word. Pressing CTRL-BACKSPACE over here | 2 times would erase the words "over here". A big replacement (read: keystroke saver) for two CTRL-SHIFT-LEFT ARROW's + DEL.

In an analogous fashion you can use CTRL-DELETE to delete words in the other direction.

This will be another killer keystroke when doing demos if I get used to it :-). Another one I blogged about earlier is "The quick brown fox jumps over the lazy dog"-generating rand-function in Word which is the ideal tool to junk strings (see "Lorem Ipsum Dolor Sit Amet" and "The quick brown fox jumps over the lazy dog" explained (or: cool KB Articles)...).

To conclude, let's mention CTRL-SHIFT-ESCAPE to open up the task manager in Windows (without going through CTRL-ALT-DEL, ALT-T or WIN-R, taskmgr, ENTER).

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

More Posts Next page »