Tomer Gabel's annoying spot on the 'net RSS 2.0
# Sunday, February 26, 2006

While working on one of our projects at Monfort, we encountered a very strange problem. The project was dependant on several COM objects, one of which queries a database according to a predefined interface and returns the results in an ADO Recordset. Our project is key-signed, so we had to import the COM objects using the .NET SDK tlbimp utility; everything worked perfectly until we added the querying logic that receives the Recordset result object. The class loader would throw an exception on calling the relevant method (it was invoked dynamically) claiming that the "referenced assembly adodb.dll could not be found." To quote Monty Python: this is, of course, pure bullshit. The imported ADODB wrapper was right there in the directory. I couldn't figure out the problem in a reasonably timespan, and finally decided to ignore it altogether by using the ADODB primary interop assembly distributed with .NET 1.1. I added a reference to the ADODB PIA and everything compiled and seem to run fine.

This turns out to have been a mistake. I was absent from work for a few days getting ready for a test, and came back to find that a colleague has encountered the same problem but elsewhere; examination of the compiled executable's references (via ILDASM) revealed that it was in fact generated with two separate references to ADODB with two different public key tokens. One of the references was the PIA, which was just peachy, but the other one (in the hidden namespace ADODB_19 of all things) referenced a non-existing assembly with the same public key token we sign our other assemblies with. I concluded that there must be some sort of problem with the build process - left over dependencies that weren't compiled properly or something of the sort. Cleaning up the build directory and rebuilding did not alleviate the issue. In desperation I tried to manually edit the project files but couldn't find anything.

I then decided that one of the COM object wrappers we created using tlbimp was, for some reason, referencing a non-existing version of the ADODB wrapper; I went through the wrapper assemblies one by one and managed to find the offending library. Turns out that tlbimp does not, by default, look for primary interop assemblies and opts to import ADODB every single time (singing the new wrapper assembly accordingly). When I deleted what I thought was a redundant ADODB wrapper assembly, I in fact deleted a version of the wrapper that was referenced by one the imported COM wrappers. So now all I had to do was add a /reference: directive to the tlbimp call in our build script and voilla - everything works!

Only it doesn't. Another COM object which references ADODB was still generated with the mangled assembly reference (i.e. it still referenced the wrapper with our own public key). I retried all sorts of tricks and couldn't figure out why it was generated that way; I eventually tried to re-import it manually with a /strictref directive, which resulted in the following error message:

C:\Temp>tlbimp SomeComServer.exe /keyfile:PublicKey.snk /reference:"%PROGRAMFILES%\Microsoft.NET\Primary Interop Assemblies\ADODB.dll" /strictref
Microsoft (R) .NET Framework Type Library to Assembly Converter 1.1.4322.573
Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.

TlbImp error: System.ApplicationException - Type library 'ADODB' is not in the list of references

A fit of confused rage and an hour later I sat at the computer again to try to figure things out; finally (as usual) it was just a matter of asking Google the right question:

The problem was that MyCOMLib.dll was compiled against ADO 2.5 and the PIA released by MS is registered only for ADO 2.7. I don't have access to the COM component to recompile it for ADO 2.7, so I had to get a PIA for ADO 2.5.

Further research into this turned out a little detail most .NET developers are probably unaware of:

Issue 7: You experience problems working with components that expect ADO 2.8 interfaces

The ADODB PIA that is included with Visual Studio 2005 is the same component that was included with Visual Studio .NET 2003 and was built by using the Microsoft .NET Framework 1.1. The ADODB PIA was built to interact with ADO 2.7 interfaces and has not been updated to work with ADO 2.8 interfaces.

Therefore, attempts to use the ADODB PIA together with components that expose ADO 2.8 interfaces will fail. This scenario is not supported with the ADODB PIA.

Oh, great job, Microsoft! You spent so much time on the interop issues with .NET (of which, by the way, there is an impressively small number), came up with the concepts for Primary Interop Assemblies, Publisher Policy Files and everything else that went into .NET in order to prevent DLL hell, you tout Primary Interop Assemblies as a way for component publishers to guarantee that their components are usable under .NET, and finally you go on to release a PIA for one of the most widely used COM objects in Windows which only supports one version!

So there you are, I hope this might save someone the frustration of having to figure all of this out on their own.

As a footnote, ILDASM is one of the worst tools I've ever used. I can't believe how Microsoft managed to wrap a useful debugging tool with one of the most frustrating and least usable UIs I've ever encountered. Don't know what I'm talking about? Try double-clicking on a node (method, manifest, whatever). You can't run a search through the text; worse still, you can't even Ctrl+A, Ctrl+C then paste into notepad! Only now, days after I needed it, did it occur to me to rightclick and "select all". I suppose it's OK if you don't follow the classic usability patterns and guidelines in a small and esoteric development tool, but please try and exercise a bit of common sense...

