nLite - Pimping up your Windows Installation

Today, I found a great tool: nLite. I wanted to slipstream the SP2 into my Windows Installation and I was searching for a tool that would do it for me when I discovered nLite.

Requirements

You need:

  • A Windows CD (kinda obvious)
  • The Service Pack 2
  • All hotfixes
  • Drivers for your hardware, extracted on disk
  • A CD burner capable of burning ISOs
  • The .NET Framework

Process

nLite is straightforward to use - just follow the wizard. The cool stuff about it is that it allows you to add your own drivers to the CD and hotfixes. If you search the web you'll find so-called update packages where you have 30-40 hotfixes bundled. Now, you have a clean and simple way to integrate them into your Windows CD so there is no need to install them afterwards. nLite worked out-of-the-box here and it took me maybe 30 minutes to include SP2, 30 hotfixes, my graphics cards driver, create an ISO (that's yet another great future that is built-in) and burn it. Excellent software!

Windows Media Player madness

Recently, I tried to write a simple tool using C#/.NET Framework that would allow me to gather information about movie files. As I wanted to be able to get the size, format and length of every movie file that WMP can open, I decided to use its SDK. Read on to see why this is not as easy as it sounds.

Step 0 - Preparation

I downloaded the WMP 10 SDK, including all sample files and I read the documentation :)

Step I - The simple approach

The simple, obvious approach:

WindowsMediaPlayer player = new WindowsMediaPlayer ();
Media = player.newMedia ();
duration = media.duration; // etc. // more queries using getItemInfo

Doesn't work, as the player's openState must change to MediaOpen before you can start to query it.

Step II - Being clever

Ok, I thought, that would have been too easy. Reading the documentation, I discovered that the player would trigger the OpenStateChanged event when it opens a media. Beware, as this will only work for the current file - i.e. player.currentMedia. Which means you can only wait for one media to open at a time. Great, I thought. I wrote a quick event handler, and ran it inside a foreach loop. The OpenStateChanged event was fired exactly once. Time for another approach.

Step III - Threads to the rescue

Obvioulsy, what was needed was a way to start up a load process and let it run until it finishes, and then return to the main process. My aim was to create a process function that would create a new WindowsMediaPlayer instance, call the newMedia method and wait until the OpenStateChanged event occurs. Then, it would get the data about the movie inside the event handler and store them. Finally, it would trigger some signal so the main thread knows the open/read/close cycle ended. I looked into the threading examples that ship with VS.NET 2003. After some reading, I discovered that I was supposed to create a ManualResetEvent, pass this to the working thread and wait for it using a WaitHandle.

Side battle field

One thing I tried during this was to use the WaitHandle.WaitAll method on an array of objects. Don't do this, enabling this needs some tricks in a Windows Forms application (as it is STAThreaded but WaitAll depends on MTAThreaded code). I created an array of ManualResetEvents, passed one to each worker thread and called WaitAll - hoping this would work. It didn't, for several reasons: First of all, it created around 800 threads, as every worker thread had it's own local media player which was multithreaded on its own. This thread count (several thousand threads!) eventually crashed the application. Second, the individual threads did start and end at different times, and it was impossible to nail down when each thread was done - sometimes, they started working after the WaitAll call!.

Step IV - The end

My last approach was to create a special object that would have a ManualResetEvent embedded and which would only return when the event handler finished its work. This does indeed work, but, as usual, it's not possible to use it in production code. As I started working more with this approach, I found out that the media player tries to open sometimes files that are not of type "video". To address this issue, I added a special call inside the event handler:

if (media.getItemInfo ("MediaType") == "video")
this.valid = true;

Later, I wanted to query this bool to decide whether to trigger the OnValidMovie or the OnInvalidFile of my backend. The curious thing was the events were fired before the object finished creating, meaning that it was in an undefined state. Even when I tried to throw an exception inside the object the event handler was already called before the exception had a chance to be thrown, although the object would not return before its internal ManualResetEvent occured! Moving the reset event outside the object didn't help, starting the object inside an own thread did also not help. The events would be triggered before the exception was thrown, no matter what I did. The code is:

System.Diagnostics.Trace.WriteLine ("openStateChangedHandler finished");
manualResetEvent.Set ();

Guess what, the output happens after the event was set! That's it, I've got enough of this kind of stuff, it takes far too much time which I don't want to spend on such a stupid problem.

F13 going public

Didn't have much time to update my blog lately, as I was quite busy working on F13 and the next Shelter13.Net homepage. I expect the page to be finished till mid-september, and fully working until october. Moreover, I'm planning the commercial release of F13 for the end of the year. For details, be sure to check out the read more section.

SH13 II - current progress

During this week, I finished the basic design of the page. There won't be any changes to it any more, except very minor ones like maybe make some text slightly larger or change a color. At the moment, I'm working on some of the backend scripts, but I'm quite confident it won't take too long before I can put the page live and concentrate on bug-fixing.

F13

Yeah, it's true, F13 is going to be released to the public! After working for 2 years on it and porting it over to PHP5, I'm going to release it by the end of this year (hopefully). While creating the next SH13 page I still discovered some inconsistency in the API design (small little things that make using it more complicated than needed), and I wanted to have them sorted out before going commercial with it. Plus I wanted the SH13 as a last "stress test" for the whole framework. F13 will be released with the full source code, I have no plans to encrypt the PHP files. It comes with complete documentation, both auto-generated API documentation and a "Getting started" PDF manual. If I have enough time, I would like to include some sample project, but I can't make any promises on that yet. Full email and IRC support, including help with integrating F13 into your own page will be provided for at least 6 months. F13 is a mature, leightweight web-development framework that simplifies loads of common tasks when creating web applications and web pages. It consists of some tightly integrated core services that are built for maximum security and flexibility, and seperated by a very clean API from all application code. For example, when developing the SH13 PasteBot or a custom in-house bugtracker, I could nearly start off directly with the application logic and didn't have to care about how do I connect to the database or how do I make a secure user login. The pastebot is a particular good example, it consists of a single PHP script which is 6,63 kb large - yet it is a fully functional pastebot with database access, $_GET parameter validation and embedded into a few templates. A note on third-party libraries used in F13: F13 makes use of Smarty! and ADOdb, libraries that were used in a lot of production environments.

New windows style

I've switched to a new windows style, which is supposed to be the same that you get with the Media Center Edition. I hope this is the right link. It's called Royale, if you search the web for "Royale Theme windows" you should easily find it.

Random thoughts

I've been working on the renderer lately, and I'm currently playing with the idea to split the renderer up into a front and backend. The front end would be responsible for "high-level" stuff, like creating buffers from geometry data and the back-end would handle the "low-level" stuff, i.e. provide interfaces to the graphics API and perform rendering only, without any knowledge what it is renderering. The intention is to allow several highly optimized backends for various rendering paths, by using vendor-specific extensions for example. I'm gonna give it a try as soon as I finalize the way meshes are going to be stored and the interfaces between the renderer and the rest of the engine.

Current progress

At the moment, I'm using the vertex array extension to perform the core rendering. I hope I'll be able to implement the vertex buffer object support next week, should save me loads of traffic up the bus as with vertex arrays, I need to send the geometry data once per frame. As I want the engine to be as fast as possible with static, rigid geometry, VBOs are the right way to go. They should be also quite a bit more memory efficent as I don't have to store the geometry in the process memory any longer.

nVidia PerfKit

For those who didn't see it yet: nVidia released the PerfKit for both OpenGL and DirectX. Yeah! Finally you get the power of PIX for OpenGL. Really great work from nVidia, hopefully they keep up their excellent support for OpenGL in Windows Vista (see my previous post for details)