The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,862 other subscribers

Archive for April, 2010

Maximum URL lengths

Posted by jpluimers on 2010/04/20

A client recently asked me what space should reserve to store URLs in their DBMS.

The plurality in the topic title is a hint: different systems have different limits on URL lengths.

But first:

Don’t use long URLs

If you use long URL’s (longer than say a coupe of 100 characters), then usually you have a problem.

First of all: short URL’s are easier to remember, index and search.

Second: long URL’s can pose problems.
It might be that your browser and server support them.
But a user might be behind an intercepting proxy (sometimes invisible to both you and your user) that imposes a URL limit.

In stead of long URLs with a HTTP GET, use shorter URLs with a HTTP POST. Read the rest of this entry »

Posted in .NET, ASP.NET, Delphi, Development, Firefox, Internet Explorer, Opera, Safari, Web Browsers, Web Development | 8 Comments »

Vliegen #Schiphol is weer begonnen

Posted by jpluimers on 2010/04/19

Kort na elkaar zijn op de Zwanenburgbaan deze vliegtuigen opgestegen:

Deze is opgestegen op de oostbaan, heeft rondje Wieringermeer gedaan, daarna stukje Noorzee en lijkt nu over Zandvoort terug te komen.
Wellicht luchtmetingen?
(Later: correctie: Kustwacht, dus vliegt laag).

Met dank aan http://www.flightradar24.com/ (inzoomen op Schiphol).

–jeroen

Posted in Schiphol | Leave a Comment »

Simple solution for “VMware Communities: Problem installing vConverter 4.0.1”

Posted by jpluimers on 2010/04/16

Sometimes you get an error message when trying to install VMware Converter 4.x:

A previous installation/reboot is still pending. Please reboot to complete the installation and try again to install.

Contrary to most solutions, this one is easy:
The message means “vConverter is already installed“.

So: check if you did not have it installed (or a previous version) before starting with hard measures :-)

–jeroen

Posted in Power User, Virtualization, VMware, VMware Converter | Leave a Comment »

.NET/C# – TEE filter that also runs on Windows (XP) Embedded – update

Posted by jpluimers on 2010/04/15

Last week, I posted a C# implementation of the tee filter from Sterling W. “Chip” Camden.

Since then I have modified it slightly.
Not because the implementation is bad, but because some pieces of software play dirty when saving their redirected output.

One of those applications is SubInAcl, otherwise a great tool for showing and modifying ACL and Ownership information of Windows NT objects (files, registry entries, etc).

However, when redirecing output or piping it, it writes a zero byte after each byte of text.
I’m not sure why: it might try to face some Unicode output, or just be buggy.

The new sourcecode is below. You can also download the project and binary as tee.C#.7z (you need the freeware 7zip compression tool to decompress this).
Read the rest of this entry »

Posted in .NET, ASCII, C#, C# 2.0, CommandLine, Development, Encoding, Software Development, Unicode, Visual Studio and tools | Leave a Comment »

Breaking changes in .NET 4.0

Posted by jpluimers on 2010/04/14

Every major release of software will bring great new stuff, but the price of upgrading from a previous version is that some stuff will break.

.NET 4.0 brings a lot of nice stuff as well, but there are a few things that break.

There is a nice Breaking changes in .NET 4.0 – Stack Overflow article on this.

The article is now a community wiki, and refers to these pages:

Since the article is a community wiki, expect it to be updated over time.

I wonder what these changes will bring (and break) in the upcoming Delphi Prism release (the datasheet is out now, the product should be out before the end of may).

–jeroen

PS:

If you do not have an MSDN subscription, but still want to see if things break for you, try one of these:

Scott Guthrie has a nice post on the bells and whistles of VS2010.

Posted in .NET, ASP.NET, C#, C# 4.0, Delphi, Development, Prism, Software Development, Visual Studio and tools, Web Development | 1 Comment »

*nix – Mastering the VI editor

Posted by jpluimers on 2010/04/13

Every once in a while I need to do some text editing in a *nix environment that has a minimum toolset installed.

Which means: use VI.

VI is a versatile text editor from the early *nix days, but it is not straight forward to use.
Since I don’t use VI often enough, I tend to forget some of the commands.

