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 July, 2011

File extension parameters do include a dot

Posted by jpluimers on 2011/07/20

This is from a long time ago, but still fun:

Sometimes simple things in life are hard do remember.

For instance, I always forgot if a file extension parameter should have a dot in it or not.

Normally it should!

But for clearing an extension, you should use a blank string.

Be aware though that empty extensions look differently depending where in the process you look at them:

C# example:

using System;
using System.IO;
public class Test
{
        public static void Main()
        {
                string extensionLess = Path.ChangeExtension(@"C:\mydir\myfile.com.extension", "");
                Console.WriteLine(extensionLess);
                string extension = Path.GetExtension(extensionLess);
                Console.WriteLine(extension);
        }
}

Outputs:

C:\mydir\myfile.com.

Delphi example:

program Demo;
{$APPTYPE CONSOLE}
uses
  SysUtils;
var
  extensionLess: string;
  extension: string;
begin
  extensionLess := ChangeFileExt('C:\mydir\myfile.com.extension', '');
  Writeln(extensionLess);
  extension := ExtractFileExt(extensionLess);
  Writeln(extension);
end.

Outputs:

C:\mydir\myfile.com
.com

Don’t you love differences in your platforms :)

–jeroen

Posted in .NET, C#, C# 2.0, C# 3.0, C# 4.0, Delphi, Development, Software Development | 4 Comments »

ISO 8601: Delphi way to convert XML date and time to TDateTime and back (via: Stack Overflow)

Posted by jpluimers on 2011/07/19

Recently I needed a way of concerting back and forth ISO 8601 DateTime values used in XML from Delphi.

Thoug the Delphi DateUtils unit has some ISO 8601 features for calculating week numbers, you actually need to the XSBuiltIns unit for converting back and forth to ISO 8601 text representation of a DateTime.

I remembered answering the related In Delphi is there a function to convert XML date and time to TDateTime question on StackOverflow a while ago (and forgot that this was back in 2009 <g>).

ISO 8601 dates can either include a time-zone, or be in UTC, which is not part of that answer. So lets elaborate on that answer a bit now:

UTC times in ISO 8601 format end in a Z time zone designator like this:

    <Created>2011-06-29T17:01:45.505Z</Created>

The Z UTC indicator is basically a shortcut for a timezone offset of +00:00 or -00:00, effectively being a zero (or zulu) timezone.

Nonzero timezones start with an optional + or -, followed by the hours and minutes offset from UTC, for instance +01:00 for the Central European Time zone.

    <Created>2011-06-29T17:01:45.505+01:00</Created>

When you want historical time zones, then you need the Delphi TZDB interface to the historical TZ database.

To do the timezone calculations, I used the TimeZoneBias function from Indy, which is either in the IdGlobal unit (Indy <= version 9) or the IdGlobalProtocols unit (Indy 10 and up).

Conversion is done by using the TXSDateTime (that like all the XS conversion classes descends from TRemotableXS in the InvokeRegistry unit).

Most of the classes descending from TRemotableXS contain two methods: NativeToXS and XSToNative doing the underlying conversions.

Since I didn’t need the historical reference in the TZDB, this is the code that I came up with:

unit Iso8601Unit;

interface

type
  TIso8601 = class(TObject)
  public
    class function DateTimeFromIso8601(const Value: string): TDateTime; static;
    class function UtcDateTimeToIso8601(const Value: TDateTime): string; static;
    class function DateTimeToIso8601(const Value: TDateTime): string; static;
    class function UtcNow: TDateTime; static;
    class function ToUtc(const Value: TDateTime): TDateTime; static;
    class function FromUtc(const Value: TDateTime): TDateTime; static;
  end;

implementation

uses
  IdGlobalProtocols, {IdGlobal for Index   SysUtils,
  XSBuiltIns;

class function TIso8601.DateTimeFromIso8601(const Value: string): TDateTime;
begin
  with TXSDateTime.Create() do
  try
    XSToNative(value); // convert from WideString
    Result := AsDateTime; // convert to TDateTime  finally
  finally
    Free();
  end;
end;

class function TIso8601.UtcDateTimeToIso8601(const Value: TDateTime): string;
begin
  with TXSDateTime.Create() do
  try
    AsUTCDateTime := Value;
    Result := NativeToXS; // convert to WideString
  finally
    Free();
  end;
end;

class function TIso8601.DateTimeToIso8601(const Value: TDateTime): string;
begin
  with TXSDateTime.Create() do
  try
    AsDateTime := Value; // convert from TDateTime
    Result := NativeToXS; // convert to WideString
  finally
    Free();
  end;
end;

class function TIso8601.UtcNow: TDateTime;
begin
  Result := ToUtc(Now);
end;

class function TIso8601.ToUtc(const Value: TDateTime): TDateTime;
var
  Bias: TDateTime;
begin
  Bias := TimeZoneBias;
  Result := Value + TimeZoneBias;
end;

class function TIso8601.FromUtc(const Value: TDateTime): TDateTime;
var
  Bias: TDateTime;
begin
  Bias := TimeZoneBias;
  Result := Value - TimeZoneBias;
end;

end.

–jeroen

via In Delphi is there a function to convert XML date and time to TDateTime – Stack Overflow.

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | 7 Comments »

Douanerechten/omzetbelasting: Wanneer hoef ik geen of minder belastingen te betalen?

Posted by jpluimers on 2011/07/18

Voor het bepalen van de invoerrechten en BTW geldt de waarde van de aankoop.

Je betaalt rechten en belasting over de waarde van de zending plus eventuele verzend- en verzekeringskosten.

Samenvatting van de grenzen op het moment van schrijven:

  • binnen EU: onbeperkt
  • buiten EU: tot EUR 22: geen douanerechten, geen omzetbelasting
  • buiten EU: van EUR 22 tot EUR 150: geen douanerechten, wel omzetbelasting
  • buiten EU: van EUR 150: wel douanerechten, wel omzetbelasting

Op de site van de Douane staat een aantal percentages hier, een uitgebreide tarievenlijst met TARIC codes hier en het proces hier.

Voor PostNL (het vroegere TNT-POST/TPG-POST) beschrijft haar proces hier.

–jeroen

via: Wanneer hoef ik geen of minder belastingen te betalen?.

Posted in Power User | Leave a Comment »

Synchronize your NTP time using pool.ntp.org: the internet cluster of ntp servers

Posted by jpluimers on 2011/07/15

If you use NTP for syncing your time, then choose pool.ntp.org as your time server:

The pool.ntp.org project is a big virtual cluster of timeservers providing reliable easy to use NTP service for millions of clients.

I use it for instance to synchronize the time on my ESXi servers.

Note: when you run Windows VMs as ESXi guests; let ESXi time-sync them through the VMware tools, and disable Windows’ own time syncing. I didn’t disable it, and my Windows VMs were consistently off by over 30 minutes.

–jeroen

via pool.ntp.org: the internet cluster of ntp servers.

Posted in *nix, ESXi4, Power User, VMware, Windows, Windows 7, Windows Vista, Windows XP | 4 Comments »

Delphi commandline oddity with double-quoted arguments

Posted by jpluimers on 2011/07/14

Boy, I was wrong. Somewhere in the back of my head I knew it.

ParamStr goes from zero (the name of the EXE) through ParamCount (the last parameter). Duh :)

 

I’ll keep this so you can have a good laugh:

 

When you add double quoted arguments to the commandline of your Delphi app, strange things can happen: the first parameter seems to be gone, while it is there.

It appears that the ParamCount/ParamStr logic fails here, and cannot be repaired because of backward compatibility.

Lets look at this commandline:

“..\bin\DumpCommandLine.exe” “C:\Program Files\test.xml” “C:\Program Files\meMySelfAndI.xml”

The demo code below will output something like this:

ParamCount:     2
ParamStr():
0       C:\develop\DumpCommandLine\bin\DumpCommandLine.exe
1       C:\Program Files\test.xml
CommandLine:
"..\bin\DumpCommandLine.exe" "C:\Program Files\test.xml" "C:\Program Files\meMySelfAndI.xml"
CommandLineStrings.Count:       3
CommandLineStrings[]:
0       ..\bin\DumpCommandLine.exe
1       C:\Program Files\test.xml
2       C:\Program Files\meMySelfAndI.xml

You see that regular ParamCount/ParamStr calls will mis the “C:\Program Files\test.xml” parameter.
But getting it through CommandLineStrings will correctly get it.

This is the dump code:

unit CommandlineDemoUnit;

interface

procedure DumpCommandLineToConsole;

implementation

uses
  Classes, CommandlineUnit;

procedure DumpCommandLineToConsole;
var
  CommandLineStrings: TStrings;
  I: Integer;
begin
  Writeln('ParamCount:', #9, ParamCount);
  Writeln('ParamStr():');
  for I := 0 to ParamCount - 1 do
    Writeln(I, #9, ParamStr(I));
  Writeln('CommandLine:');
  Writeln(CommandLine);
  CommandLineStrings := CreateCommandLineStrings();
  Writeln('CommandLineStrings.Count:', #9, CommandLineStrings.Count);
  Writeln('CommandLineStrings[]:');
  try
    for I := 0 to CommandLineStrings.Count - 1 do
      Writeln(I, #9, CommandLineStrings[I]);
  finally
    CommandLineStrings.Free;
  end;
end;

end.

And this the code to get the CommandLine and CommandLineStrings, which will fill a TStrings result using the CommaText property (it uses a default QuoteChar of of double quote #34 and Delimiter of space #32, this will work nicely):

unit CommandlineUnit;

interface

uses
  Classes;

function CommandLine: string;
function CreateCommandLineStrings: TStrings;

implementation

uses
  Windows;

function CommandLine: string;
begin
  Result := GetCommandLine();
end;

function CreateCommandLineStrings: TStrings;
begin
  Result := TStringList.Create();
  Result.CommaText := CommandLine;
end;

end.

Note that you need to manually free the TStrings object to avoid memory leaks.

–jeroen

Posted in Delphi, Development, Software Development | 13 Comments »

Extracting MSI files

Posted by jpluimers on 2011/07/13

Extracting MSI files can be a pain.

Some compression programs (like 7zip) can unpack them, but leave the unpacked filenames as gibberish.

Many people recommend using msiexec (link to technet docs) on the commandline using the /a parameter (which does an administrative install effectively unpacking it), but others prefer integration in Windows Explorer.

msiexec /a PathToMSIFile /qb TARGETDIR=DirectoryToExtractTo

There are many tools allowing to unpack, and the best seems to be LessMSIerables by Scott Willeke which used to be on the (now defunct) pingpoet blogs, but got resurrected as lessmsi at oogle code.

Note that LessMSI doesn’t always work when msiexec /a works; for instance, I once got this error message:

Error: System.Runtime.InteropServices.COMException (0x00000003): Failed to close cab extract object, error: 3

Note that when you want to view MST files in addition to MSI files, then you need MSTVIEW from ORK XP or ORK 2003 (which you can get through the Office 2003 resource kit downloads page).

–jeroen

Posted in .NET, Development, Power User, Software Development | 2 Comments »

Mac OS X Lion Supports Running 2 Additional OS X Instances Within a Virtual Machine

Posted by jpluimers on 2011/07/12

Good news for developers and IT engineers:

The new Mac OS X Lion EULA contains a phrase basically indicating you are a allowed to run 2 additional copies or instances of OS X Lion on each Mac already running OSX Lion.

This is a big change for OS X users.

For the beta, there were already steps on how to setup such a VM on a Mac or PC (including faking it to be the OS X Server), hopefully those steps have become a lot simpler now.
Probably these steps on how to make a OS X Bootable Installer from a USB Flash Drive helps too.

The OS X Lion release is already available to developers, and should be available to the general public really soon now.

–jeroen

via: Mac OS X Lion Supports Running Additional OS X Instances Within a Virtual Machine.

Posted in Apple, Development, Power User, Software Development, xCode/Mac/iPad/iPhone/iOS/cocoa | Leave a Comment »

Windows: viewing the WiFi networks nearby

Posted by jpluimers on 2011/07/11

Windows contains the versatile netsh command that allows to configure and inspect your network configuration locally or remotely, including WLAN.

One of the things you can do is view the WiFi networks nearby, including all kinds of details not readily visible through the standard Windows UI.

This is the command to do it:

netsh wlan show networks mode=bssid

It shows you information on all WiFi networks nearby, revealing details like this: Read the rest of this entry »

Posted in Power User, WiFi | Leave a Comment »

Recovering an NTFS partition: TestDisk Step By Step – CGSecurity

Posted by jpluimers on 2011/07/08

Recently I had the NTFS partition table of  a 2.5 inch USB disk fail because somehow I didn’t correctly attach the split-USB cable: the disk didn’t get enough power, and Windows decided it should overwrite the partition table.

The free TestDisk tool by GCSecurity came to the rescue: TestDisk Step By Step – CGSecurity.

–jeroen

Posted in Power User, Windows, Windows 7, Windows Vista, Windows XP | 1 Comment »

Nice error message with helpful explanation: KPN HotSpots is not available at this moment

Posted by jpluimers on 2011/07/07

When staying in hotels or holiday parcs, the error messages you get usuaully are terrible.

Not so with KPN Hotspots (which I can access as part of my xs4all ADSL subscription).

Recently I had the pleasure to be at one of the Center Parcs, and most of the Dutch ones have KPN WiFi hotspots.

When you cannot get on-line, at least you get a decent error message that shows you the steps to work around.

I had two outages that week; this is how I solved them:

  1. Rather than restarting my primary browser, I started a different one (I have Chrome, FireFox, Opera and Internet Explorer) and logged on to KPN HotSpots successfully.
    After that, my primary browser would work.
  2. The second one Disconnected the WiFi adapter for 10 minutes, reconnected, then logged on successfully to KPN HotSpots.

One tiny thing: when you have multiple WiFi devices with you (laptop + iPad for instance), only one can login to KPN Hotspots at a time.
–jeroen

Posted in Power User | Leave a Comment »