Visual DataFlex 2009 – 15.1 Released

See here for product details.

Why Some Files Are Not Migrated to the Latest VDF Revision

Why Some Files Are Not Migrated to the Latest VDF Revision is the title of my first blog entry, published this morning, on the DAW Development Team blog.

Look for future Visual DataFlex-related posts by myself and other members of the development team here.

Accessing Amazon Web Services with C#

I have been working on a personal C#.Net project that uses Amazon’s Web Services for a couple of years now. It’s been working quite well. I use this project as a personal database and learning tool for .Net.

Quite recently (August 2009) Amazon once again changed the name of their web services API and also the rules for making call to it, now requiring cryptographic signature authentication. While Amazon provides code samples, for some odd reason the only (yet new) C# SOAP sample provided by Amazon uses the dated and likely soon obsolete Web Services Enhancements (WSE) class library instead of Windows Communication Foundation (WCF). I assume this sample is for developers still using .Net 2.0, but a sample using more current technology would have been appropriate, as well.

I searched the web for a suitable sample to implement the signature authentication using .Net 3.5 and eventually came across a very appropriately titled blog entry: Signing Amazon Product Advertising API requests — the missing C# WCF sample, by Oren Trutner. Attached to Oren’s very appropriately titled blog entry are 3 samples that make implementing the calls using WCF very straightforward.

Great work and thanks, Oren!

Visual DataFlex 2009 – 15.1 first beta is available

Details are in the build notes.

My personal favorites are numerous Studio improvements, including opening each file on only one tab, instead of 2 separate tabs for designer and source code, and an updated Workspace Explorer which now shows all files included in the current project.

See the forum post/release notice for details.

The IT Crowd

I was recently introduced to this Brit TV show when someone emailed me a link to the “You can break the internet” YouTube clip. I love it! Now I’ve been watching season 3 online and really would like to see more. We do get BBC America now, but that apparently isn’t who broadcasts it. :-(

Remote Control Support is Wasting My Time!

It seems to me that “remote control” technical support (using some version of Citrix or similar technology) is making computer support even worse than it was before. I have now been on the receiving end of remote support 3 times in as many months and I am quite unhappy with it. Without fail, technicians using remote support have wasted a lot of my time and not in a single case did they actually solve the problem.

During the same time period of time, I spoke to 2 support technicians via chat or telephone without them logging on to my system. They actually listened to my explanation of the problems and solved them, both in a brief amount of time.

It just seems like remote control gives bad support technicians an excuse to waste a lot of time poking around on a PC, hoping that they will stumble over some really obvious cause for the problem. In all 3 cases where this has happened to me, the techs did not listen very well to my problem description and were falling all over over themselves to try and get access to my PC so they could poke around.

The latest incident was after switching to a new internet service provider (ISP) a few days ago. Outlook was stuck in the Outlook Send/Receive Progress window, with all of my email accounts not showing any progress. To me, this appeared to be a systemic issue affecting all accounts, like the ISP blocking port 25 (Googling this a bit and looking back at my notes from similar issues with other ISPs confirmed my suspicion).

When I called the ISP’s tech support, the first level tech had no clue what I was talking about (this in itself was a big warning sign to me, since this is clearly a very common problem that every ISP tech should be aware of). After I explained the problem, the tech just absolutely wanted to access my PC. No additional questions, no listening to what I was saying, just “let me take a look”. So I indulged him for about 20 minutes, during which he poked around my email account settings and changed the outgoing server settings for my gmail account (the only one I allowed him to look at) to some other account with the explanation that all outgoing email had to go through their servers first (What the #### ?!?). Eventually, after not being able to get that going, he relented and connected my to the next tier tech support person.

The second tier tech, after listening to my problem description said “sounds like we need to unblock port 25 for you” and did just that. About a minute later, my email was working again. Magic!

Now, to be fair, the first level tech was clearly clueless and could have wasted just as much of my time without remotely connecting to my PC. I also understand that many callers to tech support aren’t necessarily computer savvy, but that would have made no any difference in this case in solving the problem (other than that a less experienced customer might have been stuck with a bad solution, like channeling all outgoing emails through this ISP’s servers, or even have their working email settings completely messed up by this tech).

I’m not saying that being able to remotely access a PC is bad; I use this technology myself and I love it. However, it should be used to aid, not substitute for, proper problem solving techniques. Ask relevant questions, analyze the problem and go from there.

Encapsulating Code for Easier Maintenance

Code encapsulation simplifies maintenance. The more abstracted and isolated a routine is from a larger code base, the easier it will be to adjust, test, and if needed, replace later.

This came to mind recently when I wrote a short routine that determines if a mapped drive is a local drive:

[DllImport("mpr.dll")]
static extern uint WNetGetConnection(string lpLocalName, StringBuilder lpRemoteName, ref int lpnLength);

// returns whether the current drive is local
internal static bool IsLocalDrive(String driveName)
{
    bool isLocal = true;  // assume local until disproved

    // strip trailing backslashes from driveName
    driveName = driveName.Substring(0, 2);

    int length = 256; // to be on safe side
    StringBuilder networkShare = new StringBuilder(length);
    uint status = WNetGetConnection(driveName, networkShare, ref length);

    // does a network share exist for this drive?
    if (networkShare.Length != 0)
    {
        // now networkShare contains a UNC path in format \\MachineName\ShareName
        // retrieve the MachineName portion
        String shareName = networkShare.ToString();
        string[] splitShares = shareName.Split('\\');
        // the 3rd array element now contains the machine name
        if (Environment.MachineName == splitShares[2])
            isLocal = true;
        else
            isLocal = false;
    }

    return isLocal;
}

There is a post on stackoverflow asking how to do this, and, like many others, it has several answers showing several ways to do this. So, is my method correct? This code seems to work, but I’ve been programming long enough to know that code that “seems to work” doesn’t necessarily work in every circumstance and could have other negatives, such as performance issues.

So, knowing that this code I may have to tweak or replace at some future point in time, I will try to encapsulate it as much as possible to make it easier to work with in an isolated manner later. By keeping the code in a separate method, I can easily use a unit test to try it in various test scenarios without affecting any other code.

Of course, this is a very simple scenario, which made it perfect for this post. It can be much tougher to abstract and isolate more complex code, but that doesn’t mean we shouldn’t strive to do so whenever possible.

Pointless error messages

Once in a while, I try to send an email in Outlook and I get an error

An internal support function returned an error.

How is this error helpful in any way?

What function and what error and what can I do about it? If you’re not going to tell me that, then why bother telling me anything?

It tells me, the user, that the email wasn’t sent, but beyond trying it again, there’s absolutely nothing useful this error tells me. It’s not telling me a reason for the error and it’s not giving me any information for improving what I did to improve the outcome the next time I try to do the same thing.


So, what do I take away from this experience as a programmer?

  • If I create an end-user type of message, I’ll try to limit the amount of technical information in the message and try to tell the user what to do to resolve the error if that is not apparent from the message itself.

    For example, for a typical end-user, a more appropriate message might have been:

    An error occurred when trying to send this message. Try sending it again.

  • If I create a more technical message, one that contains more useful information for the programmer (me), I’ll try to expose enough technical detail information so that when the message gets back to me, I’ll know where to look in my code to find the problem.

    For example, a better technical message might have been:

    Internal function XYZ returned error 1234. Please report this error detail to your developer. Try sending the message again.


Tip: You don’t need a screen shot to capture an error message

I get a lot of screen shots in my email, most of error messages. Don’t even get me started on Word documents containing 4 MB BMP screen shots and then attached to an email. Or better yet, a Word document with a bunch of screen shots, which are then discussed in the email, so I have to keep switching back and forth.

The apparently best kept secret of a standard Windows error message is that it can be captured as plain text using Ctrl+C, since at least Windows XP. This is far better for emailing off to report an error, since it produces a far smaller email message, and it allows the recipient to select and copy text.

Typically, when someone sends me an error message screen shot, the first thing I do is to search for the exact error message text in one or more places (e.g. help, KBase, forums, etc.) If the error was sent to me as a screen shot, I now have to type in the whole error message. If it was sent as text, I can simply select and copy it, reducing the time it takes and the likelihood of transcription errors.

This works for any Windows message box. For example, this line of C# code

MessageBox.Show("This is error # ZAV45273###Y: you forgot to finagle the gizmo", "ERROR");

Displays this Windows message box:

When this message box has the focus, you can press Ctrl+C to copy it, resulting in this text:

—————————
ERROR
—————————
This is error # ZAV45273###Y: you forgot to finagle the gizmo
—————————
OK  
—————————

Now, if someone sends me the text version of the above error, it’s really easy to copy the complex error number and be sure I got it right.

Can I replace my keyboard’s Scroll Lock with an Insert Lock?

I never use my keyboard’s Insert key; well, not never, but never on purpose. Usually if I use it, it’s like this:

type type type, type type type, type (accidentally hit Insert) type, type type oh man!

Then I wind up doing one of these:

  • Undo undo undo, press Insert again (intentionally this time to un-toggle over type mode), then retype what I just undid, then continue typing normally.
  • Copy what I just typed because I don’t want to lose it, then undo undo undo, press Insert again, then paste what copied from before, then continue typing normally.

So this is usually a wonderful way to derail my train of thought.

My Cyberpower PC came with this great Logitech Y-SU61 keyboard, which is quite simplistic (no extra function keys, lit-up buttons, just a nice, full size keyboard, yet light with a small footprint) and replaces the typical Insert-above-Delete key arrangement with an extra tall Delete key. I love it! When I got it, I had high hopes this would become the new keyboard standard; however, this PC and keyboard are probably around 4 years old now, so it appears a new standard has not taken root.

Yet, I’ve been to cheap and lazy to go out and buy 2 more for the other 2 PCs I use on a daily basis. When I searched for this keyboard today, it appears to be discontinued, but there must be others with this feature.

The other alternative would be some way to simply disable (like the Caps Lock and Scroll Lock keys, neither of which I ever use) or reprogram the Insert key.