Time to share my favourite VI link: Mastering the VI editor edit: link rot, now it is at Mastering the VI editor.

The link points to the basic stuff, but the page contains most of what you ever want to know about VI.

–jeroen

PS:
If possible, I install the JOE text editor on systems where I am admin.
JOE uses WordStar like key bindings, and supports UTF-8. Talking about “something old, something new” :-)

Posted in *nix, CommandLine, Development, Encoding, Power User, Software Development, Unicode, UTF-8, UTF8, vi | 1 Comment »

Visual Studio 2010 RTM will be available on MSDN at 10AM PST *today*

Posted by jpluimers on 2010/04/12

For MSDN subscribers:

Visual Studio 2010 RTM will be available on MSDN around these times:

  • 10:00 PST
  • 13:00 EST
  • 17:00 UTC

Other time zones: see this Worlclock link.

Sources:

Posted in .NET, Delphi, Development, Software Development, Visual Studio and tools | Leave a Comment »

Classic UI mistake – OK/Cancel buttons for a Yes/No question.

Posted by jpluimers on 2010/04/12

Just unlinked/linked my DropBox account because of some synchronization issues, then got this messagebox:

—————————
Dropbox
—————————
There is already a folder in your My Documents folder called ‘My Dropbox’. Do you want to merge all the existing files in that folder into your Dropbox?
—————————
OK   Cancel
—————————

Sometimes I wonder if programmers ever are going to learn to get the basic UI things right :-)

(This was in version 0.7.110.0 of dropbox)

–jeroen

PS:
I absolutely love the functionality of dropbox, and to their credit: they do get most of their UI right.

Posted in .NET, Delphi, Development, Software Development, UI Design | 7 Comments »

Stopping percentage expansion in a Windows batch file

Posted by jpluimers on 2010/04/09

A while ago, I asked a question on percentage expansion in batch-files on superuser.com: a great site with great answers, similar to stackoverflow.com and serverfault.com , but now for asking “Power User” kind of questions.

The percentage sign (%) in URL‘s is to escape (or  URLencode) characters that should not be in a URL itself.
(Note that the old new thing had a very interesting article on URL encoding: there are many different opinions on how to to this ‘right’, and a few of these ‘right’ opinions are not always compatible with each other).

In Windows batch-files and the command-line, the percentage sign is used to expand environment variables, arguments and for loop indexes.
To make life ‘easier’, inside a batch-file, the percentage sign has a slightly different meaning than on the command-line itself.

This can break your batch-files when you use URL encoded parameters.
It does not matter if these parameters are quoted or not: cmd.exe expands them, unless you escape them properly.

So, the command for downloading the URL with wget (similar to curl) differs from running it on the plain command-line or in a batch-file.

Escaping percentage in batch-files

So the best way to escape percentages in batch files is to double them: each % becomes %%.
There is even a very old (MS-DOS era!) knowledge base article about this topic, that I just found when doing the research for this blog article :-)

URL decode

As a sidenote: manually decode thesed escaped URL’s is always a pain.
There are many sites that can do URL decoding on-line.

PS: This was the original question: How can I stop percentage expansion in a batch file? – Super User.

Posted in *nix, Batch-Files, CommandLine, Development, Encoding, Power User, Scripting, Software Development, URL Encoding, wget | 3 Comments »

.NET/C# – TEE filter that also runs on Windows (XP) Embedded

Posted by jpluimers on 2010/04/07

The usage of tee - image courtesey of Wikipedia

The tee command stems from a *nix background.
It is a command-line filter that allows you to deviate a stream from the regular stdout/stdin redirected pipeline into a file.

Recently, I needed this in a Windows Embedded Stadard (a.k.a. WES) system for logging purposes.
This way, a post-install-script (similar to the Windows Post-Install Wizard, but command-line based) could log to both the console and a log-file at the same time.

WES is the successor Windows XP Embedded (a.k.a. XPe), which is a modularized version of Windows XP.
Se WES usually means that you don’t have the luxury of everything that Windows XP has.
This in turn means that you need to be careful when selecting external tools: a lot of stuff that works on plain Windows XP won’t work.

There are various Win32 ports of tee available.
This time however, I needed a Unicode implementation, so I searched for a .NET based implementation.

Windows PowerShell 2.0 does contain a tee implementation, but:

  1. We don’t have the luxury of having PowerShell in our WES image
  2. PowerShell tee first writes the contents to e temporary file, which interferes with how we build this WES image.

Luckily Sterling W. “Chip” Camden started with such a .NET implementation of tee – in Visual C++ – back in 2005.
Though his TEE page indicates it is based on .NET 1.1, his current implementation is done in Visual Studio 2008 using C++.

Now that is a problem for the targeted WES image: that image is based on .NET 2.0.
But when using Visual C++ in .NET, you need additional run-time libraries (for instance the ones for Visual C++ 2005, or the ones for Visual C++ 2008).

If you don’t have these installed, tee.exe does not start, and you get error messages like this on the command-line:

K:\Post-Install-Scripts>tee
The system cannot execute the specified program.

and entries like this in the Eventlog:

Event Type: Error
Event Source: SideBySide
Event Category: None
Event ID: 59
Date: 01/04/2010
Time: 19:09:22
User: N/A
Computer: MYMACHINE
Description:
Generate Activation Context failed for K:\Post-Install-Scripts\tee.exe. Reference error message: The operation completed successfully.

The odd thing in this error message is “The operation completed successfully”: it didn’t :-)

Anyway: translating the underlying C++ code to C# is pretty straightforward, so:

The C# implementation

I did change a few things, none of them major:

  • replaced some for statements with foreach
  • renamed a few variables to make them more readable
  • added using statements for stdin and stdout
  • added try…finally for cleaning up the binary writers
  • moved the logic for duplicate filenames into a separate method, and moved the moment of checking to the point of adding the filename to the filenames
  • moved the help into a separate method
  • added support for the -h (same behaviour as –help or /?) command-line argument

The implementation is pretty straightforward:

  • Perform parameter parsing
  • Catch all input bytes from the stdin stream
  • Copy those bytes to both the stdout stream, and the files specified on the command-line
  • Send errors to the stderr stream
  • Do the proper initialization and cleanup

This is the C# code:

using System;
using System.IO;
using System.Collections.Generic;
// Sends standard input to standard output and to all files in command line.
// C# implementation april 4th, 2010 by Jeroen Wiert Pluimers (https://wiert.wordpress.com),
// based on tee Chip Camden, Camden Software Consulting, November 2005
// 	... and Anonymous Cowards everywhere!
//
// TEE [-a | --append] [-i | --ignore] [--help | /?] [-f] [file1] [...]
//    Example:
// 	tee --append file0.txt -f --help file2.txt
//    will append to file0.txt, --help, and file2.txt
//
// -a | --append	Appends files instead of overwriting
// 			  (setting is per tee instance)
// -i | --ignore	Ignore cancel Ctrl+C keypress: see UnixUtils tee
// /? | --help		Displays this message and immediately quits
// -f			Stop recognizing flags, force all following filenames literally
//
// Duplicate filenames are quietly ignored.
// Press Ctrl+Z (End of File character) then Enter to abort.
namespace tee
{
    class Program
    {
        static void help()
        {
            Console.Error.WriteLine("Sends standard input to standard output and to all files in command line.");
            Console.Error.WriteLine("C# implementation april 4th, 2010 by Jeroen Wiert Pluimers (https://wiert.wordpress.com),");
            Console.Error.WriteLine("Chip Camden, Camden Software Consulting, November 2005");
            Console.Error.WriteLine("	... and Anonymous Cowards everywhere!");
            Console.Error.WriteLine("http://www.camdensoftware.com");
            Console.Error.WriteLine("http://chipstips.com/?tag=cpptee");
            Console.Error.WriteLine("");
            Console.Error.WriteLine("tee [-a | --append] [-i | --ignore] [--help | /?] [-f] [file1] [...]");
            Console.Error.WriteLine("   Example:");
            Console.Error.WriteLine(" tee --append file0.txt -f --help file2.txt");
            Console.Error.WriteLine("   will append to file0.txt, --help, and file2.txt");
            Console.Error.WriteLine("");
            Console.Error.WriteLine("-a | --append    Appends files instead of overwriting");
            Console.Error.WriteLine("                 (setting is per tee instance)");
            Console.Error.WriteLine("-i | --ignore    Ignore cancel Ctrl+C keypress: see UnixUtils tee");
            Console.Error.WriteLine("/? | --help      Displays this message and immediately quits");
            Console.Error.WriteLine("-f               Stop recognizing flags, force all following filenames literally");
            Console.Error.WriteLine("");
            Console.Error.WriteLine("Duplicate filenames are quietly ignored.");
            Console.Error.WriteLine("Press Ctrl+Z (End of File character) then Enter to abort.");
        }

        static void OnCancelKeyPressed(Object sender, ConsoleCancelEventArgs args)
        {
            // Set the Cancel property to true to prevent the process from
            // terminating.
            args.Cancel = true;
        }

        static List<String> filenames = new List<String>();

        static void addFilename(string value)
        {
            if (-1 == filenames.IndexOf(value))
                filenames.Add(value);
        }

        static int Main(string[] args)
        {
            try
            {
                bool appendToFiles = false;
                bool stopInterpretingFlags = false;
                bool ignoreCtrlC = false;

                foreach (string arg in args)
                {
                    //Since we're already parsing.... might as well check for flags:
                    if (stopInterpretingFlags)  //Stop interpreting flags, assume is filename
                    {
                        addFilename(arg);
                    }
                    else if (arg.Equals("/?") || arg.Equals("-h") || arg.Equals("--help"))
                    {
                        help();
                        return 1; //Quit immediately
                    }
                    else if (arg.Equals("-a") || arg.Equals("--append"))
                    {
                        appendToFiles = true;
                    }
                    else if (arg.Equals("-i") || arg.Equals("--ignore"))
                    {
                        ignoreCtrlC = true;
                    }
                    else if (arg.Equals("-f"))
                    {
                        stopInterpretingFlags = true;
                    }
                    else
                    {	//If it isn't any of the above, it's a filename
                        addFilename(arg);
                    }
                    //Add more flags as necessary, just remember to SKIP adding them to the file processing stream!
                }

                if (ignoreCtrlC) //Implement the Ctrl+C fix selectively (mirror UnixUtils tee behavior)
                    Console.CancelKeyPress += new ConsoleCancelEventHandler(OnCancelKeyPressed);

                List<BinaryWriter> binaryWriters = new List<BinaryWriter>(filenames.Count); //Add only as many streams as there are distinct files
                try
                {
                    foreach (String filename in filenames)
                    {
                        binaryWriters.Add(new BinaryWriter(appendToFiles ?
                            File.AppendText(filename).BaseStream :
                            File.Create(filename)));  // Open the files specified as arguments
                    }
                    using (BinaryReader stdin = new BinaryReader(Console.OpenStandardInput()))
                    {
                        using (BinaryWriter stdout = new BinaryWriter(Console.OpenStandardOutput()))
                        {
                            Byte b;
                            while (true)
                            {
                                try
                                {
                                    b = stdin.ReadByte();  // Read standard in
                                }
                                catch (EndOfStreamException)
                                {
                                    break;
                                }
                                // The actual tee:
                                stdout.Write(b); // Write standard out
                                foreach (BinaryWriter binaryWriter in binaryWriters)
                                {
                                    binaryWriter.Write(b); // Write to each file
                                }
                            }
                        }
                    }
                }
                finally
                {
                    foreach (BinaryWriter binaryWriter in binaryWriters)
                    {
                        binaryWriter.Flush();  // Flush and close each file
                        binaryWriter.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(String.Concat("tee: ", ex.Message));  // Send error messages to stderr
            }

            return 0;
        }
    }
}

Some alternatives that might (or might not) support unicode:

http://www.commandline.co.uk/mtee/
http://unxutils.sourceforge.net/ (cannot be downloaded any more – pitty, as they were pretty good)

–jeroen

Update: 201009041030 – Syntax highlighting didn’t work, so changed
sourcecode language=”C#
into
sourcecode language=”csharp

Posted in .NET, C#, C# 2.0, CommandLine, Development, Encoding, Power User, Software Development, Unicode, UTF-8, Visual Studio and tools, XP-embedded | 13 Comments »