Wednesday, March 21, 2007

I'm not impressed with Diamond Multimedia support

I have a older PC that I just installed Vista. I want to make sure that our apps place well under that OS and I don't want Vista as my primary OS just yet. Usually I do that kind of testing under VMWare, but you don't get the full experience of the OS when it's virtualized.

This PC is older, a Dell Optiplex GX400 and has a NVIDIA TNT2 video card. It's a perfectly OK card, but Microsoft and NVidia are not doing a Vista driver for that card. So Vista is running it with the Standard VGA Graphics Adapter driver. The SVGA driver is better than I thought it would be, but it's slow and is running at 60 hz. I'm not terribly concerned over the speed, but the flickering is driving me nuts.

I got the OK to get a new card, and that's when the fun began. To get Vista's Aero Glass theme, you need a decent video card that has DX9 support. The GX400 has an AGP 4X port and a bank of PCI slots. No one is making AGP 4X cards anymore, it's AGP 8X or PCI-Express these days. I looked up the specs on a BFG card that claimed to be AGP 8X/4X, so I fired off an emaill to them to see if their card would work with my ancient PC.

While I was waiting for a reply, I saw an article on The Inquirer about companies releasing Vista ready PCI cards. Diamond had released a PCI card based in ATI's Radeon 1300 chipset and it sounded like it would do the job. After a few days of no response from BFG, we ordered the Diamond card. Immediately placing the order, a reply came from BFG that said their card would work.

The Diamond card came in today and I tried installing it. I removed the Nvidia card from the AGP slot and put the Diamond card in a PCI slot. There are 5 PCI slots, all of them were available. The machine wouldn't recognize the card. I tried a number of things (telling the BIOS not to expect an AGP card, moving the Diamond card to another slot, putting both cards in. With both cards in, the machine would not recognize either card.

Either it's something flaky with the Diamond card, or more likely, it's Dell building a PC that only works with AGP cards. Past experience with Dell has led me to the conclusion that the card slots on a Dell motherboard are purely decorative. I decided to call Diamond technical sipport to rule out their card.

Almost immediately, I was connected to technical support person. I forgot his name, let's refer to him as "Stan". Stan was not very helpful. It was clear that he was reading from some sort of script and deviations from that script were verboten. I explained that the PC would not make it past POST when the Diamond card was installed. He asked what OS was installed. I said "Vista, but that's not important right now". He asked what driver was installed. I told him that Vista did not support the current card and was using the SVGA driver that comes with Vista.

He asked me to uninstall the SVGA driver. I asked why and he said that having the wrong driver was a common cause of video card problems. I declined to do so for the following reasons:

  • The problem occurs at boot time, video drivers are not loaded until the OS loads. My machine was nowhere near that point.
  • It's the standard VGA driver that comes with Vista. It's the driver that gets loaded when you uninstall a vendor video driver.
  • I doubt that Vista would let you uninstall it in the first place.
  • The Diamond card had to work with SVGA driver or you would be unable to install Diamond's driver.

Since I declined to uninstall the driver, Stan's demeanor and he basically said there was nothing more he would do. I thanked him for his time and hung up.

This card is being sent back and I doubt that I would ever buy another Diamond Multimedia product. The BFG card is on order, hopefully that will be a better experience.

Tuesday, March 20, 2007

Notes on installing Delphi 2007

I got the email yesterday from CodeGear. It was a link to download the newly released Delphi 2007. I will be getting the DVD from CodeGear as part of the Software Assurance that I have, but I wanted to try the new installer. This is their first release using installer technology from InstallAware. As it happens, I'm considering switching from Wise For Windows Installer (WFWI) to InstallAware, so it's a good oppourtunity to see their installer in action.

The installer is a minimal (4MB) installer. It grabs the bits that it needs from the Internet from the bits that it needs and the bits that you want. It took a while to download the installer. There were three options, HTTP, FTP, and Galileo. From my office, none of them worked. Once again, our SonicWall firewall has safely protected me from downloading stuff that I need. After a few attempts, I went to Plan B. That was my home PC. I remoted into that box, immediately downloaded the installer without any grief and copied the file back to my office PC.

Once I had the installer, I ran it on my Vista box. The Vista box is my backup PC and I just put Vista in it to test our apps under a hostile environment. The first thing installer did (after I answered "Continue" to the ever present UAC) was to announce that it needed the .NET 2.0 SDK and it was going out to get them. It transferred about 360MB or so of .NET parts and then installed them.

After about 30 minutes or so, I got the "Welcome to the InstallAware Wizard for RAD Studio Setup" page in the setup dialog. Which led to the EULA and registration pages. Oddly enough, it defaulted to "CodeGear" as the company name. Come on folks, that value can be read from the registry. The "Next" button flickered as I typed into each field. I don't know that that's Vista, Windows Installer, or InstallAware. I'm guessing it's Vista's non-support for my ancient NVIDIA TNT2 card that it treats as a standard VGA device.

Then I was prompted for what features to install. I have the Enterprise version, there were many features. It wanted about 1GB and called itself "CodeGear RAD Studio". After one more confirmation prompt, the installer went back to the mothership to download the bits it needed.

It was done after 90 minutes. Now comes the fun part. How many of the Delphi 2006 components will work as advertised?

John Backus, RIP

*--------------------------------------------------------------*
Program BACKUSJW
*
* This program notes the passage of the creater of the
* Fortran Language
*
integer count
*
print*, 'John W. Backus, RIP'
print*, '1924-2007'
print*, ''
print*, 'Led the team that designed Fortan in 1954.'
print*, ''
print*, 'Server on the committees that design ALGOL.'
print*, ''
print*, 'Invented the first Function-level'
print*, 'programming language '
print*, ''
print*, 'Won the Turing award in 1977.'
*
do counter = 1, 15
print*", 'RIP'
enddo
*
end
*--------------------------------------------------------------*


Tuesday, March 13, 2007

Why I'm looking forward to "Orcas"

I have stayed away from the Visual Studio betas (I beta test enough stuff already, thank you), but the more I hear about the next version of Visual Studio (code named "Orcas"), the more inclined I am to installing it in a VMWare session.

Scott Guthrie has been running a series of blog posts about the new language features coming in "Orcas".  His post about Extension Methods caught my eye.  In a nut shell, Extension Methods let you new methods of an existing object type, without having to subclass that object or modifying the object.

You bascailly create a new static class with a static method.  The first parameter has the keyword "this" prepended to it.  This informs the compiler that the new method should be added to the class referenced by "this".

Codegear does something similiar with Delphi 2007 to allow it be a non-breaking upgrade from Delphi 2006.

Scott also has a good example of how to use LINQ Extension Methods to query an XML file.  That for me was the first I really got the value of LINQ.

Automatic properties look pretty cool.  It's just syntactical sugar, but it goes down pretty good.  I have always been in the habit of creating properties for the public variables of a class in C# and Delphi, this makes it a little quicker write on the C# side.