Sunday, February 26, 2006 10:47:04 PM (Jerusalem Standard Time, UTC+02:00)  #    -
I couldn't access the comments on my own website for an indeterminate amount of time (at least a week) and had to dig in the sourcecode to find the culprit (now described in bug 1439112). To make a long story short, it appears I got my dasBlog cookies mangled, so if you have the same issue either contact me or get rid of all cookies from

(If you're using Firefox and don't know how to access your cookies, here's how. If you use IE just go to d:/Documents and Settings/username/Cookies).

Sunday, February 26, 2006 8:03:39 PM (Jerusalem Standard Time, UTC+02:00)  #    -
Personal | Software
# Tuesday, February 14, 2006

Well not as such, no, but it sometimes feels like way. Particularly today, when I wasted about 40 minutes on a bug that should've taken me less than 1 minute to work out, simply because of issues with the Visual Studio debugger (2003, mind you - you'd think after three years it would be a mature product?)

Check this out, for example:

m_ltInfer is of a class deriving from DictionaryBase. What the hell am I supposed to understand from this? The fact that I can't see my dictionary is bad enough, but what's up with those blank spaces? And if that wasn't bad enough, the immediate window's expression parser - limited to begin with - is flatly lying to my face:

op.Parameters is an array. It has a Length property. The intellisense displays it. The managed expression parser prints it out as the default property for arrays. But attempting to access any of the object's properties, or even its ToString() method, results in a "... does not exist" error message. What the hell is going on here?

Tuesday, February 14, 2006 9:16:10 PM (Jerusalem Standard Time, UTC+02:00)  #    -
# Monday, February 13, 2006

So I'm sitting at work, listening as I usually do to all sorts of music in the background. I found myself listening to the excellent soundtrack written for A Clockwork Orange (which also happens to be one of the best movies I've ever seen). Some of the classical pieces there have a distinct ring to them, as if they've been performed in a very peculiar and distinct (somewhat synth-y, for lack of a better word) style. It kept bugging me that I've heard this someplace before, and after some 40 minutes it finally struck me: it sounds highly similar to the soundtrack written for the movie Tron (also highly recommended).

I took a better look at the tracks to see who wrote them - a Walter Carlos. This was even more surprising for me, because I recall the Tron soundtrack credited to a Wendy Carlos. What's up?

Some digging in wikipedia proved once again extremely fruitful:

Her first six recordings were released under the name Walter Carlos, although, being a transsexual woman, she had already changed her name from Walter to Wendy. In 1972, Carlos underwent gender reassignment therapy. The last release to be credited to Walter Carlos was By Request (1975). The first release as Wendy was Switched-On Brandenburgs (1979). Carlos's first public appearance after her gender transition was in an interview in the May 1979 issue of Playboy magazine, a decision she would come to regret as it brought unwelcome publicity to her personal life. On her official site, her transition is discussed in an essay stating that she values her privacy on the subject.

The universe never ceases to surprise me.

Monday, February 13, 2006 10:02:58 PM (Jerusalem Standard Time, UTC+02:00)  #    -
Music | Movies

I eventually get fed up with the various ReSharper builds I've been using for the past 7 months; the stability has been going steadily downhill since build 208 and performance is yet to improve. 217 originally seemed stable but turned out to be useless both for VS2003 and VS2005. I've been waiting in vain for a build as stable as 208 (which was practically beta-ready) but to no avail.

Eventually I broke down and installed the official 1.5.1 (build 164) for VS2003; unfortunately there are no official builds for VS2005 as of yet. I must say working with the official version is a pleasure - it's absolutely stable and, even more important, fast. So fast, in fact, that it feels just as responsive as the "regular" VS2003 IDE is, and the only drawback is a small increase in startup time.

I'm tenacious so I'll probably check the beta builds again when 218 is out, but in the meantime I can't help but feel pleasure in working with a mature product.

Monday, February 13, 2006 3:04:35 PM (Jerusalem Standard Time, UTC+02:00)  #    -
Development | Software
# Tuesday, February 7, 2006

I came back to my apartment today after not being there for a couple of days, to find that our (my flatmate and I) router died due to a power outage. I needed internet access so I hooked up my laptop directly to the cable modem (a Motorolla) and for some reason couldn't get a ping anywhere; some digging showed me that for some reason the modem, which acts as a DHCP server, gives me a local (192.168.x.x) IP address, no DNS servers and no default gateway.

The modem would return pings and the operational web interface showed everything to be fine and dandy, so I spent the next 15 minutes having the most futile conversation I've ever had with a tech support guy. Now as a programmer and reasonably hardware- and network-savvy individual I figured that if a modem and computer restart won't solve the issue it must have something to do with the cable/ISP networks; there was nothing to indicate local failure, so I didn't think to examine the obvious.

