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,860 other subscribers

Archive for the ‘Delphi’ Category

WinSCP can be embedded and scripted as can PSFTP but not FileZilla

Posted by jpluimers on 2016/12/01

In a quest to perform SFTP in Delphi next to FTP, I first researched what I was up against. A tiny voice in the back of my head said “SFTP is totally unlike FTP” and it was right: SFTP means SSH File Transfer Protocol, not Simple File Transfer Protocol nor FTP over SSH nor FTP over SSL aka FTPS – the latter is supported by Indy but the former isn’t.

I decided against SecureBlackBox (providing SFTPBlackbox) and IPWorks (SSH) as I tried both a while ago for S/MIME support and was disappointed about both the lack of features and documentation; in the end I went for wrapping OpenSSL for the “encrypt-then-sign” process and Indy for the SSMTP part. The merger of the SecureBlackBox and IPWorks made me even less happy.

The Chilkat alternative for SFTP isn’t too compelling either: ActiveX or DLL black-box without a lot of insight on how many people do use it.

So when I had to do SFTP and knew there are no free or open source SFTP components for Delphi available I opted for thinking outside the Delphi realm.

My basic idea was to embed either of these:

  1. Filezilla (as Filezilla on Windows is waaaay faster than WinSCP)
  2. WinSCP (a Windows SCP and SFTP client written in C++ Builder)
  3. PSFTP (the Putty SFTP client)

FileZilla

FileZilla internally uses FzSFtp.exe which is based on PSFTP code (but with some buffers making it faster than PSFTP or WinSCP).

According to the author, neither FzSFtp.exe nor FileZilla can be automated:

FileZilla cannot make any automated transfers at all. Neither FileZilla.exe nor fzsftp.exe (is for SFTP) can be used for any batch processing.

Source: run filezilla tzsftp from batch command line – FileZilla Forums

The WinSCP author commented in a similar fashion:

FileZilla does not have any command line arguments (nor any other way) that allow automatic transfer.

Source: windows – Command line option to download file in FileZilla – Stack Overflow

In addition, FileZilla is always a GUI program, so running it as a console app (which I’d prefer) would be impossible.

WinSCP

WinSCP can be automated in two ways:

  1. The WinSCP.exe command-line allows for a /console and /script switch enabling scripting mode that you can use for Scripting and Task Automation :: WinSCP
  2. A wrapper around WinSCP.exe is availble as WinSCP .NET Assembly and COM Library :: WinSCP which requires both .NET to be installed and (from Delphi) calling through COM which I don’t like much

Since I already had good Delphi wrapping code round starting/waiting-for running processes, I’d opt for using WinSCP.com scripting.

There used to be wrapping code around: Use with Delphi :: Support Forum :: WinSCP

PSFTP

These Using PSFTP to transfer files securely links should get me going:

Chapter 6: Using PSFTP to transfer files securely

Practical examples:

Source locations

For my own reference, the open source locations:

Some semi-random Delphi SSL related postss

During the search above I found the below links that will be useful to me one day:

–jeroen

Posted in .NET, Delphi, Development, Software Development, SSH, TCP | 5 Comments »

String resources and the $TypedAddress Compiler Directive require a PResStringRec typecast

Posted by jpluimers on 2016/12/01

Thanks Alexey for answering and Horácio for asking:

Use type-cast PResStringRec(@SArgumentNil_NilValue_Collection)

–jeroen

via: Hey guys, When I switch on $TypedAddress Compiler Directive, it is no longer…

Posted in Delphi, Delphi 10 Seattle, Delphi 2005, Delphi 2006, Delphi 2007, Delphi 2009, Delphi 2010, Delphi 7, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Delphi XE5, Delphi XE6, Delphi XE7, Delphi XE8, Development, Software Development, Uncategorized | Leave a Comment »

Actual source for DisableAlignPropertyEditor

Posted by jpluimers on 2016/11/30