Sunday, March 11, 2007

Julie Lerman's coming to town

On Tuesday, Julie Lerman is coming in from Vermont to do a presentation about ADO.NET Orcas at the TVUG meeting.  This will be the first meeting held at our office, it should be a cool presentation.  I saw her speak last year at a TVUG meeting and she's very good.

Thinking about WAIS, Gopher, and ExecPC

I was reading a post by Brad Abrams, where he was wondering why WAIS and FTP had died out.  While I disagreed with the idea that FTP has died out, WAIS is one of the long gone technologies of the Internet.  Unless you were using the Internet in the early '90s, the odds are that you have no idea of what WAIS was.  WAIS is over.

I remember trying it and not being terribly impressed by it when I got my first dialup Internet account (to get cheap access to ExecPC).  In the late 80's and early 90's, ExecPC was a super (as in huge) BBS, run on a bank of 386 machines.  At the time, ExecPC was one of the best places to get Amiga and DOS freeware and shareware.  While writing this post, I found out that ExecPC was still up and running, just without any modem access.  You can telnet into it from here.  I took a quick peek and it looks exactly the same as as it did the last time I logged in, back in 1998.

I got my first fast modem from an ExecPC auction.  Back in the days where 14,400 baud modems were the top end and 9200 was the norm, US Robotics had their own HST protocol that ran 16,800 downstream.  You only got HST speed when connecting to another HST modem, but the better BBSes had a least one HST modem.  One fine day, ExecPC upgraded their modems and they auctioned off the older ones.  A buddy and I got a couple of Courier HST Dual Standard internal models.  I think we paid about $150 each, at the time HST Dual Standard were going for $500.

If two those modems were not the original prototypes from US Robotics, then their serial numbers were still in the single digits.  These were full length cards and they had wires running all the place..  They worked great though.  After a couple of months, I was able to trade mine in for a new external Courier V.Everything modem.  This was back in 1994 and it was probably the fastest modem available on the consumer market.  I was able to upgrade it to the V.34 and V.90 standards when they became available.  It was is built like a tank.  I had stopped using it 7 years ago, when I got broadband, but my in-laws used it until last year, when they finally got broadband.

ExecPC was run in Wisconsin and it was expensive to call from NY.  ExecPC had a deal with an ISP named Concentric Research (CRIS).  If you had a CRIS account with a local dialup number, you could access ExecPC through the CRIS Unix shell as a local call.  When you dialed into CRIS with a terminal program, you got dumoed into a menu, from which you could access ExecPC.  It had other things on that menu.  You could drill down into WAIS and Gopher space, you could run Lynx (a text based browser), Pine (a text based email app), or even drop down to a Unix shell.

I had that CRIS account so long ago, they didn't offer a PPP connection when I signed up.  I had to use their SLIP implementation.  And this was with Windows 3.1, which didn't have native support for the Internet protocols.  I remember having to go through all sorts of gyrations getting the Trumpet Winsock to work.  You take for granted how easy it is to hook a PC up to the Internet these days, prior to Windows 95 you had to do some work to get it set up the right way. 

It's kind of funny what pops out of the deep recesses of memory by the reference of an archaic acronym.

Wednesday, March 07, 2007

Where is puterSoft.com?

Don't you hate it when a software component vendor disappears without warning?  In some of our applications, we use a custom datetime edit control named TPSCDateEdit.  This is part of a package from a company named puterSoft.  We have been using it for about 5 years and when we migrated our Delphi code to Delphi 2006, we got the Delphi 2006 version of their code.

Well, we discovered an annoying cosmetic bug.  If you exit a TPSCDateEdit control without entering in a date, the text of the control gets the date '12/30/1899'.  12/30/1899 is the day that the world began if you are a COM based life form.  The control was saving the right data (or in this case the lack of data), it was just the display that looked ugly.

So the first thought was to check puterSoft's web site to see if this was a known issue and had a fix or work around.  That failed and when I tied to ping the domain name, that failed.  I did some playing around on http://www.dnsstuff.com/ and I learned that it was hosted at DiscountASP.net and that DNS lookups are failing.  If you perform a DNS lookup for puterSoft, it goes into a loop and DNSstuff is smart enough to break out of that loop. 

I can't tell if puterSoft is gone or something is all fracked up with DiscountAsp.net's DNS records.  I've emailed Sergiy at puterSoft to see if they are still around.  I also fired off an email to DiscountAsp to see if they can tell me anything.  After 20 minutes, I got a reply back from DiscountASP.NET that the account has been cancelled.  That's Not Goodtm.

Since I'm not going to get any resolution from puterSoft in the immediate future, I decided to take a whack at it and see if it was a simple fix.  And it looks like it is.

When you exit a TPSCDateEdit, the following methods are called:

  • TPSCCustomDateEdit.PostValue
  • TPSCCustomDateEdit.SetDateTime
  • TPSCCustomDateEdit.UpdatePopup
  • TPSCCustomDateEdit.GetAsText

Other methods are called, these are the ones important here.  UpdatePopup has the following logic:

 

If Text <> GetAsText Then
  Text :
= GetAsText;

 

The code in GetAsText looks like this:

 

function TPSCCustomDateEdit.GetAsText:String;
begin
  Result:=DateTimeFormat.ToString(DateTime,Kind)
end
;

By changing that code to this:

function TPSCCustomDateEdit.GetAsText:String;
begin
  if DateTime <> 0 then
    Result:=DateTimeFormat.ToString(DateTime,Kind)
  else
    result := '';
end;

 

I get result that I want. And life is good again.

Friday, February 23, 2007

FinalBuilder to the rescue (again)

One of our applications has an installer that is created with Wise InstallBuilder 9.  The application is built from our shiny buildbox under the control of FinalBuilder.  When FinalBuilder builds the application, it does everything locally on that box.  With one exception, the installer.  The installer script file resides on another box, and our QA department uses the same installer to test various versions of the installer.

To keep our builds separate from QA's builds, I have FinalBuilder set to call the Wise compiler with a variables file.  That file is created each time FinalBuilder runs and it defines the version number, the name of the setup.exe and where the setup is created.  By sharing the installer source script with QA, we ensure that our test builds match their final layout.

Which was all good until QA edited that file on a machine that has Wise installed to a non-default location.   For some inane reason, Wise stores the location of the their runtime files in the script file.  When you open that file with the runtime in a different location, Wise throws up a dialog and prompts you to save the correct value in the file.

We have been invoking FinalBuilder from a script and that prevents the Wise dialog from being displayed.  So the build script hangs at that point.  The only way to get control back is to kill the wise32.exe process.  Why does Wise need to store a hard coded path in a script file when it already knows the location of the path?