The Motorolla modem has a standby button.

I'll be damned if I know why, but it does. And someone pressed it. All it took to get my internet connectivity back is to press it again. Which brings me to the point: it is well known that one of the cardinal sins is vanity, it is equally well known that programmers generally exhibit the three cadinal sins (vanity, hubris and laziness, I think?). So if you're a programmer, whenever you talk to tech support don't be a smartass. You'll save yourself time in the long run.

Tuesday, February 7, 2006 5:37:44 AM (Jerusalem Standard Time, UTC+02:00)  #    -
# Monday, February 6, 2006

Back when I used to code demos with friends as a pastime (1995 or so) we would slave away on three or four PCs, at best interconnected with null-modem or parallel (a.k.a laplink) cables; whenever someone would have a breakthrough we'd reconnect the machines and shift sources around (sometimes opting to use modems or floppies instead). Eventually we'd get to a more or less complete set of codebases and integrate them into a single production.

That process could best be described as hectic. I'm amazed we ever managed to get any work done, particularly in the absence of automatic merge tools such as Araxis Merge; the number of times we would accidentally overwrite or modify each other's code, accidentally delete an object file or some other stupid mistake was astounding. With that baseline in mind, when I was introduced to SourceSafe back when I was serving in the Israeli army I was appalled. The concept of a singular repository for sources (with write access to everyone on the team, no less) seemed incredibly stupid, although in retrospect I couldn't tell you why. SourceSafe's (severe) problems aside, I'd expect the fundamental concepts of source control to strike a chord with me immediately, but it took a while for that to happen; over the years I've developed pretty rigid standards of working with source control - what should or should not be checked in, how long is it OK to check out a shared file exclusively (more or less the only option with SourceSafe...) and how to organize the repository effectively.

Fast forward to 2006. I'm working on a project that has several seperate components; the project, which is actually version 2.0 of a certain product, is kept in a central source control repository along with its dependencies (libraries, documents, installables) and everything seems to be fine. Only it isn't. The first problem is that the project was originally developed for an external company which uses Perforce as its source control provider of choice. We then brought the codebase back to Monfort and set out to rework the existing components and develop new ones. This means that while large portions of the code were being worked on, others remained completely untouched - in other words, some projects were imported into our source control system (Vault) and others were not. This proved to be very annoying when I had to re-integrate and test some version 1.0 code today; it's worth noting that Visual Studio is anything but graceful when it comes to handling unavailable providers or incomplete bindings:

So much for verbosity, but at least I can Work Disconnected...

... right after I click on OK again.

That was only the first hurdle. The second was an apparent lack of attention on a certain developer's part (sigh), who forgot to add installations for certain 3rd party dependencies to the repository. Fast forward another fourty minutes or so (DevExpress's installers suck) and I was finally on my way to a working test build.

At that point, a new developer on the project approached me with some compilation issues. This was pretty rudimentary stuff - installing a public/private key container, path variables, 3rd party installations etc., but the guy couldn't be expected to know how to do any of this stuff, let alone what needs to be done or where to get the required files. Which brings me to the conclusion of this here rant:

  1. When you import a project into your development environment (source control, build system, back up, etc.) take the time to get (re-)acquainted with the codebase and make any necessary conversions. It'll pay off in the long run,
  2. Always keep all dependencies safely tucked away in your source control repository. That's as close to a file server as you are going to get, it's properly backed up (isn't it?) and the files are kept close to their target audience - developers on that particular project.
  3. A "Developer Workstation Setup" document is an absolute must-have. Saves everyone a lot of time and headache.
  4. Try and maintain behavioural consistency between developers on a given project. This doesn't have to (and preferably won't) extend to indentation and code formatting issues, but some sort of check-in, documentation and dependency resolution policy is important, if not for the project than at least for your medical bill.
Monday, February 6, 2006 3:15:49 AM (Jerusalem Standard Time, UTC+02:00)  #    -
# Monday, January 30, 2006

I'm a self-proclaimed part-time, low-budget audiophile (there's a mouthful), so I often try to combine good performance with reasonable cost. To that end, considering I spend about 80% of my time at work (and, up until recently, home as well) with headphones on my head, the Sennheiser HD600s I got about five years ago for the price of about 200 of today's US dollars after shipping and taxes were the absolute best bargain I've ever made. The Jean-Marie Reynaud Twin MK2 speakers I also bought at about the same time were so impressive that the lowest-priced comparable speakers were 60% more expensive.

Things have somewhat improved since then; the taxes on audio equipment in Israel have been considerably reduced, although at some 34% they're still very high (down from 70%...). I mentioned this before in my post regarding the Yakumo Hypersound Car. Since then I went to an auto shop for some additional equipment, specifically a 6x9" component set, 3.5" mids to replace the crappy ones in my Punto, a 12" Pioneer sub and 2x60w (continuous) amp (I'll post the models number later - damned if I remember).