Since Uwe Schuster only published a screenshot, I NewOCR-ed it and created the accompanying .dproj file (only because it’s an easy way for the DLL to require the designide package so you can use the DesignIntf and ToolsAPI units.

Uwe only posted these:

Anyway, the sources are at gist.github.com/881d4eacbcec2a9e1e6b0181f900fd7a, but the main source is this:

library DisableAlignPropertyEditor;

{
  Originally only as jpg image by Uwe Schuster.

  https://web.archive.org/web/20161117154454/https://pbs.twimg.com/media/Cxaoi-DXEAAMF03.jpg:large
  https://web.archive.org/web/20161117154450/https:/twitter.com/UScLE/status/799011392703647744
  https://web.archive.org/web/20161117154501/https://plus.google.com/107811538224738992137/posts/hTXUwkCe1TV
}

uses
  System.SysUtils,
  System.TypInfo,
  DesignIntf,
  ToolsAPI;

var
  LastRegisterPropertyEditorProc: TRegisterPropertyEditorProc = nil;

procedure NewRegisterPropertyEditor(PropertyType: PTypeInfo; ComponentClass: TClass; const PropertyName: string; EditorClass: TPropertyEditorClass);
begin
  if Assigned(EditorClass) then
  begin
    if SameText('TAlignProperty', EditorClass.ClassName) then
      Exit;
  end;
  LastRegisterPropertyEditorProc(PropertyType, ComponentClass, PropertyName, EditorClass);
end;

procedure wizardTerminate;
begin
  RegisterPropertyEditorProc := LastRegisterPropertyEditorProc;
end;

function wizardInit(const BorlandIDEServices: IBorlandIDEServices; RegisterProc: TWizardRegisterProc; var Terminate: TWizardTerminateProc): Boolean; stdcall;
begin
  LastRegisterPropertyEditorProc := RegisterPropertyEditorProc;
  RegisterPropertyEditorProc := NewRegisterPropertyEditor;
  Terminate := wizardTerminate;
  Result := True;
end;

exports
  wizardInit name WizardEntryPoint;

begin
end.

–jeroen

Read the rest of this entry »

Posted in Delphi, Delphi 10.1 Berlin (BigBen), Development, Software Development | 2 Comments »

Can some recommend a good tool to build MSI package? I use Inno Setup…

Posted by jpluimers on 2016/11/30

For my G+ Link archive:

Can some recommend a good tool to build MSI package?I use Inno Setup but only to build EXE file.Thanks,  – Chris Z. – Google+

Source: Can some recommend a good tool to build MSI package? I use Inno Setup but only…

Related:

Posted in Delphi, Development, Installer-Development, Software Development | Leave a Comment »

The curse of the Project.res file.

Posted by jpluimers on 2016/11/29

A long time ago, Lars Fosdal wrote this on the Delphi G+ group:

It really is beyond me why there is no Project.rc file which includes

  • Project.version.rc
  • Project.icon.rc
  • Project.themes.rc
  • Project.manifest.xml
  • and so forth.

That way, the .res file would be a compile-time thing (or even a thing of the past) – and the resource linker would assemble the various bits from their individual sources.

It has been an issue forever. Vincent Parrett correctly commented that if you clean out too much out of the Project.res file, the IDE gets confused:

The only thing it is used for is version info and the mainicon (the IDE gets confused if don’t do that).

In my own experience, this isn’t the case for all Delphi versions, but I forgot which versions suffer and which don’t. I think the IDE theming issue omitting the Application word in the .dpr is related.

Like many of the G+ commenters, I’ve switched to script based resources for my own projects a long time ago. That’s also the reason why I forgot: this approach just works for any Delphi version.

This post is a reminder to self to see if the IDE has finally refrained from doing Project.res handling itself.

–jeroen

Source: The curse of the Project.res file…

Some related posts:

Posted in Delphi, Delphi 1, Delphi 10 Seattle, Delphi 2, Delphi 2005, Delphi 2006, Delphi 2007, Delphi 2009, Delphi 2010, Delphi 3, Delphi 4, Delphi 5, Delphi 6, Delphi 7, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Delphi XE5, Delphi XE6, Delphi XE7, Delphi XE8, Development, Software Development | 5 Comments »

Delphi F12 Debug Hotkey for Windows 8.1 and 10 | Andy’s Blog and Tools

Posted by jpluimers on 2016/11/28

Yes. Yes. Yeesssss!

It solves [WayBackdebugging – F12 not working in Delphi debugger on Windows 7/8 – Stack Overflow

Due to robots.txt the site cannot be archived in the WayBack machine, so I’m keeping a local copy of any http://andy.jgknet.de/blog/wp-content/plugins/download-monitor/download.php?id=* files.

This is how I installed the extracted DelphiF12HotKeySupport.dll:

Read the rest of this entry »

Posted in Delphi, Development, Software Development | Leave a Comment »

The Delphi Vcl.Forms.TApplication.ActionUpdateDelay unit is … milliseconds

Posted by jpluimers on 2016/11/24

Don’t you love relevant documentation…

There is no unit defined for the Vcl.Forms.TApplication.ActionUpdateDelay – RAD Studio API Documentation.

It is used inside the TAppliation.Idle to fire the (undocumented) TApplication.DoActionIdle method. When the value is zero or less, then each Idle call will result in an DoActionIdle call in turn calling TCustomForm.UpdateActions for any visible form.

UpdateActions in turn will call (for the form itself, all the form’s menu items and all the form’s controls) the TControl.InitiateAction which – if there is an associated ActionLink – will call the TBasicActionLink.Update which in turn will call the TBasicAction.Suspended and TBasicAction.Update methods of which the latter will call the TBasicAction.OnUpdate event if it is assigned.

In theory, the OnUpdate method for each action can even be called multiple times (because multiple controls on visible forms can point to it), but the real culprit is that TApplication.Idle as it can be called from these places:

  • TApplication.DoApplicationIdle
  • TApplication.HandleMessage (in a loop from TApplication.Run)
  • TCustomActionMenuBar.ProcessMenuLoop (in a loop)
  • TCustomRibbon.DisplayKeyTips (in a loop)

The last three (especially HandleMessage) can be disastrous as they can be called a lot (for instance when moving the mouse), and more often than not, the OnUpdate event handlers aren’t exactly CPU friendly.

A while ago I bumped into an application where the OnUpdate event handler for one action was called half a million time in under 5 minutes.

This clearly indicated a huge problem (besides using a full CPU core slowing down the application) as apparently something was broadcasting Windows Messages like crazy.

Investigating and Solving the message flood is on the back-log with a reasonably high priority, but the highest priority issue was fixing the high CPU usage in the first place.

Apparently more users suffer from this, as there is a Vcl.Forms.TApplication.ActionUpdateDelay property which TApplication.Idle uses to call the Windows API function SetTimer to rate-limit the TApplication.DoActionIdle call tree. Luckily SetTimer does have documentation on the unit of ActionUpdateDelay: it’s milliseconds.

I’ve set it to 10 as that updating the actions ~100 times a second is fast enough for this application.

–jeroen

via:

Posted in Delphi, Delphi 10 Seattle, Delphi 10.1 Berlin (BigBen), Delphi 2007, Delphi 2009, Delphi 2010, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Delphi XE5, Delphi XE6, Delphi XE7, Delphi XE8, Development, Software Development | Leave a Comment »

Delphi: function IsRunningFromNetwork – via Lars Fosdal. I will need this one day

Posted by jpluimers on 2016/11/24

If I ever need it: function IsRunningFromNetwork that is based on WNetGetConnection.


function IsRunningFromNetwork(const ServerName:String = 'BetYouCantFindThisServer'): Boolean;
const
pMax = 2047;
var
dt: UINT;
volpath: Array[0..pMax] of Char;
sVol: String;
sz: Cardinal;
begin
Result := False;
dt := GetDriveType(PChar(ExtractFilePath(ParamStr(0))));
if dt = 4
then begin
GetVolumePathNameW(PChar(LowerCase(ParamStr(0))), volpath, pMax);
sVol := StrPas(volpath);
if not ((pos(LowerCase(ServerName), sVol) <> 0) or (pos('\\', sVol) = 1))
then begin
if pos(':', sVol) <> 0
then begin
sz := pMax;
if WNetGetConnection(pChar(Copy(sVol, 1, 2)), volPath, sz) = NO_ERROR
then Result := (pos(LowerCase(ServerName), LowerCase(StrPas(volPath))) <> 0) or (pos('\\', StrPas(volPath)) = 1);
end;
end
else Result := True;
end;
end;

Thanks Lars; I copied it to a gist for easier WordPress handling.

–jeroen

via:

Posted in Delphi, Development, Software Development | Leave a Comment »

ReservedWordsOP.txt and ReservedWordsC.txt for use with java2op in Delphi

Posted by jpluimers on 2016/11/22

Since these files got missing again: [WayBackDoes anybody know where to get ReservedWordsOP.txt and ReservedWordsC.txt for java2OP.exe in bin\converters\java2op for Delphi 10.1 Berlin upd2? It also… – Rik van Kekem – Google+

Here they are:

Read the rest of this entry »

Posted in Delphi, Delphi 10 Seattle, Delphi 10.1 Berlin (BigBen), Development, Software Development | 2 Comments »

Hope this doesn’t repeat itself…

Posted by jpluimers on 2016/11/18

Nice error starting Delphi XE8:

[Window Title]
Error

[Content]
Registration procedure, Dbexpressentimpl.Register in package c:\program files (x86)\embarcadero\studio\16.0\Bin\DataExplorerDBXPluginEnt220.bpl raised exception class EWrapperError: Parameter MetaClass cannot be nil.
Do you want to attempt to load this package the next time a project is loaded?

[Yes] [No]

–jeroen

Posted in Delphi, Delphi XE8, Development, Software Development | Leave a Comment »