That's annoying.  However, using FinalBuilder makes problems like this trivial to fix.  I added a Copy File action to the FinalBuilder build script to copy the install script to a second file.  That would allow us to pick up any changes that QA makes to the script.  I then added a Text Replace action that did a search and replace on "D:\PROGRA~1\WISEIN~1" with "C:\Program Files\Wise Installation System".  And our builds are back in business.

Tuesday, February 13, 2007

Windows Home Server goes Beta 2

Windows Home Server has reached Beta 2.  Foe those of your playing the home version of "Name That Beta", Beta 2 means that Microsoft has is now soliciting external testers to try the new OS.

I've been running FreeNAS for a couple of weeks without incident, so naturally I decided to see if I wanted to take a perfectly good running NAS and replace it with an unstable beta. It does some cool things that I don't do with FreeNAS, so I decided to see what was needed.  It needs a Pentium 4, 512 MB RAM, and two or more drives with at least 300 GB space.

That seems a bit steep for a head-less device.  I'm running FreeNAS on a box that is at least 5 years old.  A 1 ghz Celeron with 256 MB RAM.  I started with a couple of 20 GB drives (remember 5 years ago) and added a 250 GB drive.

FreeNAS is working just fine, I think I'll leave it alone.

Monday, February 05, 2007

I hate Macs

You have to love a good rant...

I hate Macs. I have always hated Macs. I hate people who use Macs. I even hate people who don't use Macs but sometimes wish they did. Macs are glorified Fisher-Price activity centres for adults; computers for scaredy cats too nervous to learn how proper computers work; computers for people who earnestly believe in feng shui.

That's from Charlie Brooker, someone I will now start reading on a regular basis.  Having an iMac on my desk, I really loved this line:

When I sit down to use a Mac, the first thing I think is, "I hate Macs", and then I think, "Why has this rubbish aspirational ornament only got one mouse button?" Losing that second mouse button feels like losing a limb. If the ads were really honest, Webb would be standing there with one arm, struggling to open a packet of peanuts while Mitchell effortlessly tore his apart with both hands.

Yet another rebuild (Part 2)

I'm not installing Opera this time.  I've been an Opera bigot for a long time, but it's not going on my primary work PC.  I'm using FireFox 2 instead of Opera.  Why?  Three words: Google Browser Sync.  The best description of Browser Sync comes from Google:

Google Browser Sync for Firefox is an extension that continuously synchronizes your browser settings – including bookmarks, history, persistent cookies, and saved passwords – across your computers. It also allows you to restore open tabs and windows across different machines and browser sessions

After having to rebuild my PC twice now in the last month, I'm tired of losing bookmarks and other settings.  With Google Browser Sync, my bookmarks are synched up across machines.  It adds so much value to me, that I'm giving up the faster performance, the better security, and the smaller footprint of Opera.  Of course, I'm going to make Firefox behave like Opera as much as possible.

Yet another rebuild (Part 1)

After two and half weeks, I finally got my primary development box back from our IT manager.  The delay was due to fun with RAID.  After two drive failures within 30 days, I'm not taking any more chances.  BTW, nothing beats having two development boxes.  We are on three year refresh cycles for our PC's.  Usually developer boxes get rotated out to other departments.  On the last refresh, I managed to keep my old PC.  I do enough TCP development work, where it's handy to have to physically separated machines.  Now, the old box is now the insurance policy for when the hard drive goes on the primary box. 

Now, comes the tedius part, installing all the applications and tools that I use.  After the last drive finalure, I made up a spreadsheet of everything I use, that makes things much easier.  (Note to self: Next time, don't store that list on the machine that's meant for.  I was lucky, that file was recoverable when the drive went south.)

The first job is getting Windows setup up the way I want it.  That means XP, not Vista.  None of my development tools are certifed for Vista (Visual Studio 2005, BDS 2006), so why tempt fate.  Plus XP came with the box, might was well use the license.  For now, I'll run Vista from within a VMWare session.

After installing XP, I needed to get IIS installed.  Then Office.  Since the last drive fell on it's sword, I received the Office 2007 disk as part of the MSDN subscription.  I've only had the chance to play with Excel and Outlook, but the usability improvements are real.

The first time I ran Outlook 2007, it connected to our Exchange service and grabbed my mail.  The cool part was that I didn't tell it the name of our server or my email account.  It apparently figure that out from AD.  With Outlook 2003, I use LookOut to provide high speed searching of messages.  I don't think that's supported with Outlook 2007, so I have installed Windows Search.  It seems to work, plus it works across the file system.

The next thing I always disable is the Language Bar toolbar.  Even though you can right-click on the taskbar and de-select the Language Bar, it keeps coming back.  The following steps will take care of that:

  1. Click Start, click Control Panel, and then double-click Regional and Language Options.
  2. On the Languages tab, under Text services and input languages, click Details.
  3. Under Preferences, click Language Bar.
  4. To turn text services off, select the Turn off advanced text services check box.
  5. Click Yes if you are prompted to confirm your selection.

Then I add Administrative Tools to the Start Menu.   I use that enough so it's handy being able to get in quick.   Now the OS is functional, I can start loading up the tools.

A new title for Eliot Spitzer

I dub thee "Governor Steamroller".

Generating UTF-8 string s with out Byte Order Marks

Rick Strahl has a good blog entry on how get data from XmlTextWriter with having a Byte Order Mark (BOM) at the start of the data. The trick is to create the encoding manually and pass it with the constructor to XmlTextWriter.



Tuesday, January 30, 2007

Snap Preview Anywhere is annoying

Lately, I've been starting to see idiot popup windows on blogs that should know better.  The popups are from "Snap Preview Anywhere™", a javascript thingie that displays a popup window when you move the mouse over a link on a page.

It sounds like a clever idea, but then again someone once thought the <BLINK> attribute was a clever idea.

I find the popups to be very annoying.  If you are trying to read something and you move the mouse over one these snap-enabled links, your experience has been disrupted.  I'm not the only one who dislikes SPA.

The idea is to show a preview of the site behind the link so that you can tell if you want to click that link.  Come on people, it's 2007 and our browsers have multiple tabs.  No mysterious force is preventing me from opening that link in a background tab.

The good news, it's pretty easy to fix.  You can disable the popup by going here and scroll down to the "Snap Preview Anywhere Activation" block and follow the instructions.  That method requires that your browser allow cookies.

If you are using FireFox, you can really take the snap out by installing AdBlock Pro and adding snap.com to the list of blocked sites.  That works very nice.

Tech Tags:

Monday, January 08, 2007

About a year ago, I put together a PC to automate all of our QA-Ready and production builds. We don't have a huge number of applications to build, but I wanted an automated way to build each application. Before "Build Box", each project had one developer who was reponsible for the build.


This worked, but it had some serious limitations:



  1. It relied on a developer's machine to the build, which meant it required access to that developer. If he/she wasn't there, the team lead had to make sure that the machine would be accessable.
  2. Nothing was automated, no two products were built the same way. This opens the door wide open for mistakes like not having the current source code.
  3. Making a build was a major disruption for the developer who earned the build. This limited the number builds that would get buillt a day or week.