On the left: Pioneer sub under the component speak, on the right: Yakumo Hypersound Car installed

While the CD receiver was a breeze to install, I'm pretty glad I didn't attempt to do the rest of it alone; I don't know jack about car electronics and some of the stuff involving the installation of the amp I didn't know to begin with (such as hooking up the negative terminal to the car chassis) and I would've done a heck of nasty job if I tried running some of the wires on my own. On the other hand, contrary to my usual cautious self I didn't do much market research and ended up paying considerably more than the equipment was worth. It was definitely a learning experience, though, and I won't make these mistakes next time.

That said, the sound is great - not perfect but I'm still tweaking it. The Yakumo unit turns out to have very poor amplification; at first I thought the specified 65dB signal-to-noise ratio was a mistype in the product manual, but it turns out rather accurate; there is a very audible hiss at even moderate volume levels (which I couldn't hear earlier because of the crappy speakers I bought the car with) and the rear-speaker sound is bright to the point of being harsh. This may or may not be attributed to the Pioneer component speakers - if so you can bet that they'll be replaced - but in the meanwhile I've found the amplification so horrid that I'm replacing the 2-channel monobridged Pioneer amp with a quad-channel amp to drive both sub and rear speakers (5- and 6-channel amplifiers are prohibitively expensive, so I'll skip those for now).

The Yakumo unit also suffers from some pretty severe usability issues; the TOC indexing times for USB devices (tested with a fully loaded iRiver H320) were nothing short of abhorring (about 3 minutes from iRiver boot). With CDs the problem is less of an issue, about 20 seconds for a 700MB CD, but I still think it's rather stupid that the unit can boot up to the exact location I last powered it off in but has to index the TOC first. The random mode is extremely useful with compressed files, but why does it change track when I turn it on? The fact that I can't navigate by folder (particularly with the existence of a jog dial!) without going through the tedious search function is ridiculous, and I've actually managed to get the unit's firmware to crash once or twice (Update: actually, the unit seems to be extremely crash-prone). I believe most if not all of these problems can be solved with a little work on the drive's firmware, but there is none from Yakumo. In my opinion the solution would be to simply open-source the firmware; it's probably based mostly on LGPL'd code to begin with, and it would allow community involvement in empowering the brand. I, for one, would be delighted to tweak the source code to my heart's content; it would make the unit all that more useful. With the lackluster amplification and usability issues it's very hard to recommend the unit to anyone but a die-hard OGG Vorbis fan.

Update: Having owned this unit for several months I can safely say that it, quite plainly, sucks. It is crash-prone, error-prone, extremely slow on boot up, requires constant resets and provides very low sound quality to boot. Its one saving grace is Vorbis support, and even for me that's not enough to save it from a "piece of crap" verdict. I'm going to replace this thing as soon as I find a decent alternative; the XiphWiki points at a similar product from Silvercrest, but given the track record of these things I'm inclined to forego in-dash players altogether and go for a hard-drive based solution. Now if I can only find a decent one...

Monday, January 30, 2006 2:32:34 AM (Jerusalem Standard Time, UTC+02:00)  #    -
Music | Personal
# Sunday, January 29, 2006

Whenever I get a new machine (at work, at home, anywhere) I'm always astounded by the sheer amount of time it takes to get it up and running. I don't mean just the basics, I mean a fully-functional platform that is set up just the way I'm used to, right down to the folder display settings in Explorer and the toolstrip I always like on the right side of the screen.

I mean, seriously, there's gotta be a better way to do this. The following applications are just the basic things I need to be efficient:

And that's just to get me through the day. It doesn't include all the multimedia and development tidbits, like:

I reckon the net installation and customization time is over 10 hours (some installations can be done in parallel, some can be deferred to a later time). That is a lot of time to spend on just setting up your machine. The problem with using Ghost or some similar software is that I get a system without all of my current data (profiles, files, documents etc.), and as for virtual machines, they're simply not fast enough yet for constant use (at least on my modest home desktop or laptop).

Sunday, January 29, 2006 11:34:24 PM (Jerusalem Standard Time, UTC+02:00)  #    -
Personal | Software
# Tuesday, January 24, 2006

... there's an online video of 8088 Corruption that is an absolute must-see.

Trixter, you rock!

Tuesday, January 24, 2006 8:55:01 PM (Jerusalem Standard Time, UTC+02:00)  #    -
Demos | Personal
Send mail to the author(s) Be afraid.
<February 2006>
All Content © 2024, Tomer Gabel
Based on the Business theme for dasBlog created by Christoph De Baene (delarou)