I wrote my first useful Powershell script today. I had a directory of bitmaps and I wanted to convert them to PNG. This is a relatively easy task in .NET. All I had to do was figure out how to do this within Powershell. The script is as such:

foreach($file in Get-ChildItem *.BMP)
echo $file.Name
$image = [System.Drawing.Image]::FromFile($file)
$image.Save($file.ToString().Replace("BMP","png"), [System.Drawing.Imaging.ImageFormat]::Png)

As simple as this may seem, it really isn’t. First, the FromFile() method kept throwing an exception with NO description. After running FileMon did I see that it was looking in the wrong place for the file. As to why it didn’t bubble up a FileNotFoundException, I haven’t a clue (thanks Redmond). I also attempted to trap the exception, but seems to do nothing as well.

The second hurdle to get past was the fact that Get-ChildItem returns a System.IO.FileInfo type and the Name property contains only that — no full path. However ToString() does, and so that is where I called Replace() on. Once the pieces where in place, it worked like a charm.

I just started using a Bluetooth GPS receiver from Teletype. It seems to work well when I toss the device up onto the dash. Initially, I used the freely available BlackBerry Maps from RIM, however, the lack of voice guided turn-by-turn directions makes it useless while driving. After a quick Google search for BlackBerry GPS Guidance apps, I found TeleNav and this morning I downloaded it and signed up for the 30 day trial.

TeleNav worked surprisingly well. I was surprised that the voice prompts came from the speaker and didn’t require a headset. It’s recovery from a wrong turn wasn’t as fast as the nav system in my wife’s minivan, but I’m guessing that that is a function of the data link between my 8700 and TeleNav’s servers. Furthermore, the full color interface and 3D map graphics made for a pleasant interaction with the application.

IMHO, I do not have a problem with the monthly fee ($9.95/mo). When you look at TeleNav’s side-by-side comparison to a conventional nav device (like a Garmin), it makes a lot of sense. For example, if I installed a Pioneer nav unit, with XM Traffic, I’d be on the hook for a monthly fee, and oh, BTW, TeleNav gives you the same routing around traffic. So when you look at it like that, it’s probably a better deal.

At this point, I’m awaiting a call from a TeleNav sales rep regarding bulk pricing. I’ve been looking for a nav solution for our fleet of 50 vehicles and this may be it. I can leverage the benefit of a BB in each of my technicians hands as well as giving them live, voice guided, turn-by-turn route guidance. What would be the ultimate, is to interface it with our field force automation system, so when we dispatch a call we can provide directions on the fly. That’d be phat.

I’ll keep everyone posted.

OK, maybe I’m being a snob, but I think that the global.asax file is for kids who don’t know anything about HttpModules. Any web app developer worth their salt would prefer to code up an HttpModule than waste time in a file that, IMHO, is just weird. Anyway, this is what I pimped out the other night in my HttpModule

public void Init(HttpApplication context) {
((System.Web.Profile.ProfileModule)context.Modules["Profile"]).MigrateAnonymous +=
new System.Web.Profile.ProfileMigrateEventHandler(ProfileInfoModule_MigrateAnonymous);

void ProfileInfoModule_MigrateAnonymous(object sender, System.Web.Profile.ProfileMigrateEventArgs e) {

That’s the kind of stuff you AIM your fellow coders about. Weeee!

Ok, so I spent probably a week and half banging my head against the keyboard trying to figure out why my Polycom 601 wasn’t receiving audio from an FXO voice-port connected to the PSTN on my Cisco 2620XM router/gateway. I can’t tell you how many times I typed show run, scratched my head, ran trace after trace, only to find myself at Cisco’s IP Communications and Video Forum. Here I started search “one way audio”. Well, this is where I found my silver bullet.

I finally came across a response to a post about a one way audio problem. The responder referenced Troubleshooting One Way Voice Issues. OMFG! All I had to do was read the title to the Ensure That IP Routing Is Enabled on the Cisco IOS Gateway and Routers section to realize that in the show run was no ip routing. Well, one quick change to that and blamo! Voice! Now all I have to resolve is some echo issues, but that shouldn’t be too difficult.

At work we are in the process of migrating from a legacy accounting system to Microsoft’s Navision Attain. The legacy app is running on a SCO OpenServer 3.2v2 box. The guy supporting the app wrote a dump utility that creates ASCII files of the data. The trick to get the data from the box.

The box has no NIC. It works completely with serial boards. Do you know how long it takes to cat a 5MB file over a 19.2k serial link? To long to even figure it out. Anyway, I needed to compress the data before I moved it off the box. Um, ok, then WTF do I do with it then? Can’t cat a .tar.Z file. Kermit!

The SCO box has nothing installed for any sort of file transfer (XMODEM, YMODEM, ZMODEM, or Kermit). Fortunately after spending an inordinate amount of time Googling, I found that the folks behind Kermit, Columbia University (in nYc, boyeee!) had a compiled binary for my version of SCO (!). No shit, right? Yes shit!

Ok, so I now have the Kermit binary on my Windows XP box. If you remember the aforementioned problem; no file transfer protocol implementations on the box. Now, how do I get the file to the SCO box? The SCO box has a command, doscp, that allows me to copy a file from a DOS floppy. Therefore, via sneaker net, I marched into the computer room and slipped that 3.5″ floppy from my PC into that bad-boy. Well, long story short, it fuckin’ worked! Oh yeah, pimp status +1. Furthermore, SecureCRT has fair Kermit support. But, um, we have a problem.

The files seemed to be corrupt. Back and forth I went with moving files from the SCO box to my machine. I was able to ruleout any corruption from Kermit because I was able to move raw text files, and an uncompressed tar archive across the link and they worked just fine. Now, WTF is going on? This is where RTFM is actually your friend (yes, you actually heard me say that).

SCO’s compress command is a little left of center when it comes to the standard, or so it seems to gzip. I noticed in the compress man page a -H switch, which changed compress to the use the LZH compression algorithm. Furthermore, the gzip man page says that it works with compress with the -H switch. When I used this switch, gzip’s -d output changed. Acha! We are on the path to ritcheousness. The error that gzip barfed out was “invalid compressed data -- Huffman code > 32 bits“.

Well, back to the compress man page. Compress also takes a -b switch, which allows you to specify the bit size used in compress. By using compress with -H and -b 32, I was able to get a good decompress from gzip. Pimp status +2! You must also provide the -i switch to Kermit, which lets Kermit know that you are transfering a binary file. Othewise, you get sporatic results. Now I am moving the full tar from the box as we speak. It’s over 4 megs so it’ll take close to an hour to move.

Anyway, for posterity, here is the command I used to build my tar:

tar cf - filedump | compress -H -b 32 > filedump.tar.Z

And the Kermit command:

kermit -i -s filedump.tar.Z

In the never ending quest for the ultimate RSS feed reader, I just installed Sage for Firefox. This Firefox extension resides inside the browser and integrates directly with Firefox’s live bookmarks. RSS feeds are displayed in a browser tab. The formatting is based on either an embedded CSS stylesheet, and or an external sheet.

Once installed, Sage requires one change. The default stylesheet does’t handle advanced HTML formatting in the entry all that well. Of course, not too suprising, a Safari like stylesheet has been developed for Sage. The stylesheet resides here at DeviantArt.com. Oh, and to give credit where credit is due, I found about the Safari stylesheet at StarvingArtist.

I was using RssBandit prior. Don’t get me wrong, RssBandit is a fine application, but, it’s another application. There’s just so many apps one man can run. In fact, if it wasn’t for the fact that Thunderbird can’t sync with my BlackBerry, I would migrate off of Outlook. Anyway, enjoy Sage.

datetime comparisons in T-SQL aren’t always a walk in the park. One of the most annoying things that someone would need to overcoming is filtering solely on the year, month, and day component of a datetime field. This is further complicated by how .NET initializes a DateTime object.

When a DateTime object is instantiated without secifying the time, it is set to 12:00AM (midnight). When you pass the DateTime object to an SqlParameter, the following is sent over the wire:

     exec GetContracts @CreationDate = 'Aug 13 2004 12:00:00:000AM'

A further complication is that even if you pass creationDate.ToShortDateString() (assuming of course that your DateTime object in code is ‘creationDate’) to the Value of your SqlParameter, the afortementioned value is still passed to the stored procedure. This is because the stored procedure parameter is typed as datetime. Now, how do you overcome this?

With values in the table such as ‘2004-08-13 13:02:44.767’, you’ll never be able to match ‘Aug 13 2004 12:00:00:000AM’, and therefore no rows will be returned. The way I have overcome this problem is to make use of DATEDIFF and the dayofyear DATEPART. By using the following in your WHERE clause:

     DATEDIFF(dayofyear, @CreationDate, Contracts.CreationDate) = 0

This will return 0 whenever the day of the year is the same in both the table, and the stored procedure parameter. Any other day will either cause DATEDIFF to return a non-zero value. You can also use this if you want everything from this date and on (or before) by changing the comparitor to > or < as appropriate. Sproc on!

The ability to page in SQL Server is one of those things that everyone wants, but can’t quite seem to get from Microsoft. Many ideas have been posted, each claiming to be _the_ way to do it. In the spirit of mine is better than yours, I’ve implemented my own paging scheme.

A feature that is in the upcoming version of SQL Server is the ability to supply a variable to the TOP keyword. Well, as it turns out, this functionality does exist in SQL Server 2000. The only difference is the syntax. To limit the number of rows returned from a query based on a variable is to use SET ROWCOUNT @Foo. Don’t forget, however, to reverse that after the query by setting ROWCOUNT to 0.

The principle of which this works is that I return all of the primary keys in a table into a table datatype up to and including the record that i want to start at. Then I grab that value by selecting the TOP 1 from that temp table, ordering by the value, descending. Now I have the starting primary key value.

At this point, it’s a matter of looping through the records, row by row until I have filled my cache table with a single page’s worth of data. Once that is complete, I return the contents of the cache table. In addition, in the form of an OUTPUT param, I return the total number of rows in the table. I have this value as a result of a sanity check that stops the proc if we are requesting a page of data that is past the end of the table.

I hope this sproc finds you well.