We use FinalBuilder to drive the build process. I can not say enough good things about FinalBuilder. It Just Works. With FinalBuilder, we use the following pattern to build each product:



  1. Get the latest source code. We use Vault, FinalBuilder knows how to drive Vault.
  2. Build the version information from .ini files stored in source control. With FinalBuilder, this was the easiest way to update the version number for the files. By alloing FinalBuilder to control the version resources, we can use the same mechanism for Win32 builds and for .NET builds
  3. Build the actual project or projects.
  4. Create updated installers. We use both the scripted and Windows Installer installer tools from Wise, FinalBuilder plays well with both. The only party of installer building that I can't automate, is the code to deal with upgrades in place. With Windows Installer technology, I need to handle that myself. That only happens once per product release, it's liveable.
  5. Deploy the latest bits to the QA server. QA gets two copies of everything. The first copy has the final filename, the second has the build number appended (ie. something_278.exe) to it.
  6. Send out an email to QA and the developers that notifies them that a new build has been released.

Now, any developer can remotely connect to the buildbox and start the build process. Of the course the fun part is getting the buildbox setup in the first place. It's like having another developer on the team, it gets everything installed.


What to install, what to leave out...

I have two machines that I do the brunt of my programming on.  One is a P4 1.8 Ghz box, circa 2002 that was my main work horse.  Last year I got a Pentium D 2.8 Ghz and that's the new main work horse.  Over the years, they have accumulated all the compilers that I work with (Delphi 5, Delphi 7, BDS 2006, VS 2002, VS 2003, VS 2005).   In a stunning show of solidarity, both machines had hard drive failures within a few months of each other.  The older one fell down August and the new guy blue screen in the most spectaculiar way just before Christmas.

To make a short story long, I had to repave each machine with new drives.  I have a nice long list of tools that I absolutely require to get the job done and I have been reinstalling each item as I need it.  I''ll post that list later.

When it came to the compilers, I only installed the latest of each one.  That meant BDS 2006 for my Delphi needs, and VS 2005 for my C# needs.  I didn't install the older versions of Delphi.  That was a mistake, I should of installed Delphi 7.  I really like BDS 2006, but CodeGear (née Borland) really broke the help system.  There are two many broken links, you have to explicitly the results to Delphi, or you end up with VB references.  And the content is missing many of the examples that were in Delphi 7.

But that's an annoyance, I installed only VS 2005 (plus SP1), completely forgetting that of the projects that I am involved with has an ASP.NET 1.1 front end.  Oops, I should have saw that one coming.  I don't do any of the coding on that bit, but I lost the ability to step throught that code to test my BDS 2006 based web service.  I'm trying to decide if I want to install VS 2003 (plus the older rev of DevEx) just to test some code.  What happens if you install VS 2003 AFTER VS 2005?  I spent too much repaving these boxes, I don't relish the thought of screwing it up by installing VS IDE's out of chronological order.   I think if I really need VS 2003, I'll create a VMWare session with Win 2K and install it there.  Or I'll create a VMWare image of our build box (everyone should have a buildbox), it has every compiler already configured.  Supposedly, I can create a VMWare session from an actual PC, that should be an interesting trick.

Friday, January 05, 2007

Blog Tagged

Andy just tagged me.  This is the geek version of tag.  I share 5 things about myself, then I tag 5 other people.  The hard is finding 5 other people who haven't yet been tagged.

What don't you know about me?

  1. I used to be a DataFlex programmer (During the 1st Bush administration).  Mainly for DOS, but some UNIX tossed in.  Once I got called by CDTA to fix a bus routing application that ran on some oddball mainframe version of Unix.  I had just flew in from Amsterdam (not that Amsterdam , this Amsterdam) and I was jet lagged beyond all belief.  I kept jacking the hourly rate up, hoping they would go away.  They didn't and when the rate reached to the point where I felt guilty about blowing them off, I spent the next 12 hours in a bus garage rebuilding corrupt index files.
  2. I taught myself C using Lattice C on the Amiga.
  3. My wife and I met on a blind date.
  4. The first time I earned money from something that I did on the computer was for a simple disk utility named "Easy Load" for the Commodore 64.  It was published in July 1985 edition of Compute!s Gazette.  That was back in the days when you had to type the code in from the magazines.  And they got it wrong and transposed some code, turning my little utility into a weapon of destruction.  I still got paid though.
  5. I once taught a dog to jump in and out a living room window on command.  My friend Jack used to be a band named Operation Pluto.  The leader singer, Bill, had one of those little, yappy type of dogs.   Bill's landlord wouldn't let the dog, named "Zero", live in Bill's apartment.   So Bill asked Jack to watch the dog for a days (Jack had this little tiny house) while he worked things out with the landlord.  

    The days turned to weeks and Jack got stuck taking care of the dog, and he wasn't terribly diligent about feeding Zero.   I decided to see if Zero could be taught any tricks.  Since Zero was always hungry, he was quite amenable to learning new tricks, especially if food was involved. 

    After a remarkably short amount of time and dog biscuits, I had taught Zero to jump out the living room window on command.  The window was above a couch, and he would use the couch as a launch pad. A similar command would launch the hapless mutt back in through the window.

    The next time Bill came over to the house for band rehearsal, I was already there.  He came in and the first thing he said was "Where's Zero?"  Zero was outside in the yard playing.  I innocently said, "I'll get him" and then yelled "Zero! In!".  About 5 seconds later, the dog comes flying in through the window. 

    Bill is stunned and more than slightly pissed off at me.  He said "What just happened?"  I replied, "We've been teaching Zero new tricks.  Zero! Out!".  The dog ran to the couch and jumped out the window.   I then had Zero jump back in once more, so Bill could appreciate the sound of the dog's claws scrambling against the side of house as he jumped up to the window and pulled himself back in.  Needless to say, Bill took Zero home again.

Now, I have to figure out who to tag. I pick Shawn, Andy, Mark, Renard, and Lou.  I was going to tag Ed Dague, but I don'thave his email address.

Thursday, January 04, 2007

Removing the Language Toolbar in Windows XP

This was completely copied from here.   This was bugging me to no end and I wanted to make sure that I had an easy to find copy.

Removing the Language Toolbar in Windows XP

  1. Click the Start Button.
  2. Select Control Panel option.
  3. Double-Click the Regional and Language Options icon.
  4. Click on the Languages tab.
  5. Click the Details button.
  6. Click the Language Bar button.
  7. Remove the checkmark from the Show Language Bar option.
  8. Click OK.

 

Wednesday, January 03, 2007

Ed Dague is more than a floating head

I just came across Ed Dague's blog. He's much more than a floating head on a an obscure web site. His comments on local media and politics are both interesting and intelligent. His take on Spitzer's naming of Michael Balboni as Deputy Secretary for Public Safety shows how 2 out of the three 3 local stations completely missed the hidden implications of that move.

He had to retire too soon from local TV for health reasons, but I'm glad to see that he has a forum for sharing his thoughts.

Tuesday, January 02, 2007

Sybase has left the building

We dropped support for Sybase's Adaptive Server Anywhere, effective 12/31/06.  It wasn't an easy decision, but it was the right choice for us.

About seven years ago, our main application used file based database storage, through the BDE.  As we were designing what would be the present day version of application, we evaluated many different client/server solutions.

  • It had to be designed for SQL.   Sounds like a given, but at the time file-based databases usually had SQL bolted on.

  • It had to require zero maintenance.  Many of our clients do not have an IT department that can run a database that requires hand holding or was difficult to install.

  • It had to be affordable.  We didn't want to have to charge for a database runtime for entry level pricing.

  • It had to have name recognition.  That makes a big difference when making sales presentations.

  • It had to support views, procedures, and the other good stuff that comes with a modern SQL database.

  • Had to run on Netware.  Many of clients were running Novell Netware as their network server and they wanted the data to stay on the server.

The president of the company wanted us to use Microsoft SQL Server.  It fit the list except for the last item.  Novell Netware.

That was hard one.  We needed a database that would be on the Netware server.  That meant it had to run on the Netware box.  The number of client server databases that run on Netware is a short list.  Back in 2000, the list included Oracle, Advantage, Pervasive, Interbase, Sybase SQL Anywhere.

We had ruled out Oracle because of cost and support concerns.  Advantage was a client server engine wrapped around a file based storage system and didn't have the name recognition.  Pervasive was the current incarnation of Btrieve and I had bad experiences with Btrieve in the past.  It didn't have the name recognition that we wanted and pricing was a concern.

Interbase met everything, but the name recognition.  At the time we were considering it, it was in the process of going open source and we had concerns over the long term viability.  Plus there was the name recognition.

That left Sybase's Adaptive Server Anywhere.  It had everything, but the name recognition.  It did have a feature that none of the others had.  It supported the T-SQL dialect of SQL that Microsoft SQL Server uses.  That allowed us to write code that would be compatible with both SQL Server and Adaptive Server Anywhere.  There were a few places where the SQL was different, but that was less than 1% of the time.

Sounds great, so we did end support at the end of 2006?  There were a few reasons that added up to a big reason.

Performance was a sore point.  All things considered equal, SQL Server was faster than Adaptive Server Anywhere.  The more complicated the SQL, the bigger the disparity in the performance.  We ended up migrating most of our clients that were on Adaptive Server Anywhere to SQL Server or the MSDE.

The Sybase native OLE DB provider (ASAPROV) had bugs that never got fixed.  Our Win32 applications use ADO and OLE DB to connect to the databases.  The native Adaptive Server Anywhere OLE DB provider would throw strange errors when working with client side record sets.  I submitted multiple bug reports to Sybase and they addressed some but not all of them.   Instead using their provider, we used the Microsoft's generic OLE DB to ODBC provider (MSDASQL) to connect to Sybase over ODBC.  That worked, but it added an extra layer to the mix.  Another concern was that Microsoft has deprecated MSDASQL and stated that it will not be available in 64-bit operating systems.  At some point a custimer was going to get a 64-bit edition of Windows and wouldn't be able to connect to the database.

The additional testing time became a concern.  Sybase releases frequent updates, and we found many bugs that were reported on our application were caused by bugs introduced in the latest and greatest patch from Sybase.

After talking to some of of clients, we made the decision over a year ago to end Sybase support.  We down to a handful of clients still using Sybase and we expect to be migrating their data within the next few months.  It has gone very smoothly.

Thursday, December 14, 2006

TiVo now placing ads on the delete screen

I finally saw TiVo's new advertising placements on the "Delete this recording?" screen. It was a one line blurb for Burger King that you could click into via the remote. It was not intrusive and didn't change how to delete a recording at all.

If TiVo can do stuff like that to improve their bottom line, I'm all in favor of it. They are saying: "Here's some advertising If you want to see it, click on it." I still have the choice in viewing the ad or not. If it keeps TiVo from going under or having to raise the subscription fees, then it's a great thing. I do wonder how the advertising is selected. Is it targeted by the show that was recorded, or is it more random?

One thing TiVo could do is to display subtitles when you fast forward through a commercial. That way if you were skipping over a commercial and you could still get the message of the commercial. You might see something that makes you stop and view that commercial. The technology is already inplace, subtitles are already encoded in the TV signal.

Thursday, November 09, 2006





It looks like Genesis is going back out on the road. Phil, Mike, and Tony will be doing 20 shows in Europe and 20 in the US for the "Turn It On Again" tour of 2007. Originally, the five members from the classic '70s lineup met to see if they could schedule a set of shows of "The Lamb Lies Down on Broadway", but Peter Gabriel declined due to scheduling conflicts. With Peter out, it didn't make sense to include Steve Hackett as the four member version of Genesis was only a tiny slice out of their history. You can view their news conference where they discuss all of this from this shiny link.


With just 20 shows in the US, I don't have my hopes up for a local appearance.

Wednesday, November 08, 2006

Sometimes there is a free lunch


I had a nice little surprise in my email yesterday. It was a gift certificate from VSoft Technologies for a one free license for Automise. Evidently I received it because I own a license for FinalBuilder, a fantastic tool for automating product builds.

With FinalBuilder, I can create a new build of one our applications from source control, through compiling, to building the installers, to sending out email to all interested parties that a new build is out.

Automise is basically FinalBuilder, but without the compiler specific tools. If you have a batch process that uses a motley collection of batch files and command line tools, then Automise will make your life simpler.

Tuesday, October 31, 2006

Why doesn't {$REGION} work above the interface?

Our Delphi code has some standard header comments at the top of the unit.  It has some information about the unit and who created it, and the purpose of that unit.  It also has some tags that the version contol system will use to expand.  On of those tags is the history of who edited that file.  On some of our older files, that list can get quite long.

So I figured since we moved to Delphi 2006, I could wrap those comments inside a {$REGION}/{$ENDREGION} block and collapse that block.  I added {$REGION} and {$ENDREGION}, but I couldn't get the collapse button to appear.  I tried it elsewhere in the code, worked just fine.  Tried a different unit, same problem.  Well it's Delphi 2006, maybe restarting it will fix it.  Nope.

It turns out that $REGION only collapses after the interface line.  I moved interface to above the {$REGION} line and all was good.  I couldn't find that factoid documented anywhere.

Tuesday, October 03, 2006

Best description of VMware/Virtual PC ever....

"It’s kind of like Las Vegas.  What happens in the virtual machine, stays in the virtual machine."

-Leo Laporte, September 17th 2006

http://www.twit.tv/sn50

Friday, September 22, 2006

The Terra Cotta Army: 1000 Chinese statues + 1 German art student

This story off of the AP wire I found greatly amusing. A 26 year old art student named Pablo Wendel joined the Terra Cotta warriors in Xi'an. His home made costume was so convincing it took a while for the security guards to find him. Posted by Picasa

Friday, September 15, 2006

How to be a programmer

I saw this on secretGreek today:

   intellisense
||
\/
code >>> compile >>>> run >>> success ;-)
/\ || ||
^^ \/ \/
^^ errors errors
^^ \\ //
^^ \\ //
^^ google
^^ ||
\\ \/
\<<<<<<< cut N paste

I have days where this is my programming model.


Thursday, September 14, 2006

Where is "Step Into" on my Visual Studio 2005 Debug menu?

I was debugging some code in VS 2005 when I noticed that I could no longer find "Step Into" on the debug menu.  I was already used to the keyboard short cut of F11, but I was wondering why it was no longer on the menu.  After some googling, I found a post from Paul Litwin's blog that explained how to fix it.  Basicly, the IDE thinks that you just don't want to see that menu item and you just need to reset your profile.   Here are the steps that Paul listed on his blog:

  1. Click the Tools->Import and Export Settings menu item
  2. Choose Reset all Settings
  3. Don’t save your settings
  4. Pick a new profile
  5. Profit!

OK, I couldn't resist the last one.  The $64,000 question is why this happened in the first place.  When Paul posted his blog entry, VS 2005 was still new and shiny and the thought was that a prior installation of VS 2005 (beta?) had some how screwed up the settings.  That didn't match my setup, I avoided the VS 2005 beta like the plague.  I do have VS 2003 installed, that may have confused VS 2005.  I also installed SQL Server 2005 before VS 2005, that too could confuse VS 2005.

Tech Tags:

Monday, September 11, 2006

Surfing with Takeshi Terauchi and the Bunnys

While skimming Boing Boing, I came across a link to some MP3s by Takeshi Terauchi. These files come courtesy of WFMU's Beware of the Blog. Takeshi Terauchi plays surf guitar music the old schol way, these MP3s were from recordings that are four decades old. They sound the Ventures with backed by a traditional Chinese opera (in a good way). WFMU has two complete albums, This is Terauchi Bushi, and Let's Go Classics.

Let's Go Classics is a surf guitar interpretation of traditional classical pieces like Blue Daube Waltz and the theme from Swan Lake. Very different.

Takeshi Terauchi started out as a sideman in Country/Western band, Jimmy Tokita & the Mountain Playboys. In 1962, Terauchi formed his first Eliki (Japanese slang for Electric) band, the Bluejeans, becoming Japan's first Surf band. In '66, Terauchi quit the Bluejeans and formed the Bunnys, the group behind the two albums on WFMU.

Thursday, September 07, 2006

THIS IS YOUR REPLACEMENT TAG

I'm on my third E-ZPass tag.  The battery in the first one died after about 5 years.  I have had the second one for another 5 years.  This time, the E-ZPass people sent me a new one before the current one died.

They did it the right way.  The new tag came in a small envelope with a letter and a return envelope.  The return envelope was for the old tag so it could be sent back.  It was a pre-paid envelope, a nice touch.  The letter explained that the new tag had to be sent back, or I would be charged for it's replacement cost. 

They clearly labeled the serial number of the old tag and of the new one.  I have two tags in use, I had to check each car to grab the right one.

The replacement tag had a eaisy to peel off sticker with the following text: THIS IS YOUR REPLACEMENT TAG.  Seems kinds of obvious, but if you are fooling around in your garage with the tags, that makes it easy not to mix up the old tag with the new one.

They could have mentioned which car the tag was for.  The only way to tell was by the serial number on the front of tag.  I could read it just fine, but it's in small print and that's not too friendly for AARP crowd.  That would be the only thing I would have changed with how they handle replacements.

More companies should study how the E-ZPass program is run.  The hardware just works, no fuss or muss.  We recentl;y drove from Albany NY, to Corolla, NC and just about every toll bridge and road accepted the E-ZPass.  The only exception was the Chesapeake Bay Bridge-Tunnel, and they are in the process of implementing an electronic toll collection system (E-ZPass).

Why you wont see Linux on Corporate America's desktops just yet

I came across this blog post by Robert Scoble while checking something for a GPS data collector that I writing, it has a useful data point to file in the back of the mind.  It has nothing to do with GPS data collection or even what I was googling for, but it explains a very good reason why you won’t see Linux on corporate desktops for the conceivable future.

 

I can sum it up for you with one sentence:  Linux fonts and their technology are no match to Windows and the Mac.

 

I'm not bashing Linux, I have a few things that run on it at home.  Not paying the Microsoft tax makes perfect sense for devices using embedded OS's.  I love my TiVo and the fact that it uses an OS that doesn't blue screen.  My $70 router/access point is running a pretty cool 3rd party firmware that could only be done if it was using Linux.

But on the desktop, I want a desktop that easy on the eyes.  The quality of the fonts and how they are displayed are a huge part of that.  Microsoft recognizes that and they spend a lot of time and money on fonts.  Consolas is a very nice typeface for pounding out code.  It's not everyone's cup of tea, but I like it. 

Monday, September 04, 2006

Project Bluemoon

Dave Zatz uploaded to YouTube a file that's relatively hidden on TiVo's web site which details the mysterious orgins of the TiVo device.  Tune and watch "Project Bluemoon".

You can also download the file as an .mp4 video directly from TiVo's web site (50 mb) from www.tivo.com/bluemoon

There looks like there are some subliminal text message in the video, I couldn't navigate YouTube's controls with enough precision to get the frames with the text.  It was a more subtle effect than the blipverts used in some GE commercials than ran back in May.

Friday, September 01, 2006

TiVo Series 3: Looks cool, pretty costly

I've been drooling over reading the various articles and blog postings over the soon to be released TiVo Series 3.

It has the stuff I want: Ethernet support built in, dual tuners, cablecard, High Def, big honking hard drive (plus external SATA port).  The rumored list price is $795.  That's a lot of shekels.  I have two Series 2 units and $800 is too much for my pocket.  Maybe next year if the prices drop...

I read a rumor that they are finally addiing WPA support for their 802.11g adapter.  I don't know how accurate that rumour is, TiVo has been planning on supporting WPA for nearly two years.

It's stunning that they have gone so long without it WPA.  When I first bought my TiVos, I had them on the home network using a wireless connection.  I did it a little differently than most people.  TiVo supports a limited range of USB connected wireless network adapters.  TiVo supports WEP, but not WPA.

WEP is fairly trivial to crack, while WPA is pretty secure.  Our neighborhood is pretty noisy on the 2.4ghz spectrum, everybody and their mother has a wireless router/access point.  I had set up the wireless part of my home network to be 802.11g with WPA security.  TiVo's wireless solution was not going to work.

There is more than one way to proivde wireless ethernet.  I picked up a couple of SMC 2870W wireless bridges.  A wireless bridge converts an Ethernet to 802.11 (a/b/g/n) signal.  It works transparently to the Ethernet equipped device.  That device thinks it's on a wired network and there are no drivers to install.  The 2870W supports WPA right out of the box.  The radio on the 2870W is lot more powerful than the run of the mill USB wireless adapters, it's like having mini access points on each machine.

With the TiVo, I use a cheap Linksys USB to Ethernet adapter and connect that adapter to the bridge.  The TiVo thinlks it's on a wireless network and everyone is happy.  There is an additional performance benefit by offloading the 802.11g processing from the TiVo to the 2870W.  The bottleneck becomes the 11 mb/s speed of the USB connection.  The TiVO CPU is not the fastest in the world.  Its roughly equivalent to Pentium 100, no need to have it tackle 802.11 processing if it doesn't have to.  That's probably the reason it didn't support WPA, just not enough horse power under the hood.

The Linksys/SMC combination worked very well, I never had any problems.  I had more problems using a Linksys 802.11g adapter on Windows XP box on the same network and in the same room as one of the TiVos.

I ended up running CAT5e cable through the house when I swtched to FiOS and now the TiVos are wired to the network. If you can do that, life is much easier.  With each TiVo directly on the network, I can transfer shows between the TiVos in real time.  I'm still hobbled by the Series 2 USB speed (or lack thereof), the Series built in Ethernet adapter would be cool to have.

Thursday, August 31, 2006

Diagnostic mode for Ipod Shuffle

Shuffle Lights

Main

Solid orange Charging, OK to disconnect.
Blinking orange Mounted, do not disconnect.
Solid green Connected to charger: fully charged, OK to disconnect.
Not connected: play. Light will turn off after two seconds.
Blinking green Paused: light will turn off after one minute.
Solid orange when you press a button Hold is on. To turn it off, hold the Play/Pause button for three seconds.
Solid green when you press a button Normal operation of that button. The light stays on as long as you press the button.
Blinking green and orange You're trying to play a song, but the shuffle is empty.

Battery Status (when pressed)

Green Good charge.
Amber Low charge.
Red Very low charge.
Off No charge.

courtesy of Craig A. Finseth

 

I just took a MSDart to the head and I don't feel so well right now.

One of clients went to run some of our applications on their Windows Server 2003 SP1 box and it wasn't very pretty. They got the error message:

"The procedure entry point DefWindowProcI could not be located in the dynamic link library msdart.dll"

Not a very helpful message. It happens when we access an ADO object within our code. We couldn't duplicate the problem on our W2K3 SP1 boxes. Some searches through Google seem to point the figure at a corrupted MDAC stack with SP1. When our client rolled SP1 back, the problem went away. Microsoft seems to be aware of a similiar problem as they have a KB article, 889114, that describes a similiar issue in Msdart.dll, but not with W2K3. I have also seen references to another article, 892500, but that one refers to DCOM permissions. I'm not sure if that one is relevant.

The question now is how to resolve this issue. How many ways can SP1 be installed on Windows Server 2003? Our boxes got SP1 through Windows Update and they have the right version of Msdat.dll.

Leave that thread priority alone

During initial e-Link web service development, I played around with lowering the priority of a background processing thread.  It didn't need to run in real time and having the service handling client requests was more important.  For a background housekeeping thread, I lowered it's priority to BelowNormal.

Well that didn't work quite the way I expected it.  That thread never ran, or it ran so seldom that it was effectively useless.  So I removed the calls to lowering the thread priority and life was good again.  I chalked it up to one of those thread things not to touch and moved on to other tasks.

Today, I saw a posting on the Coding Horror that explained why you should never mess with thread prioirities.  If you have a thread running at a lower priority and it enters a sleep state, it may never wake up if another thread with a higher priority continues to run.  That's an oversimplification, the actual details are described better here by Joe Duffy.

The moral of today's story is "Set up your threads at normal priority and let the operating system deal with scheduling them"

 

Thursday, August 24, 2006

Stream reading in C#

I was banging my head against the wall with an odd stream reading problem.  I was making a web service call as straight http, no SOAP, when I hit a snag reading the response back.  I was making the request with a HttpWebRequest object and getting the HttpWebResponse response back by calling the HttpWebResponse GetResponse() method.  From the response object, I was using GetResponseStream() to get at the content.  The data coming back was of variable size.  You would get a fixed size header block, plus a number of fixed sized data entries.  The header block had a field to say how many data blocks there would be.

Naively, I thought I could just use a BinaryReader on the data stream and read x number of bytes in for the header block.  The I would parse that header to the get number of data blocks and then call Read() for that number of data blocks.  Let's say that the header block was 64 bytes in size and the data blocks were 32 bytes.  I had logic like the following:

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

Stream stream = resp.GetResponseStream();
BinaryReader br = new BinaryReader(stream);

byte[] buff = new byte[Marshal.SizeOf(typeof(MyHeader))];

c = br.Read(buff, 0, 64);

GCHandle handle = GCHandle.Alloc(buff, GCHandleType.Pinned);
MyHeader header = (MyHeader)
Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(MyHeader));
handle.Free();

LogEntry MyLogEntry;

for (int i=0; i < MyHeader.EntryCount; i++)
{
  buff =
new byte[Marshal.SizeOf(typeof(LogEntry))];
 
c = br.Read(buff, 0, 32);
 
if (c == 32)
  {
    handle = GCHandle.Alloc(buff, GCHandleType.Pinned);
   
LogEntry = (LogEntry)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(LogEntry));
   
handle.Free();
 
}

}

The problem was that c was sometimes less than 32.  My bytes were disappearing.  I did some quick sanity check code like this:

c = br.Read(buff, 0, 8192);
TotalBytes = c;

while (c > 0)
{
  w.Write(buff, 0, c);
  c = br.Read(buff, 0, 8192);
  TotalBytes += c;
}

When I ran that, TotalBytes had the expected number.  What was I missing?  A little bit of googling found this bit of extremely helpful information from a guy named Jon.  I was reading while data was still coming into the stream.  The Read method is going to return before all of the data has been written to the source stream,  I had to read the stream into a holding array, by reading it as chunks, until there were no more bytes.  Then I could read the data from the array.  This was so obvious, I can't believe I missed it.  The ReadFully() method that Jon supplied worked quite well.

In case you were wondering about the GCHandle stuff, that was needed to marshall C style structures into C# structures.  Getting that bit of code to work right is another story....

 

Vista performance (or lack of)

I just installed the Beta 2 of Vista on one of my dev boxes.  It used to be my primary development box until I got a bright shiny new one last year.  About two weeks ago, the hard drive had a massive failure (it needs to be defraggled at this point) and I needed to rebuild the box.  Since we had the Vista DVD, I figured why not.  We set it up as a dual boot, with XP as the "other" OS.

After a couple of days of use, I've come the this conclusion.  Vista is a pig.  It's slow to boot and slow to run.  It's running on an older box, P4 1.7ghz with 1GB of RAM, but that box is fast enough to run XP without any issues.  It's slow enough that I am not going to use it as a day to day OS.  I'll run XP as the primary OS and I'll manually boot into Vista when needed.  The performance issues come with the beta tag, that's all and good.  I just can't use it.  It felt like OS/2 on a 386.

The fun part was trying to figure out how to get XP back as the default OS.  The new Vista Boot Loader is a strange and wonderful beast, but it's not your father's boot.ini file.  With boot.ini, it's a trivial process to set the default OS.  Vista requires you to use a new command line tool named bcdedit.exe.  With bcdedit, you can specify the default OS, by using the /default parameter and the GUID of the OS to run.

The GUID of the OS?  Where the frack do I get the GUID of the OS? If you run BCDEDIT /enum all, you get a listing of everything BCDEDIT knows how to load and the includes the GUID.  Except for my XP, which didn't get one.  Apparently that's a magic number, if you run bcdedit /default {466f5a88-0af2-4f76-9038-095b170dc21c}, the legacy OS becomes the default.

Since I'm using the Vista Boot Loader, I'll need to remember to restore XP's boot loader before I rip out this Vista Beta for next one.  In the Vista section of Tech-Recipes, they have helpful information on how to do that.  What you need to do is the following:

  1. Reboot using the XP CD-ROM
  2. Start the Recovery Console
  3. Run FixBoot
  4. Run fixmbr to reset the Master Boot Record
  5. Exit the Recovery Console
  6. Reboot

Lifehacker has some tips on how to setup the dual boot here.

Friday, August 18, 2006

Back from vacation

After a couple of weeks of vacation, I came back to the office to find my old development book DOA.  It was worse than a Blue Screen, it was a black screen with Read/Write error message.  My C: partition was filled with CRC errors.  I could copy some files off it, but most were toast.  A second parition on the same drive reported no errors, so I don't think it was a drive failure.  We did have a brown out while I was away, and that box only had a surge protector to save it.  Which it didn't.

I was planning on on installing the Vista Beta 2 in a VMware session on my main development box, but I think it will go on the old box.  I have to reinstall the OS anyways, why not go with the beta.  It's not like I have anything to lose at this point.

This post and the one before it was created with Windows Live Writer (Beta).  It's a pretty cool blog entry tool from Microsoft.  What is really nice about it is that it reads your blog setup and you can edit the posts in the look and feel of your actual blog.  It just works.  It didn't display the map below, but it showed where it would be.

Another cool feature is that you can edit previous posted entries and it replaces the old post with the new post.  This is my 3rd attempt on this post.

We spent a week down on the Outer Banks in North Carolina.  We have been going on and off down there for the last ten years and I like it alot.  This year, we stayed in Pine Island, on the southern end of Corolla.  I played a bit with Wikimapia and got this map of where we stayed:

 

The house in the lower left corner is where we stayed.  I tell you the name, but I want to rent it next year...

Dates are not numbers

One of the other developers that I work with had a question about inserting some date values into a SQL Server database.  The code in question is doing a batch insert and it was implemented as a series of INSERT statements and they get executed in large batches.  He was having some difficulty in getting the right values for the dates.  He was formatting the INSERT statement with the datetime values being formatted as numeric values.  The end result was that the dates were off by two days.  It was easy to fix and is yet another example of a leaky abstraction can bite you in the ass.

Dates are not numbers.  You have to consider them to be an intrinsic date type, even if the environment handles them internally as floating point numbers.  It's easy to get into the habit of adding 1.0 to datetime variable to increment the time by one day. SQL Server will happily let you do so, and so do many programming languages.  Oddly enough, Sybase Adaptive Server Anywhere wont let you treat datetime values as numbers, they force you to do it the right way.

The problem is how each environment anchors that numeric value to the actual calendar.  What day is day 0?   It depends on what created that value.  For SQL Server, the number 0 corresponds to 1900-01-01 00:00:00.  In the Delphi programming environment that we do a lot of work in, 0 works out to be 1899-12-30 00:00 (a Saturday for those keeping score).  If you pass in a datetime as numeric, when you query it back out of SQL Server, it's going to two days ahead of from your original date.

The 1899 date was define by Microsoft when they defined their OLE Automation data types.  The .NET runtime uses 0001-01-01 as it's starting point.  Those are not the only ways datetime can be encoded.  Raymond Chen did a decent round up on his blog.

The way we usually pass in datetime variables in non-parameterized INSERT statements is to encode the datetime variable as a string in the standard SQL-92 format (yyyy-mm-dd hh:mm:ss).

Tuesday, August 01, 2006

Hidden gotcha in FreeAndNil()

Time to go memory leak hunting in my service. I'm using AutomatedQA's AQTime 4, a really cool tool. I've used it's profiling features in the past, but not the memory leak detection. Since Delphi frees up your allocated memory when you exit the app and/or service, it's too easy to get sloppy and not free up singleton types of objects. Well, that makes it harder to find actual memory leaks as AQTime is going to flag everything that wasn't explicitly freed up as a leak. And that will lower the s/n ratio to make the too to hard to use.

So I'm pounding through the code and making sure that everything gets created, gets freed. Great fun, I recommend it for the entire family. I'm starting the service (actually the app version of service, but that's another posting), then exiting it after it initiatizes. That way I can clear out all of the obvious suspects and then turn my attention to the serious memory leaks.

So I'm in the middle of doing this, when one of the objects that I am now explicitly freeing is now blowing up when I free it. And not in a good way. This object, let's call him Fredo (not really the name), owns a few accessory objects (call them Phil and Reuben). In Fredo's destructor, Fredo is destroying Phil & Reuben. In Phil's destructor, Phil references another object belonging to Fredo and blows up because Fredo has gone fishing and doesn't exist anymore.

It took a while to figure out what was going on. You see Fredo wasn't actually fishing, Fredo was still around. Phil was accessing Fredo through a global variable (bad legacy code) because Fredo was a singleton. The variable that reference Fredo had been set to nil, even though Fredo was still in existence.

It took a while, but I figured where and how I had broken Fredo. The code that I had added to destroy Fredo looked like this:
FreeAndNil(Fredo);

The FreeAndNil() procedure was added back around Delphi 3 or so. You pass in an object reference, it free's that object and sets the reference to nil. Horse and buggy thinking for the managed code set, but useful in non-managed versions of Delphi. The problem was that FreeAndNil doesn't exactly work that way. Let's take a quick peek at that code:

procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil;
Temp.Free;
end;

It's setting the variable to nil before it free's it. It's not how it's documented and it caused my code to fail. There's nothing wrong with how FreeAndNil is coded, by setting the variable to nil first, other objects can check to see if it still exists and not try to access that object while it's being destroyed. I just would preferred that the documentation more accurately described the actual functionality.