Saturday, July 7, 2007

error MSB4018: The "Vbc" task failed unexpectedly.

Today I got this error after moving about a dozen .vb files out of an App_Code directory of an ASP.Net project and into a separate class library project.

error MSB4018: The "Vbc" task failed unexpectedly.

I knew that when I moved all of that code over to this different location the project would not compile so I wasn't surprised to get a few error messages. Well, the nasty thing about this error is that you lose all intellisense and basically Visual Studio becomes Notepad.

I know an aspiring storyteller should always make the sorry really exciting and maybe even include a few car crashes but I think I'll cut to the chase on this one.

After removing all of the .vb files from my project and still not being able to compile I forwarded my problem to the very helpful MSBuild team at Microsoft. It turned out that the problem was that I had manually overridden the "Base Address" setting (Project Properties Compile tab Advanced Compile Options button) with a hex number that was too large for the compiler. So, if you dare to change the base address setting they recommend that set it to a relatively small number. My number was &H98512474.

Here is there full recommendation:

In general, you want to keep base addresses lower than 2gig; although each process that you create runs in a virtual process space that on 32 bits is 4gig, you may be causing a fair amount of memory page swapping with such a large address space. What you are trying to avoid by setting the base address is loading into a space someone else is loading into. Collisions occur, and it just slows down the load time of your program. A small amount, but some. By default, VS builds programs at 0x10000000. Now since Microsoft knows that, we move all our dll's to higher ranges. For example, most MSFT components load in the 0x60000000 to 0x80000000 range (Use the tool below and open System.dll from the .Net Framework to see an example).

A good tool to use to help you set an appropriate address is dependency walker. This used to ship as part of Visual Studio but is now open source.

Build your executable, and open it with dependency walker. This will show every dll you are dependent on. Look at the column 'Preferred Base' and 'Virtual Size'. Set your dll to a base that is not taken, and add your virtual size to ensure that you are not tramping over someone else's preferred base.

A good rule of thumb is to use the space between 0x10000000 and 0x40000000. The only time you really need to worry about this is when you're are building a program with several libraries. Since your libraries will all want to load into the same space, they will clash and collide.

Let's just say this was not one of my most joyous adventures but it sure was exciting when I couldn't get a project with no .vb files to compile.

Thanks for joining me on this adventure.

No comments: