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 2,115 other followers

Archive for July 24th, 2019

Some links on code metrics

Posted by jpluimers on 2019/07/24

A while ago, I got a question on code metrics, so here some links for my reading list:

Delphi related:

–jeroen

Posted in Development, Profiling-Performance-Measurement, Software Development | Leave a Comment »

delphi – Why variables are declared as TStrings and created as TStringList? – Stack Overflow

Posted by jpluimers on 2019/07/24

Blast from the past: [WayBackdelphi – Why variables are declared as TStrings and created as TStringList? – Stack Overflow

Q

Why variables are declared as TStrings and created as TStringList?

A

Because that way you could put another TStrings descendant in the SL variable (I’d probably call that Strings, not SL).

In your case, that is moot, since the logic around SL contains the creation of a TStringList and no external assignment or parameter parsing.

But if you ever split the logic away from the assignment, then you could benefit from using any TStrings descendant.

For instance, a TMemoy.LinesTListBox.ItemsTComboBox.Items, etc.
From the outside it looks like they are TStrings, but internally they do not use a TStringList but their own descendant.

A few examples of classes that descend from TStrings:

source\DUnit\Contrib\DUnitWizard\Source\DelphiExperts\Common\XP_OTAEditorUtils.pas:
     TXPEditorStrings = class(TStrings)
source\fmx\FMX.ListBox.pas:
       TListBoxStrings = class(TStrings)
source\fmx\FMX.Memo.pas:
     TMemoLines = class(TStrings)
source\rtl\common\System.Classes.pas:
     TStringList = class(TStrings)
source\vcl\Vcl.ComCtrls.pas:
     TTabStrings = class(TStrings)
     TTreeStrings = class(TStrings)
     TRichEditStrings = class(TStrings)
source\vcl\Vcl.ExtCtrls.pas:
     TPageAccess = class(TStrings)
     THeaderStrings = class(TStrings)
source\vcl\Vcl.Grids.pas:
     TStringGridStrings = class(TStrings)
     TStringSparseList = class(TStrings)
source\vcl\Vcl.Outline.pas:
     TOutlineStrings = class(TStrings)
source\vcl\Vcl.StdCtrls.pas:
     TCustomComboBoxStrings = class(TStrings)
     TMemoStrings = class(TStrings)
     TListBoxStrings = class(TStrings)
source\vcl\Vcl.TabNotBk.pas:
     TTabPageAccess = class(TStrings)

–jeroen

Posted in Delphi, Development, Software Development | 1 Comment »

PowerShell script header to be as strict as possible and always throw exceptions

Posted by jpluimers on 2019/07/24

This is my default PowerShell script header from now on:

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$PSDefaultParameterValues['*:ErrorAction']='Stop'

This might sound like overkill, but it solves these problems:

The above helped me tremendously with for instance [WayBack] powershell – Why does the exception not get me in the catch block? – Stack Overflow:

I’m trying to interrogate some service information. Sometimes the installer of the application fails to correctly install, so the registry does not contain a service entry. I want to find out which installer steps did get executed correctly, even on systems that do not have proper logging in the installer.

If MyService does not exist, the script below does not go to the catch block even though the exception handling documentation suggests a bare catch should be enough:

try {
    $path = 'hklm:\SYSTEM\CurrentControlSet\services\MyService'
    $key = Get-Item $path
    $namevalues = $key | Select-Object -ExpandProperty Property |
        ForEach-Object {
        [PSCustomObject] @{
            Name = $_;
            Value = $key.GetValue($_)
        }
    }
    $namevalues | Format-Table
}
catch {
    $ProgramFilesX86 = [System.Environment]::GetFolderPath("ProgramFilesX86");
    $ProgramFiles = [System.Environment]::GetFolderPath("ProgramFiles");
    Write-Host $ProgramFilesX86
    Write-Host $ProgramFiles
}

Why is that and how should I force it to end up in the catch?

This is what PowerShell outputs:

Get-Item : Cannot find path 'HKLM:\SYSTEM\CurrentControlSet\services\MyService' because it does not exist.
At C:\Users\Developer\...\GetMyServiceInfo.ps1:17 char:12
+     $key = Get-Item $path
+            ~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (HKLM:\SYSTEM\Cu...vices\MyService:String) [Get-Item], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemCommand

For which I edited the answer to become this:

Force the error to be terminating:

$key = Get-Item $path -ErrorAction Stop

That way it will throw and catch will get it.

Explanation and links to the official Microsoft documentation:

What is missing there is the link to the $PSDefaultParameterValues documentation at [WayBack] about_Parameters_Default_Values | Microsoft Docs

–jeroen

Posted in CommandLine, Development, PowerShell, PowerShell, Scripting, Software Development | Leave a Comment »

 
%d bloggers like this: