<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/"><channel><atom:link href="https://www.finalbuilder.com/DesktopModules/LiveBlog/API/Syndication/GetRssFeeds?Tag=delphi&amp;mid=632&amp;PortalId=0&amp;tid=181&amp;ItemCount=20" rel="self" type="application/rss+xml" /><title>VSoft Technologies Blogs</title><description>VSoft Technologies Blogs - posts about our products and software development.</description><link>https://www.finalbuilder.com/resources/blogs</link><item><title>Signing .rdp files with Signotaur (and surviving the April Windows update)</title><link>https://www.finalbuilder.com/resources/blogs/postid/882/signing-rdp-files-with-signotaur-and-surviving-the-april-windows-update</link><category>.NET,Code Signing,DelphiSignotaur,Windows</category><pubDate>Fri, 24 Apr 2026 02:27:48 GMT</pubDate><description>&lt;style type="text/css"&gt;div.blog_content h1 { font-size: 1.9rem; margin-bottom: 0.3rem; }
    div.blog_content h2 { font-size: 1.4rem; margin-top: 2.2rem; border-bottom: 1px solid #e0e0e0; padding-bottom: 0.4rem; }
    div.blog_content h3 { font-size: 1.15rem; margin-top: 1.6rem; color: #222;}
    div.blog_content strong {  font-weight: 600;  color: #888;}
    div.blog_content .meta { color: #777; font-size: 0.9rem; margin-bottom: 2rem; }
    div.blog_content code { background: #f4f4f4; padding: 0.15em 0.4em; border-radius: 3px; font-size: 0.92em; }
    div.blog_content pre { background: #f4f4f4; padding: 1rem; border-radius: 5px; overflow-x: auto; }
    div.blog_content pre code { background: none; padding: 0; }
    div.blog_content a { color: #0066cc; }
    div.blog_content img { max-width: 100%; border: 1px solid #ddd; border-radius: 4px; margin: 1rem 0; }
    div.blog_content .note { background: #eef6ff; border-left: 4px solid #0066cc; padding: 0.8rem 1rem; margin: 1.2rem 0; border-radius: 0 4px 4px 0; }
    div.blog_content ol { margin: 1rem 0 1.5rem 1.5rem; padding-left: 0.5rem;}
    div.blog_content ol li {  margin-bottom: 0.7rem;  line-height: 1.6;}
    div.blog_content ol li strong {  font-weight: 600;}
    div.blog_content ul li {  margin-bottom: 0.45rem;}
&lt;/style&gt;
&lt;div class="note"&gt;&lt;strong&gt;In this article:&lt;/strong&gt;
&lt;ul&gt;
	&lt;li&gt;What changed for signed &lt;code&gt;.rdp&lt;/code&gt; files in the April 2026 Windows update&lt;/li&gt;
	&lt;li&gt;Why previously-working signatures now show an orange warning dialog&lt;/li&gt;
	&lt;li&gt;The registry policy recipient machines need for no dialog at all&lt;/li&gt;
	&lt;li&gt;How Signotaur signs &lt;code&gt;.rdp&lt;/code&gt; files without distributing the certificate&lt;/li&gt;
	&lt;li&gt;Deploying the policy via Group Policy or PowerShell&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

&lt;p&gt;If you push Remote Desktop shortcuts out to users, you probably already know about the April 2026 Windows cumulative update (&lt;a href="https://support.microsoft.com/kb/5083769"&gt;KB5083769&lt;/a&gt; on Windows 11, KB5082200 on Windows 10). If you don't, you might have found out the hard way — via a Monday-morning deluge of "is this a virus?" tickets from users who suddenly have a big orange warning on the RDP file that worked fine last week.&lt;/p&gt;

&lt;p&gt;Signotaur 1.2.0.107 ships with &lt;code&gt;.rdp&lt;/code&gt; file signing support. Here's what changed in Windows, why it matters, and what the new signing command actually does.&lt;/p&gt;

&lt;h2&gt;What Microsoft changed&lt;/h2&gt;

&lt;p&gt;The April cumulative addresses &lt;a href="https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-26151"&gt;CVE-2026-26151&lt;/a&gt;. Two user-visible things came with it:&lt;/p&gt;

&lt;ol style="margin-left: 1.4em;  margin-bottom: 1em;"&gt;
	&lt;li&gt;The Remote Desktop Connection warning dialog was redesigned. It now lists every resource the connection can redirect (drives, printers, clipboard, USB, etc.) with individual checkboxes, and &lt;strong&gt;every box is off by default&lt;/strong&gt;. Users have to opt in to each one on every connection, every time.&lt;/li&gt;
	&lt;li&gt;The trust criteria for signed &lt;code&gt;.rdp&lt;/code&gt; files tightened. Pre-April, a file signed by an untrusted cert got a yellow "Verify the publisher" banner. Post-April, the same file gets an orange "Caution: Unknown remote connection" banner — visually indistinguishable from an unsigned file.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's what the new per-launch dialog looks like. For an unsigned file:&lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;img alt="The RDP security warning dialog for an unsigned file: an orange 'Caution: Unknown remote connection' banner, 'Unknown publisher', and per-redirection checkboxes all off by default." src="https://cdn.finalbuilder.com/blog/daves/signotaur-rdp/unsigned-rdp-security-warning-dialog.png" /&gt;&lt;/p&gt;

&lt;p&gt;And for a file signed by a publisher Windows can verify:&lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;img alt="The RDP security warning dialog for a signed file: a yellow 'Verify the publisher of this remote connection' banner with the publisher name, and the same per-redirection checkboxes." src="https://cdn.finalbuilder.com/blog/daves/signotaur-rdp/signed-rdp-security-warning-dialog.png" /&gt;&lt;/p&gt;

&lt;p&gt;Separately, the first time any user opens an &lt;code&gt;.rdp&lt;/code&gt; file after installing the update, Windows shows a one-time educational dialog explaining what &lt;code&gt;.rdp&lt;/code&gt; files are and why they can be dangerous:&lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;img alt="The first-launch educational dialog shown once per user account after installing KB5083769, explaining what RDP files are and the associated phishing risks." src="https://cdn.finalbuilder.com/blog/daves/signotaur-rdp/rdp-first-launch-dialog.png" /&gt;&lt;/p&gt;

&lt;p&gt;Once dismissed, it doesn't reappear for that account.&lt;/p&gt;

&lt;p&gt;Discussion and lament: &lt;a href="https://www.reddit.com/r/sysadmin/comments/1sm61eo/fyi_microsoft_rdp_changes_with_april_cumulative/"&gt;r/sysadmin: FYI: Microsoft RDP changes with April cumulative&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is a genuinely good security change — the old dialog was vague and under-informed users about what was being shared with the remote host. It is also a rather annoying deployment change, because plenty of teams had &lt;code&gt;rdpsign.exe&lt;/code&gt;-signed files quietly working for years, and now they don't.&lt;/p&gt;

&lt;h2&gt;Why people got caught out&lt;/h2&gt;

&lt;p&gt;The usual story goes like this: a team signed their &lt;code&gt;.rdp&lt;/code&gt; file years ago with a self-signed or internal-CA certificate, shipped it to users, and it displayed a friendly yellow "Verify the publisher: Acme Corp" dialog that everyone clicked through. After April's update, the same file suddenly shows an orange "Unknown remote connection" dialog and support gets flooded. One representative example from the Reddit threads: &lt;a href="https://www.reddit.com/r/sysadmin/comments/1sp6h4x/comment/ohaenxv/"&gt;a sysadmin describing exactly this&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The signatures on those files are still cryptographically valid. Windows is just stricter now about what counts as a "verified publisher" for RDP.&lt;/p&gt;

&lt;h2&gt;The actual recipe (no dialog at all)&lt;/h2&gt;

&lt;p&gt;Cutting through the noise, here's what recipient machines need for a signed &lt;code&gt;.rdp&lt;/code&gt; file to open with no warning dialog at all:&lt;/p&gt;

&lt;ol style="margin-left: 1.4em;  margin-bottom: 1em;"&gt;
	&lt;li&gt;The signing certificate's chain must terminate in a root the client machine trusts. Commercial code-signing certs (DigiCert, Sectigo, etc.) chain to roots Windows already trusts. For an internal CA or self-signed cert, the root has to be imported into &lt;code&gt;Cert:\*\Root&lt;/code&gt; on each client.&lt;/li&gt;
	&lt;li&gt;A Remote Desktop trust policy must be in place that whitelists your signing certificate's SHA-1 thumbprint. This lives at either &lt;code&gt;HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services&lt;/code&gt; (machine-wide, requires admin) or &lt;code&gt;HKCU\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services&lt;/code&gt; (per-user, no admin required), and needs two values:
	&lt;ul style="margin-bottom: 0.5em;"&gt;
		&lt;li&gt;&lt;code&gt;AllowSignedFiles&lt;/code&gt; — REG_DWORD, set to &lt;code&gt;1&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;TrustedCertThumbprints&lt;/code&gt; — REG_SZ, the SHA-1 thumbprint of your signing cert, uppercase, no spaces (semicolon-separated if you have more than one)&lt;/li&gt;
	&lt;/ul&gt;
	&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A word of warning about one trap we hit: &lt;code&gt;TrustedCertThumbprints&lt;/code&gt; is a whitelist on top of normal chain validation, not a replacement for it. Dropping a self-signed cert's thumbprint into the list without also importing the cert into a trusted root store does nothing. If you've tried this and wondered why it didn't work, that's why.&lt;/p&gt;

&lt;h2&gt;What Signotaur does when you sign a .rdp file&lt;/h2&gt;

&lt;p&gt;Unlike &lt;code&gt;rdpsign.exe&lt;/code&gt;, Signotaur signs &lt;code&gt;.rdp&lt;/code&gt; files against a remote server — the private key stays on the server (or an HSM it's connected to), so no admin workstation or automation host needs a local copy of the signing certificate. This is the main reason to use Signotaur for &lt;code&gt;.rdp&lt;/code&gt; signing rather than running &lt;code&gt;rdpsign.exe&lt;/code&gt; directly.&lt;/p&gt;

&lt;p&gt;The mechanics otherwise match what you'd expect. The client reads the &lt;code&gt;.rdp&lt;/code&gt; file, canonicalises the contents, sends only the digest to the server for signing, and writes the signed file back in place. The output is byte-equivalent to &lt;code&gt;rdpsign.exe&lt;/code&gt;'s — same canonical form, same 12-byte Microsoft wrapper, same detached CMS structure — so recipients see the same Windows Remote Desktop Connection dialog regardless of which tool produced the signature.&lt;/p&gt;
        &lt;p&gt;RFC 3161 timestamping is supported, and the timestamp is embedded into the CMS in the standard way. But there's a caveat that's easy to miss: &lt;code&gt;mstsc.exe&lt;/code&gt; doesn't actually consult the timestamp when validating a &lt;code&gt;.rdp&lt;/code&gt; signature — it only checks whether the signing certificate is currently valid at the moment the file is opened. The strongest indirect evidence for this is that Microsoft's own &lt;code&gt;rdpsign.exe&lt;/code&gt; has no timestamping support at all — no &lt;code&gt;/tr&lt;/code&gt; flag, no timestamp in its output.&lt;/p&gt;
        &lt;p&gt;The timestamp is still worth having: it's standards-compliant CMS so general-purpose tools can read the signing time, it provides a tamper-evident audit trail, and it future-proofs against any future change in &lt;code&gt;mstsc&lt;/code&gt;'s behaviour. In practice though, plan to re-sign distributed &lt;code&gt;.rdp&lt;/code&gt; files when your signing certificate is renewed, the same way you would for an unsigned-but-distributed file.&lt;/p&gt;

&lt;p&gt;Because the registry recipe above is easy to get wrong, Signotaur also prints the recipe for you after signing, pre-filled with the thumbprint of the certificate that just signed the file. It tells you whether the cert is self-signed (in which case you'll also need to deploy the cert itself to recipient trusted-root stores) or chained (in which case you may not).&lt;/p&gt;

&lt;p&gt;If you're running &lt;code&gt;sign&lt;/code&gt; interactively on Windows, it also offers to apply the policy to &lt;code&gt;HKCU&lt;/code&gt; for the current user on the spot — no admin rights needed, no registry editor, no PowerShell snippet to copy-paste. This is mostly useful for confirming the signing works locally before you deploy the policy via GPO. In unattended runs, the prompt is automatically skipped, and you can pass &lt;code&gt;--no-mstsc-guidance&lt;/code&gt; (&lt;code&gt;--nmg&lt;/code&gt;) to suppress the whole lot if the log gets noisy.&lt;/p&gt;

&lt;h2&gt;An example&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;sign&lt;/code&gt; command detects &lt;code&gt;.rdp&lt;/code&gt; files automatically based on extension, so there's nothing special to type:&lt;/p&gt;

&lt;div&gt;
&lt;div class="syntaxhighlighter  bash" id="highlighter_rdpsign"&gt;
&lt;table border="0" cellpadding="0" cellspacing="0"&gt;
	&lt;tbody&gt;
		&lt;tr&gt;
			&lt;td class="gutter"&gt;
			&lt;div class="line number1 index0 alt2"&gt;&gt;&lt;/div&gt;
			&lt;/td&gt;
			&lt;td class="code"&gt;
			&lt;div class="container"&gt;
			&lt;div class="line number1 index0 alt2"&gt;&lt;code class="bash plain"&gt;SignotaurTool.exe sign -a &lt;apikey&gt; -s &lt;signserver&gt; -t &lt;thumbprint&gt; --tr http://timestamp.digicert.com --td SHA256 connect-to-prod.rdp&lt;/thumbprint&gt;&lt;/signserver&gt;&lt;/apikey&gt;&lt;/code&gt;&lt;/div&gt;
			&lt;/div&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;After a successful sign you'll see something along the lines of:&lt;/p&gt;

&lt;pre style="margin-bottom: 1em;"&gt;
&lt;code&gt;RDP signing guidance (Windows Remote Desktop Connection compatibility, post-KB5083769):

By default recipients will see a "Verify the publisher" or "Unknown publisher"
warning dialog when opening this signed file in Windows Remote Desktop Connection.
To eliminate the warning, each recipient machine needs:

1. The signing certificate's chain trusted on the machine.
   For commercial certificates chaining to a Windows-preinstalled root, no action
   is required; internal-CA certificates require the CA to be imported into each
   recipient's Trusted Root store.

2. The signing certificate's thumbprint added to the Remote Desktop trust-publisher
   policy:

   Value: AllowSignedFiles (REG_DWORD) = 1
   Value: TrustedCertThumbprints (REG_SZ) = &lt;your_cert_thumbprint&gt;

Apply AllowSignedFiles + TrustedCertThumbprints to your current user registry now?
Useful for testing this signed .rdp locally. [y/N]:&lt;/your_cert_thumbprint&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Answer &lt;code&gt;y&lt;/code&gt; and it writes the values to your &lt;code&gt;HKCU&lt;/code&gt; — open the file in Remote Desktop Connection, confirm there's no dialog, and you know the signing bit is working before you take the policy near a GPO.&lt;/p&gt;

&lt;h2&gt;Deploying the policy to the fleet&lt;/h2&gt;

&lt;p&gt;For anything beyond a couple of machines, Group Policy is the right tool — it's also how you set these same values without touching the registry by hand. In the Group Policy Management Editor:&lt;/p&gt;

&lt;ul style="margin-bottom: 1em;"&gt;
	&lt;li&gt;Computer (or User) Configuration → Administrative Templates → Windows Components → Remote Desktop Services → Remote Desktop Connection Client&lt;/li&gt;
	&lt;li&gt;&lt;em&gt;Allow .rdp files from valid publishers and user's default .rdp settings&lt;/em&gt; → Enabled&lt;/li&gt;
	&lt;li&gt;&lt;em&gt;Specify SHA1 thumbprints of certificates representing trusted .rdp publishers&lt;/em&gt; → Enabled, with your thumbprints in the list (uppercase, semicolon-separated if multiple)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Intune has equivalent settings under the Administrative Templates profile. If you're deploying to a smaller set of machines, or scripting it, a PowerShell snippet that does the per-user version (no admin needed) looks like this:&lt;/p&gt;

&lt;div&gt;
&lt;div class="syntaxhighlighter  powershell" id="highlighter_psrecipe"&gt;
&lt;table border="0" cellpadding="0" cellspacing="0"&gt;
	&lt;tbody&gt;
		&lt;tr&gt;
			&lt;td class="gutter"&gt;
			&lt;div class="line number1 index0 alt2"&gt;1&lt;/div&gt;

			&lt;div class="line number2 index1 alt1"&gt;2&lt;/div&gt;

			&lt;div class="line number3 index2 alt2"&gt;3&lt;/div&gt;

			&lt;div class="line number4 index3 alt1"&gt;4&lt;/div&gt;
			&lt;/td&gt;
			&lt;td class="code"&gt;
			&lt;div class="container"&gt;
			&lt;div class="line number1 index0 alt2"&gt;&lt;code class="powershell plain"&gt;$p = 'HKCU:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services'&lt;/code&gt;&lt;/div&gt;

			&lt;div class="line number2 index1 alt1"&gt;&lt;code class="powershell plain"&gt;New-Item -Path $p -Force | Out-Null&lt;/code&gt;&lt;/div&gt;

			&lt;div class="line number3 index2 alt2"&gt;&lt;code class="powershell plain"&gt;Set-ItemProperty -Path $p -Name AllowSignedFiles -Value 1 -Type DWord&lt;/code&gt;&lt;/div&gt;

			&lt;div class="line number4 index3 alt1"&gt;&lt;code class="powershell plain"&gt;Set-ItemProperty -Path $p -Name TrustedCertThumbprints -Value 'YOUR_THUMBPRINT_UPPERCASE' -Type String&lt;/code&gt;&lt;/div&gt;
			&lt;/div&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Swap &lt;code&gt;HKCU&lt;/code&gt; for &lt;code&gt;HKLM&lt;/code&gt; for the machine-wide version (and run elevated). The thumbprint must be uppercase with no spaces; use a semicolon to join multiple thumbprints if you have more than one signing cert in rotation.&lt;/p&gt;

&lt;h2&gt;What you still can't do&lt;/h2&gt;

&lt;p&gt;A few things worth knowing up front so you don't hunt for them:&lt;/p&gt;

&lt;ul style="margin-bottom: 1em;"&gt;
	&lt;li&gt;The per-redirection checkboxes in the new dialog are not controlled by &lt;code&gt;AllowSignedFiles&lt;/code&gt;. Even with a properly trusted and whitelisted signature, users still see the redirection dialog on first use. There's a separate set of policies for which redirections are allowed on the server side; the client-side checkboxes are a user-consent UI rather than a trust decision.&lt;/li&gt;
	&lt;li&gt;There's a temporary "revert to pre-April dialog" switch at &lt;code&gt;HKLM\Software\Policies\Microsoft\Windows NT\Terminal Services\Client\RedirectionWarningDialogVersion = 1&lt;/code&gt;. Don't rely on it — Microsoft has been explicit that it will be removed in a future update.&lt;/li&gt;
	&lt;li&gt;Windows has no built-in &lt;code&gt;.rdp&lt;/code&gt; signature verifier. &lt;code&gt;rdpsign.exe /v&lt;/code&gt; is "verbose", not "verify"; in practice the only verifier is Remote Desktop Connection opening the file. Signotaur's &lt;code&gt;verify&lt;/code&gt; command will validate the signature and cert chain offline if you want a CI-friendly check.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;If you'd rather not think about any of this&lt;/h2&gt;

&lt;p&gt;The short version: get a code-signing certificate from a public CA that chains to a Windows-preinstalled root, register it with your Signotaur server, sign your &lt;code&gt;.rdp&lt;/code&gt; files as part of your distribution workflow, and push the &lt;code&gt;AllowSignedFiles&lt;/code&gt; + &lt;code&gt;TrustedCertThumbprints&lt;/code&gt; policy out via GPO. After that, signed &lt;code&gt;.rdp&lt;/code&gt; files open with no dialog, and the next time Microsoft tightens the rules you've already done the trust-deployment work.&lt;/p&gt;

&lt;hr /&gt;
&lt;p&gt;For command-line details and the full signing command reference see the &lt;a href="https://docs.finalbuilder.com/sn/1.0/"&gt;Signotaur documentation&lt;/a&gt;. If you run into something specific — especially if you have an internal CA or a less-common PKCS#11 token in play — our support team is happy to help.&lt;/p&gt;
</description><guid isPermaLink="false">882</guid></item><item><title>Managing Certificate and API Key Expiry with Signotaur</title><link>https://www.finalbuilder.com/resources/blogs/postid/879/managing-certificate-and-api-key-expiry-with-signotaur</link><category>.NET,Code Signing,Continua CI,Delphi,FinalBuilderSignotaur</category><pubDate>Fri, 13 Mar 2026 03:18:12 GMT</pubDate><description>&lt;style type="text/css"&gt;
	div.blog_content h1 { font-size: 1.9rem; margin-bottom: 0.3rem; }
    div.blog_content h2 { font-size: 1.4rem; margin-top: 2.2rem; border-bottom: 1px solid #e0e0e0; padding-bottom: 0.4rem; }
    div.blog_content h3 { font-size: 1.15rem; margin-top: 1.6rem; color: #222;}
    div.blog_content strong {  font-weight: 600;  color: #888;}
    div.blog_content .meta { color: #777; font-size: 0.9rem; margin-bottom: 2rem; }
    div.blog_content code { background: #f4f4f4; padding: 0.15em 0.4em; border-radius: 3px; font-size: 0.92em; }
    div.blog_content pre { background: #f4f4f4; padding: 1rem; border-radius: 5px; overflow-x: auto; }
    div.blog_content pre code { background: none; padding: 0; }
    div.blog_content a { color: #0066cc; }
    div.blog_content img { max-width: 100%; border: 1px solid #ddd; border-radius: 4px; margin: 1rem 0; }
    div.blog_content .note { background: #eef6ff; border-left: 4px solid #0066cc; padding: 0.8rem 1rem; margin: 1.2rem 0; border-radius: 0 4px 4px 0; }
    div.blog_content ol { margin: 1rem 0 1.5rem 1.5rem; padding-left: 0.5rem;}
    div.blog_content ol li {  margin-bottom: 0.7rem;  line-height: 1.6;}
    div.blog_content ol li strong {  font-weight: 600;}
    div.blog_content ul li {  margin-bottom: 0.45rem;}
&lt;/style&gt;
&lt;div class="note"&gt;&lt;strong&gt;In this article:&lt;/strong&gt;
&lt;ul&gt;
	&lt;li&gt;Why code signing certificates now expire sooner&lt;/li&gt;
	&lt;li&gt;How certificate labels remove thumbprints from build scripts&lt;/li&gt;
	&lt;li&gt;How to rotate and renew API keys safely&lt;/li&gt;
	&lt;li&gt;How to automate the process in Continua CI&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

&lt;h2&gt;Shorter Certificate Lifetimes Are Coming&lt;/h2&gt;

&lt;p&gt;Code signing certificates used to last up to three years. As of &lt;strong&gt;March 1, 2026&lt;/strong&gt;, that is no longer the case.&lt;/p&gt;

&lt;p&gt;The CA/Browser Forum adopted &lt;strong&gt;Ballot CSC-31&lt;/strong&gt; on November 17, 2025, reducing the maximum validity period for publicly-trusted code signing certificates from 39 months to &lt;strong&gt;460 days&lt;/strong&gt; (roughly 15 months). For most teams, that means certificate renewals are now an annual operational task rather than an occasional one.&lt;/p&gt;

&lt;p&gt;When a certificate is renewed, it receives a new thumbprint, and build scripts that reference the old thumbprint must be updated. In large CI/CD environments, tracking down every reference can be tedious and error-prone.&lt;/p&gt;

&lt;p&gt;Separately, API keys used by CI agents to authenticate with the signing server have their own lifecycle and eventually need to be rotated. Replacing them without interrupting active build pipelines can be challenging.&lt;/p&gt;

&lt;p&gt;Signotaur addresses both concerns. &lt;strong&gt;Label-based certificate selection&lt;/strong&gt; decouples build pipelines from individual certificates, while &lt;strong&gt;API key rotation with overlap&lt;/strong&gt; allows credentials to be replaced without downtime. Together they turn what used to be stressful maintenance tasks into routine operations.&lt;/p&gt;

&lt;h2&gt;Certificate Labels: Automatic Certificate Rotation&lt;/h2&gt;

&lt;h3&gt;The Thumbprint Problem&lt;/h3&gt;

&lt;p&gt;Traditionally, build scripts reference a code signing certificate by its SHA-1 thumbprint — a 40-character hex string that uniquely identifies the certificate. When you renew, you get a new certificate with a new thumbprint, so every script that signs code needs to be updated. If you sign across multiple CI configurations, that means tracking down and editing each one.&lt;/p&gt;

&lt;h3&gt;Labels to the Rescue&lt;/h3&gt;

&lt;p&gt;Signotaur lets you assign a &lt;strong&gt;label&lt;/strong&gt; to each registered certificate — for example, &lt;code&gt;production&lt;/code&gt; or &lt;code&gt;nightly&lt;/code&gt;. When you request a signing operation by label instead of thumbprint, Signotaur automatically selects the certificate with the &lt;strong&gt;latest expiry date&lt;/strong&gt; among all enabled, non-expired certificates that share that label. This ensures that newly issued certificates automatically take precedence.&lt;/p&gt;

&lt;p&gt;The rotation workflow is straightforward:&lt;/p&gt;

&lt;ol&gt;
	&lt;li&gt;Register your renewed certificate and assign it the same label as the outgoing one.&lt;/li&gt;
	&lt;li&gt;Builds automatically pick up the new certificate — no script changes required.&lt;/li&gt;
	&lt;li&gt;The old certificate expires naturally; remove it from Signotaur when you're ready.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;Expiration Monitoring&lt;/h3&gt;

&lt;p&gt;Signotaur's background monitoring service checks certificate expiration &lt;strong&gt;daily&lt;/strong&gt; and sends email notifications to administrators at configurable intervals. The defaults are &lt;strong&gt;30, 14, 7, 3, and 1 day(s)&lt;/strong&gt; before expiry, with an additional alert if a certificate has already expired. You can customise these warning thresholds in the server configuration.&lt;/p&gt;

&lt;p&gt;During a rotation window — when both the old and new certificates are registered with the same label — the admin UI highlights the duplicate label so you can confirm the overlap is intentional.&lt;/p&gt;

&lt;p&gt;&lt;img alt="Screenshot: Certificate list in the Signotaur admin UI showing two certificates sharing the 'production' label. The older certificate shows an expiry warning badge." src="https://cdn.finalbuilder.com/blog/daves/managing-certificate-and-api-key-expiry/screenshot-cert-labels.png" /&gt;&lt;/p&gt;

&lt;h2&gt;API Key Rotation with Overlap&lt;/h2&gt;

&lt;h3&gt;Why Rotate Keys?&lt;/h3&gt;

&lt;p&gt;API keys grant access to your signing service. If a key is leaked or reused indefinitely, it becomes a long-lived security risk. Regular rotation limits the impact if a key is compromised, satisfies compliance requirements, and handles natural key expiry gracefully. But naive rotation — revoke old, issue new — creates a window where CI agents holding the old key start failing.&lt;/p&gt;

&lt;h3&gt;How Signotaur Handles It&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;rotate-key&lt;/code&gt; command creates a new API key while keeping the old one valid for a configurable &lt;strong&gt;overlap period&lt;/strong&gt; of &lt;strong&gt;0–30 days&lt;/strong&gt; (default: &lt;strong&gt;7 days&lt;/strong&gt;). During this window, both keys are accepted, allowing CI agents and environments to transition without interruption.&lt;/p&gt;

&lt;p&gt;Once the overlap period expires, the old key is &lt;strong&gt;automatically revoked&lt;/strong&gt;. If you prefer to manage revocation manually, pass &lt;code&gt;--no-auto-revoke&lt;/code&gt; and the old key will remain valid until you explicitly revoke it.&lt;/p&gt;

&lt;p&gt;&lt;img alt="Screenshot: API Keys page in the Signotaur admin UI showing a rotated key pair. The old key displays an 'Auto-revoke' date and the new key is marked as active." src="https://cdn.finalbuilder.com/blog/daves/managing-certificate-and-api-key-expiry/screenshot-api-key-rotation.png" /&gt;&lt;/p&gt;

&lt;h3&gt;Safety Guardrails&lt;/h3&gt;

&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Role required&lt;/strong&gt; — users must be assigned the &lt;strong&gt;ApiKeyRotator&lt;/strong&gt; role before they can rotate keys. An administrator can assign this role in the Signotaur admin UI.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Rate limiting&lt;/strong&gt; — a maximum of 5 rotations per user per 24-hour period prevents accidental key sprawl.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Linear chain only&lt;/strong&gt; — a key that has already been rotated cannot be rotated again; you must use the successor key. This prevents branching into multiple active key chains.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Proactive expiry checking&lt;/strong&gt; — the sign command accepts a &lt;code&gt;--fail-if-expiring-within&lt;/code&gt; flag (e.g. &lt;code&gt;14d&lt;/code&gt;). If the API key used for signing will expire within that window, the command fails immediately with a clear message — catching the problem in CI before it causes a real signing failure.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Conditional Rotation&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;--if-expiring-within&lt;/code&gt; flag on &lt;code&gt;rotate-key&lt;/code&gt; makes rotation idempotent: the key is only rotated if it expires within the specified duration (e.g. &lt;code&gt;14d&lt;/code&gt;, &lt;code&gt;1w&lt;/code&gt;, &lt;code&gt;24h&lt;/code&gt;). This makes it safe to run &lt;code&gt;rotate-key&lt;/code&gt; on every CI build or on a nightly schedule without generating unnecessary keys.&lt;/p&gt;

&lt;p&gt;Example scheduled rotation command:&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;signotaur rotate-key --if-expiring-within 14d&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Key Renewal&lt;/h3&gt;

&lt;p&gt;By default, a rotated key &lt;strong&gt;inherits the old key's expiry date&lt;/strong&gt;. If the old key had 30 days of validity remaining, the new key also expires in 30 days. Over time, repeatedly rotating a key gradually shortens its remaining lifetime — which can be a problem for long-running automation.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;--renew&lt;/code&gt; flag gives the new key a &lt;strong&gt;fresh validity period&lt;/strong&gt; starting from the rotation date, rather than inheriting whatever time was left on the old key. Without a value, it uses the server default of &lt;strong&gt;90 days&lt;/strong&gt;; with a value (e.g. &lt;code&gt;--renew 180d&lt;/code&gt;), it sets a specific duration up to a maximum of &lt;strong&gt;365 days&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This pairs naturally with conditional rotation — check whether the key is approaching expiry, and if so, rotate and renew in a single command:&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;signotaur rotate-key --if-expiring-within 14d --renew&lt;/code&gt;&lt;/pre&gt;

&lt;div class="note"&gt;If the renewal duration would be &lt;em&gt;shorter&lt;/em&gt; than the old key's remaining validity (for example renewing for 30 days when 60 days remain), the command fails as a safety measure. Pass &lt;code&gt;--allow-validity-reduction&lt;/code&gt; to override this check when the shorter duration is intentional.&lt;/div&gt;

&lt;h2&gt;Putting It Together in Continua CI&lt;/h2&gt;

&lt;p&gt;Continua CI ships dedicated &lt;strong&gt;Signotaur actions&lt;/strong&gt; for both signing and key rotation, so you can wire up the entire workflow without writing any custom scripts. Before configuring those actions, you'll need to assign a label to your certificates in the Signotaur admin UI.&lt;/p&gt;

&lt;h3&gt;Assigning a Label to Your Certificates&lt;/h3&gt;

&lt;p&gt;In the Signotaur admin UI, navigate to &lt;strong&gt;Certificates&lt;/strong&gt; and either add a new certificate or edit an existing one. In the certificate dialog you'll find two name fields:&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Alias&lt;/strong&gt; — a unique display name for the certificate (auto-generated by default, e.g. "CodeSigningCert (2027-12-31)").&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Label&lt;/strong&gt; — an optional identifier used for CLI and CI/CD certificate selection, e.g. &lt;code&gt;production&lt;/code&gt;. Multiple certificates can share the same label. Matching is case-insensitive, so &lt;code&gt;Production&lt;/code&gt; and &lt;code&gt;production&lt;/code&gt; resolve the same way.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you renew a certificate, register the new one and assign it the same label as the outgoing certificate. The admin UI will show an orange notice confirming that multiple active certificates share the label and that the one with the latest expiry will be selected automatically. No build script changes needed.&lt;/p&gt;

&lt;p&gt;&lt;img alt="Screenshot: Signotaur certificate edit dialog showing the Alias and Label fields. The Label field is set to 'production'." src="https://cdn.finalbuilder.com/blog/daves/managing-certificate-and-api-key-expiry/screenshot-cert-edit-label.png" /&gt;&lt;/p&gt;

&lt;p&gt;For full details, see the &lt;a href="https://docs.finalbuilder.com/sn/1.0/server/admin/certificates/certificates.html"&gt; Certificates documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Setting Up the Rotate Keys Action&lt;/h3&gt;

&lt;p&gt;Add the &lt;strong&gt;Signotaur Rotate Keys&lt;/strong&gt; action to a stage — either in a scheduled maintenance configuration or directly in your build configuration. With the &lt;strong&gt;If Expiring Within&lt;/strong&gt; condition the action only rotates the key when expiry is approaching, so it can safely run on every build.&lt;/p&gt;

&lt;p&gt;The action is organised into several tabs:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Signotaur Rotate Keys tab&lt;/strong&gt; — configure &lt;strong&gt;Overlap Days&lt;/strong&gt; (how long the old key remains valid alongside the new one, default 7) and whether to &lt;strong&gt;Disable auto-revocation&lt;/strong&gt; if you prefer to revoke old keys manually.&lt;/p&gt;

&lt;p&gt;&lt;img alt="Screenshot: Continua CI Signotaur Rotate Keys action — Main tab showing Overlap Days and Disable auto-revocation options." src="https://cdn.finalbuilder.com/blog/daves/managing-certificate-and-api-key-expiry/screenshot-rotate-keys-main.png" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Server tab&lt;/strong&gt; — set the &lt;strong&gt;Server URL&lt;/strong&gt; for your Signotaur instance and the &lt;strong&gt;API Key Source&lt;/strong&gt;. Select &lt;em&gt;Value (from variable)&lt;/em&gt; and reference a server variable (e.g. &lt;code&gt;%SignotaurAPIKey%&lt;/code&gt;) to avoid hard-coding keys in the action.&lt;/p&gt;

&lt;p&gt;&lt;img alt="Screenshot: Continua CI Signotaur Rotate Keys action — Server tab showing Server URL and API Key Source set to a server variable." src="https://cdn.finalbuilder.com/blog/daves/managing-certificate-and-api-key-expiry/screenshot-rotate-keys-server.png" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conditions tab&lt;/strong&gt; — set &lt;strong&gt;If Expiring Within&lt;/strong&gt; to make the rotation conditional (e.g. &lt;code&gt;14d&lt;/code&gt; to only rotate if expiry is within two weeks). Enable &lt;strong&gt;Ignore already rotated error&lt;/strong&gt; to safely run the action in concurrent CI builds without failure if the key was already rotated by another build.&lt;/p&gt;

&lt;p&gt;&lt;img alt="Screenshot: Continua CI Signotaur Rotate Keys action — Conditions tab showing If Expiring Within and Ignore already rotated error options." src="https://cdn.finalbuilder.com/blog/daves/managing-certificate-and-api-key-expiry/screenshot-rotate-keys-conditions.png" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Renewal tab&lt;/strong&gt; — enable the &lt;strong&gt;Renew&lt;/strong&gt; checkbox to give the new key a fresh validity period instead of inheriting the old key's remaining lifetime. Set a specific &lt;strong&gt;Renew Duration&lt;/strong&gt; (e.g. &lt;code&gt;90d&lt;/code&gt;), or leave it blank to use the server default. Check &lt;strong&gt;Allow validity reduction&lt;/strong&gt; if the renewal duration may be shorter than the old key's remaining validity.&lt;/p&gt;

&lt;p&gt;&lt;img alt="Screenshot: Continua CI Signotaur Rotate Keys action — Renewal tab showing Renew checkbox, Renew Duration, and Allow validity reduction options." src="https://cdn.finalbuilder.com/blog/daves/managing-certificate-and-api-key-expiry/screenshot-rotate-keys-renewal.png" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output tab&lt;/strong&gt; — choose &lt;strong&gt;Set Variable&lt;/strong&gt; as the output destination and select a &lt;strong&gt;Server variable&lt;/strong&gt; to store the new key. This way your sign actions automatically pick up the rotated key without any manual updates.&lt;/p&gt;

&lt;p&gt;&lt;img alt="Screenshot: Continua CI Signotaur Rotate Keys action — Output tab with Set Variable selected, storing the new key in a server-scoped variable." src="https://cdn.finalbuilder.com/blog/daves/managing-certificate-and-api-key-expiry/screenshot-rotate-keys-output.png" /&gt;&lt;/p&gt;

&lt;p&gt;Full documentation: &lt;a href="https://docs.finalbuilder.com/ci/1.0/user-guide/actions/signing-actions/signotaur-rotate-keys-action.html"&gt; Signotaur Rotate Keys Action &lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Setting Up the Sign Action with Label Selection&lt;/h3&gt;

&lt;p&gt;Add the &lt;strong&gt;Signotaur Sign&lt;/strong&gt; action to your build stage, after compilation and before packaging.&lt;/p&gt;

&lt;p&gt;Key fields:&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Files to Sign&lt;/strong&gt; — glob patterns for your build output, e.g. &lt;code&gt;**/*.exe&lt;/code&gt;, &lt;code&gt;**/*.dll&lt;/code&gt;.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Certificate Selection Mode&lt;/strong&gt; — set to &lt;strong&gt;Label&lt;/strong&gt;.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Label&lt;/strong&gt; — your shared label, e.g. &lt;code&gt;production&lt;/code&gt;. Signotaur will automatically select the certificate with the latest expiry date.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;API Key Source&lt;/strong&gt; — point to the server variable populated by the Rotate Keys action, or a securely stored key.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Fail If Expiring Within&lt;/strong&gt; — e.g. &lt;code&gt;14d&lt;/code&gt;. If the API key expires within two weeks, the action fails early so you can rotate before it becomes a blocker.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Timestamp Server &amp; Digest&lt;/strong&gt; — configure your preferred timestamping authority and hash algorithm.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="Screenshot: Continua CI Signotaur Sign action — Certificate tab showing Selection Mode set to Label with value 'production'." src="https://cdn.finalbuilder.com/blog/daves/managing-certificate-and-api-key-expiry/screenshot-sign-certificate.png" /&gt; 
&lt;/p&gt;
&lt;p&gt;&lt;img alt="Screenshot: Continua CI Signotaur Sign action — Server tab showing Fail If Expiring Within set to '14d'." src="https://cdn.finalbuilder.com/blog/daves/managing-certificate-and-api-key-expiry/screenshot-sign-server.png" /&gt;&lt;/p&gt;

&lt;p&gt;Full documentation: &lt;a href="https://docs.finalbuilder.com/ci/1.0/user-guide/actions/signing-actions/signotaur-sign-action.html"&gt; Signotaur Sign Action &lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Typical Rotation Workflow&lt;/h2&gt;

&lt;p&gt;In practice, certificate and API key rotation can be handled with a small amount of scheduled automation in your CI system.&lt;/p&gt;

&lt;ol&gt;
	&lt;li&gt;&lt;strong&gt;Register renewed certificates&lt;/strong&gt; in Signotaur and assign them the same label as the previous certificate.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;CI builds continue using the label&lt;/strong&gt;, automatically selecting the certificate with the latest expiry date.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Schedule periodic API key checks&lt;/strong&gt; using the &lt;code&gt;rotate-key --if-expiring-within&lt;/code&gt; option.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;The new key is written to a CI server variable&lt;/strong&gt;, allowing build pipelines to automatically use the rotated key.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Use &lt;code&gt;--renew&lt;/code&gt;&lt;/strong&gt; so rotated keys receive a fresh validity period rather than inheriting the old key's remaining lifetime.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Retire old certificates and keys&lt;/strong&gt; once they are no longer needed.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;Wrapping Up&lt;/h2&gt;

&lt;p&gt;With code signing certificate lifetimes dropping to roughly 15 months, the days of "set it and forget it" certificate management are over. Signotaur's label-based signing means your CI/CD pipelines don't need to know — or care — which specific certificate is current. And overlap-based API key rotation ensures you can swap credentials without any signing downtime.&lt;/p&gt;

&lt;p&gt;These features are already available in Signotaur. If you're evaluating it, check out the &lt;a href="https://docs.finalbuilder.com/signotaur/1.0/"&gt;Signotaur documentation&lt;/a&gt; to get started.&lt;/p&gt;
</description><guid isPermaLink="false">879</guid></item><item><title>Using YAML with Delphi - VSoft.YAML</title><link>https://www.finalbuilder.com/resources/blogs/postid/875/using-yaml-with-delphi-vsoftyaml</link><category>Delphi,FinalBuilder,Open Source</category><pubDate>Tue, 16 Sep 2025 13:21:38 GMT</pubDate><description>&lt;h2&gt;Introduction&lt;/h2&gt;

&lt;p&gt;Almost every modern Delphi application needs a way to store structured data: configuration settings, runtime options, or even project metadata. For decades, developers have relied on INI files for simple key/value storage, XML for deeply structured documents, or JSON as a lightweight alternative.&lt;/p&gt;

&lt;p&gt;But there’s another option that has grown into the de facto standard in DevOps and configuration management: YAML.&lt;/p&gt;

&lt;p&gt;This article introduces &lt;a href="https://github.com/VSoftTechnologies/VSoft.YAML" target="_blank"&gt;VSoft.YAML&lt;/a&gt; - an open-source Delphi library that makes working with YAML straightforward. We’ll cover why you might choose YAML over INI, XML, or JSON, then dive into practical Delphi code examples for parsing, editing, and writing YAML.&lt;/p&gt;

&lt;h2&gt;Why YAML?&lt;/h2&gt;

&lt;h3&gt;Human-Readability&lt;/h3&gt;

&lt;p&gt;YAML is designed for humans first. Compare the following formats describing a database configuration:&lt;/p&gt;

&lt;h4&gt;YAML&lt;/h4&gt;

&lt;pre class="brush:plain; toolbar:false;"&gt;
database:
  host: localhost
  port: 5432
  user: admin
  password: secret

            &lt;/pre&gt;

&lt;h4&gt;JSON&lt;/h4&gt;

&lt;pre class="brush:jscript; toolbar:false;"&gt;
{
    "database": {
    "host": "localhost",
    "port": 5432,
    "user": "admin",
    "password": "secret"
    }
}

            &lt;/pre&gt;

&lt;h4&gt;XML&lt;/h4&gt;

&lt;pre class="brush:xml; toolbar:false;"&gt;
&lt;database&gt;
    &lt;host&gt;localhost&lt;/host&gt;
    &lt;port&gt;5432&lt;/port&gt;
    &lt;user&gt;admin&lt;/user&gt;
    &lt;password&gt;secret&lt;/password&gt;
&lt;/database&gt;
            &lt;/pre&gt;

&lt;p&gt;The YAML version is the least noisy, especially when configurations get larger.&lt;/p&gt;

&lt;h4&gt;Expressiveness&lt;/h4&gt;

&lt;ul&gt;
	&lt;li&gt;Supports mappings (key/value), sequences (lists), and scalars (strings, numbers, booleans).&lt;/li&gt;
	&lt;li&gt;Handles deeply nested structures naturally.&lt;/li&gt;
	&lt;li&gt;More flexible than INI files, which are limited to sections and key/value pairs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Adoption&lt;/h4&gt;

&lt;ul&gt;
	&lt;li&gt;YAML is everywhere, especially in DevOps.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Introducing VSoft.YAML&lt;/h3&gt;

&lt;p&gt;VSoft.YAML is a pure Delphi implementation of a YAML 1.2 parser and emitter:&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;No external dependencies&lt;/strong&gt; — just add the source to your project.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Round-trip capable&lt;/strong&gt; — parse, modify, and write YAML without losing formatting.&lt;/li&gt;
	&lt;li&gt;Supports multiple documents in a single YAML stream.&lt;/li&gt;
	&lt;li&gt;Supports reading/writing JSON&lt;/li&gt;
	&lt;li&gt;Extensive &lt;a href="https://github.com/VSoftTechnologies/VSoft.YAML/blob/main/docs/JSONPath-Syntax.md" target="_blank"&gt;JSONPath&lt;/a&gt; support&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Getting Started&lt;/h3&gt;

&lt;h4&gt;Installation&lt;/h4&gt;

&lt;p&gt;Clone the repo or add it as a Git submodule:&lt;/p&gt;

&lt;pre brush="bash"&gt;
git clone https://github.com/VSoftTechnologies/VSoft.YAML.git
            &lt;/pre&gt;

&lt;p&gt;Then add the &lt;code&gt;VSoft.YAML\Source&lt;/code&gt; folder to your Delphi project’s search path.&lt;/p&gt;

&lt;h3&gt;Parsing YAML&lt;/h3&gt;

&lt;p&gt;The most common scenario is loading YAML from a string or file.&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
uses
  VSoft.YAML;

var
  Doc: IYAMLDocument;
  YamlText: string;
begin
  YamlText :=
    'database:' + sLineBreak +
    ' host: localhost' + sLineBreak +
    ' port: 5432' + sLineBreak +
    ' user: admin' + sLineBreak +
    ' password: secret';

    Doc := TYAML.LoadFromString(YamlText);
    Writeln('Database host: ', Doc.Root.Values['database'].Values['host'].AsString);
    Writeln('Database port: ', Doc.Root.Values['database'].Values['port'].AsInteger);
end;
            &lt;/pre&gt;

&lt;p&gt;To load from a file, just call &lt;code&gt;TYAML.LoadFromFile&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;Traversing Sequences&lt;/h3&gt;

&lt;p&gt;YAML supports lists (called &lt;strong&gt;sequences&lt;/strong&gt;).&lt;/p&gt;

&lt;h4&gt;Example YAML&lt;/h4&gt;

&lt;pre class="brush:plain; toolbar:false;"&gt;
servers:
- name: web01
  ip: 10.0.0.1
- name: web02
  ip: 10.0.0.2
            &lt;/pre&gt;

&lt;h4&gt;Delphi Code&lt;/h4&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
var
    doc : IYAMLDocument;
    servers: IYAMLSequence;
    server : IYAMLMapping; 
    i: integer;
begin
    doc := TYAML.LoadFromFile('c:\test\config.yaml');
    servers := Doc.Root.Values['servers'].AsSequence;
    for i := 0 to servers.Count - 1 do
    begin
        server := Servers.Items[I].AsMapping;
        Writeln(Format('%s (%s)',[server.Values['name'].AsString, Server.Values['ip'].AsString]));
    end;
end;
          &lt;/pre&gt;

&lt;h3&gt;Modifying YAML&lt;/h3&gt;

&lt;p&gt;Once parsed, you can update values and write them back out:&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
var
    root: IYAMLMapping;
begin
    root := Doc.Root.AsMapping;
    root.AddOrSetValue('environment', 'production');
    TYAML.WriteToFile(doc, 'c:\test\config.yaml')
end;
            &lt;/pre&gt;

&lt;h2&gt;Practical Use Cases for Delphi Developers&lt;/h2&gt;

&lt;ul&gt;
	&lt;li&gt;Configuration files — ship your app with config.yaml instead of INI or XML.&lt;/li&gt;
	&lt;li&gt;DevOps integration — generate or consume YAML configs for devops tools.&lt;/li&gt;
	&lt;li&gt;Structured data — when you need nested lists or dictionaries without verbosity.&lt;/li&gt;
	&lt;li&gt;Collaboration — YAML files are easy for non-developers to read and edit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Tips and Best Practices&lt;/h2&gt;

&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Use JSON when machine-only consumption is expected.&lt;/strong&gt;&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Use YAML when humans will edit the config.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;YAML Rules to be aware of&lt;/h2&gt;

&lt;p&gt;Even though YAML is designed to be human-friendly, it comes with its own quirks. Here are a few issues you might run into when using YAML with Delphi:&lt;/p&gt;

&lt;h3&gt;1. Indentation Rules&lt;/h3&gt;

&lt;ul&gt;
	&lt;li&gt;YAML is indentation-sensitive.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Spaces only&lt;/strong&gt; — tabs are not allowed for indentation.&lt;/li&gt;
	&lt;li&gt;A single misplaced space can completely change the structure.&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="brush:plain; toolbar:false;"&gt;
valid:
  key1: value
  key2: value

invalid:
  key1: value
   key1: value # wrong indentation
            &lt;/pre&gt;

&lt;h3&gt;2. Duplicate Keys&lt;/h3&gt;

&lt;p&gt;Unlike JSON, YAML technically allows duplicate keys in mappings, but this can lead to unexpected behavior. YAML Parsers will typically keep only the last occurrence.&lt;/p&gt;

&lt;pre class="brush:plain; toolbar:false;"&gt;
settings:
  timeout: 10
  timeout: 30 # overwrites the first one
            &lt;/pre&gt;

&lt;p&gt;VSoft.YAML has a parser option to control the handling of duplicate keys&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
options := TYAML.CreateParserOptions;
options.DuplicateKeyBehavior := TYAMLDuplicateKeyBehavior.dkError; // default is dkOverwrite
doc := TYAML.LoadFromFile(fileName, options);
            &lt;/pre&gt;

&lt;p&gt;Best practice: avoid duplicates in configs, and add validation in your app if needed.&lt;/p&gt;

&lt;h3&gt;3. Scalars and Quoting&lt;/h3&gt;

&lt;p&gt;YAML is permissive about quoting strings, which can sometimes surprise you:&lt;/p&gt;

&lt;pre class="brush:plain; toolbar:false;"&gt;
path: C:\Temp\file.txt # might be misinterpreted due to backslashes
             &lt;/pre&gt;

&lt;p&gt;Safer to quote unusual strings:&lt;/p&gt;

&lt;pre class="brush:plain; toolbar:false;"&gt;
path: "C:\Temp\file.txt"
            &lt;/pre&gt;

&lt;h3&gt;4. Boolean Values&lt;/h3&gt;

&lt;p&gt;YAML recognizes a wide set of values as booleans: yes/no, true/false, on/off.&lt;/p&gt;

&lt;pre class="brush:plain; toolbar:false;"&gt;
feature_enabled: yes # interpreted as boolean true
            &lt;/pre&gt;

&lt;p&gt;If you actually mean the literal string "yes", you must quote it:&lt;/p&gt;

&lt;pre class="brush:plain; toolbar:false;"&gt;
feature_enabled: "yes"
                        &lt;/pre&gt;

&lt;h3&gt;5. Comments&lt;/h3&gt;

&lt;p&gt;While YAML supports # comments, they are not part of the data model and usually not preserved&lt;/p&gt;

&lt;p&gt;VSoft.YAML &lt;strong&gt;does&lt;/strong&gt; attempt to preserve comments. This is non standard. Generally, comments before mappings (objects) and sequences(arrays) are preserved, comments after scalar values may be preserved.&lt;/p&gt;

&lt;p&gt;Blank lines will not be preserved.&lt;/p&gt;

&lt;h3&gt;6. Large or Complex Documents&lt;/h3&gt;

&lt;ul&gt;
	&lt;li&gt;For deeply nested structures, readability can drop.&lt;/li&gt;
	&lt;li&gt;Split configs into multiple YAML files if possible.&lt;/li&gt;
	&lt;li&gt;Use &lt;code&gt;---&lt;/code&gt;(start) and &lt;code&gt;...&lt;/code&gt;(end) to separate documents in a single file if needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;7. Type Guessing&lt;/h3&gt;

&lt;p&gt;By default, YAML interprets unquoted values:&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;&lt;code&gt;42&lt;/code&gt; → integer&lt;/li&gt;
	&lt;li&gt;&lt;code&gt;3.14&lt;/code&gt; → float&lt;/li&gt;
	&lt;li&gt;&lt;code&gt;3.1.4&lt;/code&gt; → string&lt;/li&gt;
	&lt;li&gt;&lt;code&gt;true&lt;/code&gt; → boolean&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to enforce string semantics, quote the value:&lt;/p&gt;

&lt;pre class="brush:plain; toolbar:false;"&gt;
port: "5432"
            &lt;/pre&gt;

&lt;h3&gt;8. CRLF vs LF Line Endings&lt;/h3&gt;

&lt;p&gt;VSoft.YAML is tolerant of Windows vs Unix line endings, but if your configs are shared across systems, normalize line endings in your source control to avoid “it works on my machine” issues.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;YAML offers developers a unique combination of human readability, expressiveness, and versatility. Unlike INI files, it can represent complex nested structures; unlike XML, it remains clean and concise; and unlike JSON, it's easier for humans to read and maintain.&lt;/p&gt;

&lt;p&gt;The full list of features support by VSoft.YAML is &lt;a href="https://github.com/VSoftTechnologies/VSoft.YAML/blob/main/docs/YAML-Features-Implementation.md" target="_blank"&gt;available here.&lt;/a&gt;&lt;/p&gt;
</description><guid isPermaLink="false">875</guid></item><item><title>DPM Package Manager - Progress update</title><link>https://www.finalbuilder.com/resources/blogs/postid/842/dpm-package-manager-progress-update</link><category>Delphi,DPM</category><pubDate>Wed, 24 Feb 2021 10:46:15 GMT</pubDate><description>        &lt;p&gt;In December 2019, I &lt;a href="/resources/blogs/introducing-dpm-a-package-manager-for-delphi" target="_blank"&gt;blogged&lt;/a&gt; about a package manager for Delphi that I am working on. This post is
            a progress update that shows where it's at and what's left to do to get to v1.&lt;/p&gt;

        &lt;h3&gt;DPM Recap&lt;/h3&gt;

        &lt;p&gt;
            For those not familiar with what I am trying to achieve here, I highly recommend reading my original &lt;a href="/resources/blogs/delphi-package-manager-rfc" target="_blank"&gt;
                Delphi Package Manager RFC&lt;/a&gt; post. In that post I detailed my ideas, and some of the challenges that Delphi presents when compared to other development environments.
        &lt;/p&gt;

        &lt;p&gt;
            In December 2019, the bare bones of DPM were there. We had a command line tool and that was it. We were able to create packages, install packages (and their dependencies) and restore them
            (restore ensures all referenced packages are present). Oh and we could list the available packages in our package feed (a folder).
        &lt;/p&gt;

        &lt;h3&gt;IDE Integration&lt;/h3&gt;

        &lt;p&gt;
            In the last 13 months there were around 175 commits to the DPM repository. In that time I have added an IDE plugin (that works in Delphi XE2 to 10.4). This involved the creation of several
            custom controls (I wasn't able to bend any existing ones to work how I wanted it to).
        &lt;/p&gt;

        &lt;p&gt;
            In addition to the work in the project repository, I also published &lt;a href="https://github.com/vsoftTechnologies/" target="_blank"&gt;several useful libraries&lt;/a&gt; that I needed for this
            project. DPM is now bootstrapped, to build DPM you need DPM, as it requires several libraries that are referenced as dpm packages.
        &lt;/p&gt;

        &lt;p&gt;
            In Nov 2020 I published the first alpha release that included an installer (code signed by VSoft Technologies) for installing both the command line tool and the IDE plugin (single
            installer, you can choose which IDE versions to install for). The installer allows you to install for the current user, or for all users (requires elevation to install).
        &lt;/p&gt;

        &lt;img src="https://cdn.finalbuilder.com/blog/vincent/dpm-progress/installer.png"&gt;
        &lt;p&gt;&lt;/p&gt;
        &lt;p&gt;
            I also did a zoom presentation about DPM to the Melbourne chapter of the Australian Delphi Users Group - a recording of that (long) presentation can be found &lt;a
               href="https://www.youtube.com/watch?v=TjVAMLfhgLo" target="_blank"&gt;here&lt;/a&gt;.
        &lt;/p&gt;

        &lt;p&gt;
            Adding IDE support for DPM was a massive undertaking. I had very little experience in developing Delphi IDE plugins (using the tools api) - and there were lots of subtle changes between
            delphi versions, getting things working correctly in 12 versions of Delphi was not easy. In particular, with the later versions of Delphi IDE that use VCL themes, getting things to look
            right (ie like a native part of the IDE) was a challenge.
        &lt;/p&gt;

        &lt;img src="https://cdn.finalbuilder.com/blog/vincent/dpm-progress/dpm-ide.png"&gt;
        &lt;p&gt;&lt;/p&gt;
        &lt;p&gt;The above image shows the installed packages for one of the projects in the project group, you get to this view by right clicking on the project node, or the DPM Packages node in the
            Project tree. &lt;/p&gt;
        &lt;p&gt;Note the view only shows the directly installed packages, not the transient dependencies - those you can see in the project tree under the DPM Packages node.&lt;/p&gt;
        &lt;p&gt;Before you can use DPM in the IDE, you need to configure a package source (a folder where your package files will live)&lt;/p&gt;
        &lt;p&gt;This can be done fron the command line&lt;/p&gt;
        &lt;pre&gt;dpm sources add -name=local -source=path to the folder you created&lt;/pre&gt;
        &lt;p&gt;&lt;/p&gt;
        &lt;p&gt;Or from the IDE Settings&lt;/p&gt;
        &lt;img src="https://cdn.finalbuilder.com/blog/vincent/dpm-progress/dpm-settings.png"&gt;
        &lt;p&gt;&lt;/p&gt;
        &lt;h3&gt;Compile during install&lt;/h3&gt;
        &lt;p&gt;
            The most recent updates added support for compiling packages during first install. Packages need to declare how to build in their dspec file, and dpm will use that and call msbuild to
            compile the packages if needed. DPM also records a bill of materials file (package.bom) in the package cache so that it can tell whether the package needs to be recompiled or not.
        &lt;/p&gt;

        &lt;p&gt;On first install, packages that are being compiled during the install process will take a little longer, but on subsequent installs or restores, the process is almost instant (a few ms).
        &lt;/p&gt;

        &lt;p&gt;
            Prior to adding this feature, building dpm on our Continua CI build agents took 13 minutes, much of which was taken up with compiling the dpm packages that it references (in particular,
            earlier versions of Delphi were very slow with spring4d). Since updating dpm on our agents with the new version, the entire build process for DPM (console app and 12 versions of the IDE
            plugin and the installer) takes less than 2 minutes.
        &lt;/p&gt;
        &lt;img src="https://cdn.finalbuilder.com/blog/vincent/dpm-progress/dpm-build-times.png"&gt;
        &lt;p&gt;&lt;/p&gt;
        &lt;h3&gt;Missing features&lt;/h3&gt;

        &lt;h4&gt;Project group support&lt;/h4&gt;

        &lt;p&gt;
            When installing packages, the dependency resolution code does not know about other projects in the project group, or what packages and versions they reference. This
            will be a problem for packages that include design time components that need to be loaded - the IDE can only load 1 version of a design time package. This is what I am currently working
            on.
        &lt;/p&gt;

        &lt;h4&gt;Design time packages&lt;/h4&gt;
        &lt;p&gt;DPM does not currently install design time packages into the IDE. This is dependent on project group support, so it's next on the list after project group support.&lt;/p&gt;

        &lt;h4&gt;Package Updates&lt;/h4&gt;
        &lt;p&gt;The ability to detect when package updates are available and make it easy to install those updates. There's an Updates tab in the IDE but it's non functional at this time.&lt;/p&gt;

        &lt;h4&gt;Package Repository&lt;/h4&gt;

        &lt;p&gt;In it's current state, DPM only supports folder based package feeds. This works fine, but it does have some limitations&lt;/p&gt;
        &lt;ul&gt;
            &lt;li&gt;Limted search abilities - limted to searching on the package filenames.&lt;/li&gt;
            &lt;li&gt;You have to download packages to a folder.&lt;/li&gt;
            &lt;li&gt;Package Authors have to host the package files somewhere (mine are under releases on their github projects).&lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;I have made a start on the Package Repository, but not a lot of progress since I'm focusing on the client site right now.&lt;/p&gt;

        &lt;h3&gt;Q &amp; A&lt;/h3&gt;

        &lt;h4&gt;Is it usable?&lt;/h4&gt;
        &lt;p&gt;In it's current state, it's only usable for non visual libraries. As I mentioned, the DPM projects all use DPM themselves, and
            we have DPM actions in FinalBuilder for running the Pack and Restore commands. &lt;/p&gt;
        &lt;p&gt;If you use any of my open source libraries like DUnitX, Delphi Mocks etc, I have created packages for all of those libraries, and also
            created mirror projects (just for hosting the package files) for some other popular libraries like Spring4D. &lt;/p&gt;
        &lt;p&gt;I would encourage library authors in particular to take a look and provide feedback.&lt;/p&gt;

        &lt;h4&gt;Where can we find it?&lt;/h4&gt;
        &lt;p&gt;DPM is an open source project on &lt;a href="https://github.com/DelphiPackageManager/DPM" target="_blank"&gt;GitHub&lt;/a&gt;, the installer can be found under &lt;a
               href="https://github.com/DelphiPackageManager/DPM/releases" target="_blank"&gt;Releases&lt;/a&gt;
            (under each release, there is an Assets dropdown section).&lt;/p&gt;
        &lt;img src="https://cdn.finalbuilder.com/blog/vincent/dpm-progress/installer-location.png"&gt;
        &lt;p&gt;&lt;/p&gt;

        &lt;h4&gt;What versions of Delphi does it support?&lt;/h4&gt;
        &lt;p&gt;Delphi XE2 to 10.4.2 - note that we compile with the latest updates installed for each compiler version. &lt;/p&gt;

        &lt;h4&gt;Why is it taking so long?&lt;/h4&gt;
        &lt;p&gt;Yes, someone asked that recently! This is a side project, free and open source. My primary focus is on running my business and working on our products (that keeps the lights on).&lt;/p&gt;

        &lt;h4&gt;Can we sponsor the project?&lt;/h4&gt;
        &lt;p&gt;Not right now, however it's something I'll look at in the future. &lt;/p&gt;

        &lt;h4&gt;Can we help?&lt;/h4&gt;
        &lt;p&gt;Absolutely. Fork the project on GitHub and clone it to your dev machine and spend some time getting to know the source code. Before making any pull requests, create an issue on github
            to discuss your ideas and make sure we on the same wavelength!&lt;/p&gt;</description><guid isPermaLink="false">842</guid></item><item><title>Advice for Delphi library authors</title><link>https://www.finalbuilder.com/resources/blogs/postid/841/advice-for-delphi-library-authors</link><category>Delphi,DPM</category><pubDate>Wed, 24 Feb 2021 00:57:00 GMT</pubDate><description>        &lt;p&gt;We use many third-party Delphi libraries to build FinalBuilder and Automise, and that brings plenty of issues when upgrading compiler versions. I've been using Delphi since 1995, both as a
            developer and as a component vendor, I have learned a thing or two about creating libraries that I would like to share. These are all ideas that make life easier for users, and make it
            easy to migrate from one version of Delphi to another.&lt;/p&gt;
        &lt;p&gt;There's no hard and fast rules on how Delphi Libraries are &lt;i&gt;supposed to be&lt;/i&gt; structured, these are just my preferences and things I have learned over the years. Hopefully this will
            help new and existing library authors.&lt;/p&gt;

        &lt;h3&gt;Folder Structure&lt;/h3&gt;
        &lt;p&gt;Keep the Source and the Packages in separate folders, this makes it easier to find the correct packages to compile, e.g :
        &lt;pre&gt;\Source
\Packages
\Demos&lt;/pre&gt;
        &lt;/p&gt;
        &lt;p&gt;Under Packages, create a folder for each compiler version your library supports, e.g:
        &lt;pre&gt;\Packages\Rad Studio XE8
\Packages\Rad Studio 10.0
\Packages\Rad Studio 10.1&lt;/pre&gt;
        &lt;/p&gt;
        &lt;h3&gt;Package Names&lt;/h3&gt;

        &lt;p&gt;Please, &lt;b&gt;do not&lt;/b&gt; put the Delphi version in the package project names.&lt;/p&gt;
        &lt;h4&gt;Bad!!!&lt;/h4&gt;
        &lt;pre&gt;MyProjectRun_D10_4.dproj
MyProjectDesign270.dproj&lt;/pre&gt;
        &lt;h4&gt;Good&lt;/h4&gt;
        &lt;pre&gt;MyProjectRun.dproj
MyProjectR.dproj
MyProjectDesign.dproj
MyProjectD.dproj&lt;/pre&gt;
        &lt;p&gt;&lt;/p&gt;
        &lt;p&gt;Why not put the compiler version in the package project name you might ask? Well the answer is that it makes upgrading compiler versions a major pain for users who link their
            projects with Runtime Packages (yes, that includes us).&lt;/p&gt;

        &lt;p&gt;The reason is that when you compile a package, it creates a packagename.dcp file and that is what your project references. So, if your package name is MyPackageRun_D10_4 then that is what
            will be added to projects that use it.&lt;/p&gt;


        &lt;pre class="brush:delphi; toolbar:false;"&gt;
package MyOwnPackage;
//...
requires
  rtl,
  vcl,
  MyPackageRun_D10_4,
  AnotherPackage_Sydney,
  YetAnotherPackage_D104,
//  ...
        &lt;/pre&gt;
        &lt;p&gt;&lt;/p&gt;
        &lt;p&gt;When Delphi 10.5 comes out, guess what the user has to do to upgrade their projects.... Yep, replace that all those package references with 10.5 versions (and the multitude of suffixes).
            Multiply that by a number
            of
            projects and a number of libraries (each with potentially multiple runtime packages) and you can see why this might be a pain.&lt;/p&gt;

        &lt;p&gt;Now you might say, but we don't want 15 versions of MyPackageRun.bpl laying about on users machines, and you would be right. The solution to this is a feature that has been around
            since Delphi 6 (2001) - &lt;a href="https://docwiki.embarcadero.com/RADStudio/Sydney/en/Compiler_directives_for_libraries_or_shared_objects_(Delphi)" target="_blank"&gt;LIBSUFFIX&lt;/a&gt;.&lt;/p&gt;
        &lt;img src="https://cdn.finalbuilder.com/blog/vincent/advice-for-d/libsuffix.png" alt="LIBSUFFIX"&gt;
        &lt;p&gt;&lt;/p&gt;
        &lt;p&gt;Setting LIBSUFFIX (on the Description section of project settings) will append the specified suffix to the BPL file name. So a suffix of _D10_4 will result in a package :&lt;/p&gt;
        &lt;pre&gt;MyPackageRun_D10_4.bpl&lt;/pre&gt;
        &lt;p&gt;&lt;/p&gt;
        &lt;p&gt;however, the DCP file will still be generated as :&lt;/p&gt;
        &lt;pre&gt;MyPackageRun.dcp&lt;/pre&gt;
        &lt;p&gt;&lt;/p&gt;
        &lt;p&gt;Remember it's the dcp file that our projects reference (for linking) - so by keeping the dcp file the same for all delphi versions, upgrading to a new compiler version just got a whole lot
            easier!&lt;/p&gt;

        &lt;p&gt;So when Delphi 10.5 comes out in the future, all I need to do is install the packages, no changes to my projects.&lt;/p&gt;

        &lt;p&gt;&lt;b&gt;Update&lt;/b&gt; : Someone pointed out that Delphi 10.4.1 support LIBSUFFIX $(Auto) - this will use the Delphi defined PackageVersion - which for 10.4 is 270. This is a nice addition 
            as it makes upgrading the package projects simpler. Of course if you don't like the PackageVersion suffix and use a custom one, then this is not for you.&lt;/p&gt;

        &lt;h3&gt;Use Explicit rebuild, not Rebuild as needed&lt;/h3&gt;
        &lt;p&gt;Have you ever encountered the error
        &lt;pre&gt;E2466 Never-build package 'XXX' requires always-build package 'YYY'&lt;/pre&gt;
        What this means is, a package, set to Expicit rebuild, references another package, set to 'Rebuild as needed', and it's a pain in the proverbial. Rebuild as needed is also referred to
        as Implicit Build - in dpk's you will see it as
        &lt;pre&gt;{$IMPLICITBUILD ON}&lt;/pre&gt;
        If that "Rebuild as needed" package is not part of your project group, guess what, you get to waste time closing and opening projects trying to get it to compile.
        &lt;/p&gt;
        &lt;p&gt;I'm sure someone will correct me on this, but I cannot see a good reason to have "Rebuild as needed" set. I suspect this is a hangover from before the Delphi IDE
            allowed you to specify &lt;a href="https://docwiki.embarcadero.com/RADStudio/Sydney/en/Project_Dependencies" target="_blank"&gt;Project Dependencies&lt;/a&gt; and it slows down builds.
        &lt;/p&gt;

        &lt;h3&gt;Use Search Paths for includes&lt;/h3&gt;

        &lt;p&gt;I often see includes with either hard coded paths, or relative paths like this :&lt;/p&gt;
        &lt;pre class="brush:delphi; toolbar:false;"&gt;
{$I '..\..\MyDefines.inc'}
        &lt;/pre&gt;
        &lt;p&gt;That's great, if the installer delivers the files in the right place - but they often don't - I hit this issue today, where the package just would not compile. I eventually
            figured out that the relative path was wrong.
        &lt;/p&gt;

        &lt;p&gt;There's a simple fix for this, and that is to remove the path in the $I statement, and use the Project Search Paths feature instead. &lt;/p&gt;

        &lt;img src="https://cdn.finalbuilder.com/blog/vincent/advice-for-d/searchpath.png" alt="Search Paths"&gt;
        &lt;p&gt;&lt;/p&gt;
        &lt;p&gt;I have also seen libraries where there are mulitple copies of the include file and they are slightly different!&lt;/p&gt;

        &lt;h3&gt;Mark packages as Runtime only or Designtime only&lt;/h3&gt;
        &lt;p&gt;Some libraries have their packages marked as "Runtime and Designtime" (the default) - the impact of this is only minor, but it's a pet peeve of mine. The Delphi IDE (in recent versions at
            least) provides a nice indication of whether packages are runtime or designtime in the project tree, and for designtime packages, whether they are installed. &lt;/p&gt;
        &lt;p&gt;This makes it simple for me to determine which ones need to be installed or not.&lt;/p&gt;
        &lt;p&gt;Not Installed&lt;/p&gt;
        &lt;img src="https://cdn.finalbuilder.com/blog/vincent/advice-for-d/not-installed.png" alt="Not Installed"&gt;
        &lt;p&gt;Installed&lt;/p&gt;
        &lt;img src="https://cdn.finalbuilder.com/blog/vincent/advice-for-d/installed.png" alt="Installed"&gt;
        &lt;p&gt;&lt;/p&gt;

        &lt;h3&gt;Summing up&lt;/h3&gt;

        &lt;p&gt;One of the major reasons people do not upgrade Delphi versions is because it's too hard to deal with the third party libraries and all the changes required just to
            get to the point of compiling. That eventually results in a lack of Delphi sales which results in a lack of investment in Delphi which feeds back into.... well you get the idea ;)&lt;/p&gt;

        &lt;p&gt;Making third party libraries easier to work with in Delphi has been a bit of a crusade for me, I've been &lt;a href="/resources/blogs/delphi-package-manager-rfc"&gt;working on this for a while
                now&lt;/a&gt;,
            and I'm getting closer to a solution - &lt;a href="https://github.com/DelphiPackageManager/DPM"&gt;DPM - A package manager for Delphi&lt;/a&gt; - if you are a library author, I encourage you
            to take a look. For examples on how to create a package spec (dspec) take a look at our open source projects &lt;a
               href="https://github.com/vsoftTechnologies/"&gt;https://github.com/vsoftTechnologies/&lt;/a&gt;
        &lt;/p&gt;
</description><guid isPermaLink="false">841</guid></item><item><title>Introducing DPM - a Package Manager for Delphi</title><link>https://www.finalbuilder.com/resources/blogs/postid/837/introducing-dpm-a-package-manager-for-delphi</link><category>Delphi,DPM,Open Source</category><pubDate>Thu, 12 Dec 2019 09:41:00 GMT</pubDate><description>&lt;p&gt;Back in Feb 2019, I &lt;a href="/resources/blogs/delphi-package-manager-rfc" target="_blank"&gt;blogged&lt;/a&gt; about the need for a Package Manager for Delphi. The blog post garnered lots of mostly useful feedback and encouragement, but until recently I could never find a solid block of time to work on it. Over the last few weeks I've been working hard to get it to an mvp stage.&lt;/p&gt;

&lt;p&gt;DPM is an &lt;b&gt;open source&lt;/b&gt; package/library manager for Delphi XE2 or later. It is heavily influenced by Nuget, so the cli, docs etc will seem very familiar to nuget users. Delphi’s development environment is quite different from .net, and has different challenges to overcome, so whilst I drew heavily on nuget, DPM is not identical to nuget. I also took a close look at many other package managers for other development eco systems.&lt;/p&gt;

&lt;h2&gt;What is a Package Manager&lt;/h2&gt;

&lt;p&gt;A package manager provides a standard for developers to share and consume code. Authors create packages that other developers can consume. The package manager provides a simple way to automate the installation, upgrading or removal of packages. This streamlines the development process, allowing developers to get up and running on a project quickly, without needing to understand the (usually adhoc) way the project or organization has structured their third party libraries. This also translates into simpler build/CI processes, with less ‘compiles on my machine’ style issues.&lt;/p&gt;

&lt;h2&gt;Who and Why&lt;/h2&gt;

&lt;p&gt;DPM’s initial developer is Vincent Parrett (author of DUnitX, FinalBuilder, Continua CI etc). Why is discussed in &lt;a href="https://www.finalbuilder.com/resources/blogs/delphi-package-manager-rfc"&gt;this blog post&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;DPM Status&lt;/h2&gt;

&lt;p&gt;DPM is still in development, so not all functionality is ready yet. At this time, it's at the stage where we I would encourage library authors to take a look and play with it and provide feedback (and perhaps get involved in the development). It's very much at a minimum viable product stage. Potential users are of course welcome to look at it and provide feedback, it's just that, well, there are no packages for it yet (there's some test packages in the repo, and I'll be creating ones for my open source libraries). .&lt;/p&gt;

&lt;h3&gt;What works&lt;/h3&gt;

&lt;ul&gt;
	&lt;li&gt;Creating packages&lt;/li&gt;
	&lt;li&gt;Pushing packages to a package source.&lt;/li&gt;
	&lt;li&gt;Installing packages, including dependencies&lt;/li&gt;
	&lt;li&gt;Restoring packages, including dependencies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;How do I use it&lt;/h3&gt;

&lt;p&gt;The documentation is at &lt;a href="https://docs.delphi.dev"&gt;https://docs.delphi.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See the &lt;a href="https://docs.delphi.dev/getting-started/installing.html"&gt;getting started guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The command line documentation can be found &lt;a href="https://docs.delphi.dev/commands/commands.html"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Source is on GitHub &lt;a href="https://github.com/DelphiPackageManager/DPM"&gt;https://github.com/DelphiPackageManager/DPM&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Is DPM integrated into the Delphi IDE&lt;/h3&gt;

&lt;p&gt;Not yet but it is planned. If you are a wiz with the open tools api and want to contribute then let us know.&lt;/p&gt;

&lt;h3&gt;Is there a central package source&lt;/h3&gt;

&lt;p&gt;Not yet but it is planned. At the moment, only local folder based &lt;a href="https://docs.delphi.dev/concepts/package-sources.html"&gt;sources&lt;/a&gt; are supported. The client code architecture has a provision for http based sources in the future, however right now we are focused on nailing down the package format, dependency resolution, installation, updating packages etc.&lt;/p&gt;

&lt;h3&gt;Is my old version of delphi supported&lt;/h3&gt;

&lt;p&gt;Maybe, &lt;a href="https://docs.delphi.dev/compiler-versions.html"&gt;see here&lt;/a&gt; for supported compiler versions. All target &lt;a href="https://docs.delphi.dev/platforms.html"&gt;platforms&lt;/a&gt; for supported compiler versions are supported.&lt;/p&gt;

&lt;h3&gt;What about C++ Builder or FPC&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.delphi.dev/compiler-versions.html"&gt;see here&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Does it support design time components&lt;/h3&gt;

&lt;p&gt;Not yet, but that is being worked on.&lt;/p&gt;

&lt;h3&gt;How does it work&lt;/h3&gt;

&lt;p&gt;See &lt;a href="https://docs.delphi.dev/concepts/how-it-works.html"&gt;this page&lt;/a&gt;&lt;/p&gt;
</description><guid isPermaLink="false">837</guid></item><item><title>Managing Delphi Version Info with FinalBuilder</title><link>https://www.finalbuilder.com/resources/blogs/postid/836/managing-delphi-version-info-with-finalbuilder</link><category>Delphi,FinalBuilder,Windows</category><pubDate>Wed, 26 Jun 2019 15:49:26 GMT</pubDate><description>&lt;p&gt;In this post, we'll take a look at the various options for managing and updating Version Info in Delphi projects using FinalBuilder.&lt;/p&gt;

&lt;h2&gt;Windows Version Info Primer&lt;/h2&gt;

&lt;p&gt;Windows Version Info (ie the version info shown in explorer) is stored in a &lt;a href="https://docs.microsoft.com/en-us/windows/desktop/menurc/versioninfo-resource" target="_blank"&gt;VERSIONINFO&lt;/a&gt; resource inside the executable (exe or dll). These resources are created by defining a .rc file, and compiling with either the windows resource compiler (rc.exe) or Delphi's provided resource compiler (brcc32 or cgrc depending on the delphi version). This results in a .res file, which can be linked into exe at compile time by referencing it in the source code, e.g :&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
{$R 'myresource.res'}&lt;/pre&gt;

&lt;p&gt;I highly recommend familiarising yourself with the VERSIONINFO resource type and it's parts.&lt;/p&gt;

&lt;h2&gt;Delphi IDE Support for Version Info&lt;/h2&gt;

&lt;p&gt;The Delphi IDE creates a [YourProjectName].res file next to the dpr or dpk when you create a new project. This is where the IDE will place the VERSIONINFO resource when you enable the option to "Include version information in project".  When you compile the project in the IDE, if needed the IDE will regenerate this res file with updated version info before it is linked into the executable.  For exe's, this resource file also includes the MAINICON resource (the icon shown in explorer).&lt;/p&gt;

&lt;p&gt;You do not have to use this feature, you can leave the option turned off and manage the version info yourself, by creating your own resource script (.rc) with a VERSIONINFO structure,  and compiling it and referencing the resulting .res file in your source code. You can even just reference the .rc file&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
{$R 'myresource.res' 'myresource.rc'}&lt;/pre&gt;

&lt;p&gt;and the IDE will compile the rc file and link in the resulting res file. The caveat to this technique is that the command line compiler (dcc32, dcc64 etc) does not support this. &lt;/p&gt;

&lt;p&gt;If your binary doesn't have version info, or has incorrect version info, it's typically because :&lt;/p&gt;

&lt;p&gt;1) The version info  resource wasn't referenced in the source and wasn't linked in&lt;br /&gt;
2) There are duplicate VERSIONINFO resources linked, windows will pick the first one it finds.&lt;br /&gt;
3) You set the version info on the wrong IDE configuration (more on this below). &lt;/p&gt;

&lt;p&gt;The Delphi IDE, along with the dproj file (which is an msbuild project file), uses a convoluted configuration inheritance mechanism to set project properties, including version info. Many a developer has been caught out by this scheme, setting the version info at the wrong node in the heirachy, resulting in no version info in their executables. There have also been issues with dproj files that have been upgraded through multiple versions of delphi over the years.&lt;/p&gt;

&lt;h2&gt;Using FinalBuilder&lt;/h2&gt;

&lt;p&gt;In the development environment, the version info usually doesn't matter too much, but for formal releases it's critical, so it's best to leave setting/updating your version info  to your &lt;a href="/finalbuilder" target="_blank"&gt;automated build tool&lt;/a&gt; or your &lt;a href="/continua-ci" target="_blank"&gt;continuous integration server&lt;/a&gt;. In FinalBuilder we have invested a lot of time and energy to making version info work correctly with all the different versions of delphi, dealing with the vagaries and subtle differences with each version (and there are many!).&lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;img src="https://cdn.finalbuilder.com/blog/vincent/fbversioninfo/delphi-versioninfo-tab.png" /&gt;&lt;/p&gt;

&lt;p&gt;On the Delphi action in FinalBuilder, the Version Info tab presents the version info in a similar way to old versions of delphi IDE did (a much nice ui that the current version imho). This ui allows you control all the various version info properties (and there are a lot!). Note that these will only take effect if you have the "Regenerate resource" option checked on the Project tab (ie, regenerate yourproject.res). &lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;img src="https://cdn.finalbuilder.com/blog/vincent/fbversioninfo/delphi-project-tab.png" /&gt;&lt;/p&gt;

&lt;p&gt;Note that the Major, Minor, Release and Build fields are number spin edits, and cannot take FinalBuilder variables. That can easily be worked around with some simple scripting, in the BeforeAction script event  (javascript):&lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;img src="https://cdn.finalbuilder.com/blog/vincent/fbversioninfo/delphi-action-script.png" /&gt;&lt;/p&gt;

&lt;p&gt;Another option is to use &lt;a href="https://wiki.finalbuilder.com/display/FB8/Property+Sets" target="_blank"&gt;Property Sets&lt;/a&gt; to provide the source of the Version Info. Property sets are especially useful when you have multiple actions that need the same version info, or at least to share the same version numbers. Creating a Property Set is trivial, just drop a PropertySet Define action on your target, before the Delphi Action. In the PropertySet Define action, select Win32 Version Info to manage all version info properties, or Win32 Version Numbers to have the property set just manage the major, minor, release and build numbers.&lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;img src="https://cdn.finalbuilder.com/blog/vincent/fbversioninfo/define-propertyset.png" /&gt;&lt;/p&gt;

&lt;p&gt;To set the property set values, add a PropertySet Assign Values action before the Delphi action.&lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;img src="https://cdn.finalbuilder.com/blog/vincent/fbversioninfo/propset-assign.png" /&gt;&lt;/p&gt;

&lt;p&gt;Then in the Delphi action it's a simple task to select the property set in the version info tab&lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;img src="https://cdn.finalbuilder.com/blog/vincent/fbversioninfo/delphi-use-propset.png" /&gt;&lt;/p&gt;

&lt;p&gt;Notice that the version number fields are disabled, since they are now provided by the property set. If you choose the Win32 Version Info property set type, more fields are disabled.&lt;/p&gt;

&lt;p&gt;One last thing I should mention, is that along with the Version Info and the MAINICON, the project.res file also typically (well for windows at least) contains the manifest file. I recommend you look at the Resource Compiler tab, where it lets you choose which resource compiler to use (more useful in older versions of delphi, where brcc32 didn't cope with some hicolor icon types) and specify the manifest file. I discussed &lt;a href="/resources/blogs/windows-manifest-files" target="_blank"&gt;windows manifest files a few years ago in this blog post&lt;/a&gt;.&lt;/p&gt;
</description><guid isPermaLink="false">836</guid></item><item><title>Delphi 10.3 Rio - Language Changes</title><link>https://www.finalbuilder.com/resources/blogs/postid/832/delphi-103-rio-language-changes</link><category>Delphi,FinalBuilder</category><pubDate>Thu, 13 Dec 2018 11:12:39 GMT</pubDate><description>&lt;p&gt;Back in December 2016, I posted some ideas for some &lt;a href="/resources/blogs/delphi-language-enhancements"&gt;Delphi language enhancements&lt;/a&gt;. That post turned out to be somewhat controversial, I received some rather hostile emails about how I was trying to turn Delphi into C#. That certainly wasn't my intent, but rather to modernize Delphi, in a way that helps me write less, but more maintainable code. Nearly 2 years later, Delphi 10.3 Rio actually implements some of those features.&lt;/p&gt;

&lt;p&gt;I'm not going to claim credit for the new language features, and the syntax suggestions I made were pretty obvious ones, but I like to think I perhaps spurred them on a bit ;) My blog post had over 12K views, so there was certainly plenty of interest in new language features, and from what I have seen out there on the interwebs they have for the most part been well received.&lt;/p&gt;

&lt;p&gt;So lets take a look at which suggestions made the cut for 10.3 - referencing my original post.&lt;/p&gt;
&lt;style type="text/css"&gt;.featureTable {
        border: 1px solid #0071c5;
        border-collapse: collapse;
        width: 100%;
        margin-left: auto;
        margin-right: auto;
    }

    .featureTable thead {
        background-color: #0071c5;
        color: White;
    }

    .featureTable td {
        border: 1px solid #0071c5;
        padding: 5px;
    }
&lt;/style&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="featureTable"&gt;
	&lt;thead&gt;
		&lt;tr&gt;
			&lt;th&gt;Feature&lt;/th&gt;
			&lt;th&gt;Implemented&lt;/th&gt;
			&lt;th&gt;Comments&lt;/th&gt;
		&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#localvarinit" target="_blank"&gt;Local Variable Initialisation&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;No&lt;/td&gt;
			&lt;td&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#typeinference" target="_blank"&gt;Type Inference&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;Yes!&lt;/td&gt;
			&lt;td&gt;For inline variables only, Confuses code insight!&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#inlinevars" target="_blank"&gt;Inline variable declaration, with type inference and block scope&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;Yes, Yes and Yes!&lt;/td&gt;
			&lt;td&gt;Confuses code insight!&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#loopvars" target="_blank"&gt;Loop variable inline declaration&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;Yes!&lt;/td&gt;
			&lt;td&gt;Confuses code insight!&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#shortcutprops" target="_blank"&gt;Shortcut property declaration&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;No&lt;/td&gt;
			&lt;td&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#interfacehelpers" target="_blank"&gt;Interface Helpers&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;No&lt;/td&gt;
			&lt;td&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#nonordinalcase" target="_blank"&gt;Strings (and other non ordinals) in Case Statements&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;No&lt;/td&gt;
			&lt;td&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#ternaryoperator" target="_blank"&gt;Ternary Operator&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;No&lt;/td&gt;
			&lt;td&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#tryexceptfinally" target="_blank"&gt;Try/Except/Finally&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;No&lt;/td&gt;
			&lt;td&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#namedargs" target="_blank"&gt;Named Arguments&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;No &lt;/td&gt;
			&lt;td&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#varargs" target="_blank"&gt;Variable method arguments&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;No&lt;/td&gt;
			&lt;td&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#lambdas" target="_blank"&gt;Lambdas&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;No&lt;/td&gt;
			&lt;td&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#linq" target="_blank"&gt;Linq&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;No&lt;/td&gt;
			&lt;td&gt;Depends on lambdas and interface helpers.&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#asyncawait" target="_blank"&gt;Async/Await&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;No&lt;/td&gt;
			&lt;td&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#nonrefinterfaces" target="_blank"&gt;Non reference counted interfaces&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;No&lt;/td&gt;
			&lt;td&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#attributeconstraints" target="_blank"&gt;Attribute Constraints&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;No&lt;/td&gt;
			&lt;td&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#operatoroverloading" target="_blank"&gt;Operator overloading on classes.&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;No&lt;/td&gt;
			&lt;td&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#genericonstraints" target="_blank"&gt;Improve Generic Constraint&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;No&lt;/td&gt;
			&lt;td&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#fixienumerable" target="_blank"&gt;Fix IEnumerable &lt;t&gt;&lt;/t&gt; &lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;No&lt;/td&gt;
			&lt;td&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#yield" target="_blank"&gt;Yield return - Iterator blocks&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;No&lt;/td&gt;
			&lt;td&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#partialclasses" target="_blank"&gt;Partial classes&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;No&lt;/td&gt;
			&lt;td&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#multipleuses" target="_blank"&gt;Allow Multiple Uses clauses&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;No&lt;/td&gt;
			&lt;td&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;a href="/resources/blogs/delphi-language-enhancements#interfacegenerics" target="_blank"&gt;Allow non parameterized interfaces to have parameterized methods&lt;/a&gt;&lt;/td&gt;
			&lt;td&gt;No&lt;/td&gt;
			&lt;td&gt; &lt;/td&gt;
		&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;So, 3 out of 23. To be honest, I was pleasantly surprised when I found out about them, given the pace of language change in the past. I'm hopeful this is just the start of things to come and we get to see Delphi evolve and catch up with other modern programming languages. I have a bunch of other language features I'd like to see, and received lots of suggestions from other users. &lt;/p&gt;

&lt;p&gt;We're still using Delphi XE7 for FinalBuilder 8, and I rarely change compiler versions during the life of a major product version. So I'll only get to use the new language features when I get fully stuck into FinalBuilder 9 &amp; Automise 6. I'm in the process of getting Delphi 10.3 compatible versions of all the third party libraries (commercial and open source) - as and long time delphi user will know, that's always more difficult than it should be!  &lt;/p&gt;
</description><guid isPermaLink="false">832</guid></item><item><title>Delphi Package Manager RFC</title><link>https://www.finalbuilder.com/resources/blogs/postid/777/delphi-package-manager-rfc</link><category>Delphi,DPM,Open Source</category><pubDate>Mon, 16 Jul 2018 01:58:00 GMT</pubDate><description>&lt;p&gt;Delphi/Rad Studio desperately needs a proper package/library/component manager. A package manager provides a standardized way of consuming third party libraries. At the moment, use of third party libraries is very much adhoc, and in many cases this makes it difficult to move projects between machines, or to get a new hire up and running quickly.&lt;/p&gt;

&lt;p&gt;Other developement environments, like the .net and javascript eco systems, recognised and solved this problem many years ago. Getting a .net or javascript project up an running, in a new working folder or new machine is trivial.&lt;/p&gt;

&lt;p&gt;With Delphi/Rad Studio, it's much harder than it should be. In consulting work, I've made it a point to see how clients were handling third party code, and every client had a different way. The most common technique was... well, best described as adhoc (with perhaps a readme with the list of third party products to install). Getting that code compiling on a CI server was a nightmare.&lt;/p&gt;

&lt;h2&gt;Existing Package Managers&lt;/h2&gt;

&lt;p&gt;Embarcadero introduced their GetIt package manager with XE8, and the GetIt infrastructure has certainly has made the installation of RAD Studio itself a lot nicer. But as a package manager for third party libraries, it comes up short in a number of areas.&lt;/p&gt;

&lt;p&gt;There is also Delphinus, which is an admirable effort, but hasn't gotten much traction, possibly due to it being strongly tied to github (you really need github account to use it, otherwise you get api rate limiting errors).&lt;/p&gt;

&lt;p&gt;Rather than pick apart GetIt or Delphinus, I'd like to outline my ideas for a Delphi package manager. I spend a lot of time working with .net (nuget) and javascript (npm, yarn), so they have very much influenced what I will layout below.&lt;/p&gt;

&lt;p&gt;I have resurrected an old project (from 2013) that I shelved when GetIt was announced, and I have spent a good deal of time thinking about package management (not just in Delphi), but I'm sure I haven't thought of everything, I'd love to hear feedback from people interested in contributing to this project, or just potential users.&lt;/p&gt;

&lt;h2&gt;Project Ideals&lt;/h2&gt;

&lt;p&gt;These are just some notes that I wrote up when I first started working on this back in 2013, I've tried to whip them into some semblance of order for presentation here, but they are just just rough outline of my ideas.&lt;/p&gt;

&lt;h3&gt;Open Source&lt;/h3&gt;

&lt;p&gt;The Project should be Open Source. Of course we should welcome contributions from commercial entities, but the direction of the project will be controlled by the community (ie users). The project will be hosted on GitHub, and contributions will be made through Pull Requests, with contributions being reviewed by the Steering committee (TBA).&lt;/p&gt;

&lt;h3&gt;Public Package Registry&lt;/h3&gt;

&lt;p&gt;There will be a public website/package server, where users can browse the available packages, and package authors can upload packages. This will be a second phase of the project, with the initial phase being focused on getting a working client/package architecture, with a local or network share folder for the package source.&lt;/p&gt;

&lt;p&gt;The package registry should not be turned into a store. Once a public package registry/server is available, evaluation packages could be be allowed, perhaps by providing a fee (web hosting is not free). Commercial vendors will of course be able to distribute commercial packages directly to their customers, as the package manager will support hosting of packages in a shared network or local directory. Package meta data will include flags to indicate if the packages are commercial, eval or free/open source. Users will be able to decide which package types show up in their searches.&lt;/p&gt;

&lt;h3&gt;Package Submission&lt;/h3&gt;

&lt;p&gt;Package submission to the public registry should be a simple process, without filling in and signing and faxing of forms! We will follow the lead of nuget, npm, ruby etc on this. There should be a dispute process for package names, copyright infringement etc. There will also be the ability to assign ownership of a package, for example when project ownership changes.&lt;/p&gt;

&lt;p&gt;Package Authors will be able to reserve a package prefix, in order to prevent other authors from infringing on their names or copyrights. For example, Embarcadero might reserve Emb. as their prefix, TMS might reserve TMS. as theirs. (of course I'm hoping to get both on board). The project will provide a dispute resolution process for package prefixes and names.&lt;/p&gt;

&lt;h2&gt;Delphi specific challenges&lt;/h2&gt;

&lt;p&gt;Delphi presents a number of challenges when compared to the .net or nodejs/javascript world.&lt;/p&gt;

&lt;h3&gt;Compatibility&lt;/h3&gt;

&lt;p&gt;With npm, packages contain source (typically minimized and obfuscated) which is pure javascript. Compatibility is very high.&lt;/p&gt;

&lt;p&gt;With Nuget, packages contain compiled (to .NET IL) assemblies. A package might contain a few different versions, that target different the versions of the .net framework. Again, compatibility is pretty good, an assembly compiled against .net 2.0 will work on .net 4.7 (.net core breaks this, but it has a new compatibility model, netstandard).&lt;/p&gt;

&lt;p&gt;If we look at Delphi, binary compatibility between Delphi compiler versions is pretty much non existent(yes, I know about 2006/7 etc). The dcu, dcp and bpl files are typically only compatible with the version they were compiled with. They are also only compatible with the platform they were generated for (so you can't share dcu's between 32 and 64 bit windows, or between iOS and Android). So we would need to include binaries for each version of Delphi we want our library to support. This also has major implications for library dependencies. Where as npm and nuget define dependencies as a range of versions, a binary dependency in Delphi would be fixed to that specific version. There is a way to maintain binary compatibility between releases, provided the interfaces do not change, however exactly what the rules are for this is hard to come by, so for now we'll ignore that possibility.&lt;/p&gt;

&lt;p&gt;That limits the scope for updating to newer versions of libraries, but that can also be overcome by including the source code in package, and providing on the fly compilation of the library during install. My preference would be for pre-compiled libraries, as that speeds up the build process (of course, since that's an area I have a particular interest in). In Continuous Integration environments, you want to build fast and build often, rebuilding library code with each CI build would be painful (speaking from experience here, 50% of time building FinalBuilder is building the third party libraries).&lt;/p&gt;

&lt;p&gt;There's also the consideration of Debug vs Release - so if we are including binaries, compiled for Release would be required, but Debug optional? The size of a package file could be problematic. If the package contains pre-compiled binaries for multiple compiler versions, it could get rather large. So perhaps allow for packages that either support a single compiler version, or multiples? The compilers supported would be exposed in the package metadata, and perhaps also in the package file name. Feedback, ideas around this would be welcome.&lt;/p&gt;

&lt;p&gt;Package files would be (like with other package managers), a simple zip file, which include a metadata (xml) file which describes the contents of the package, and folders containing binaries, source, resources etc. Packages will not contain any scripts (ie to build during install) for security reasons (I don't want to be running random scripts). We will need to provide a way to compile during install (using a simple dsl to describe what needs to be done), this still needs a lot of thought (and very much involves dependencies).&lt;/p&gt;

&lt;h3&gt;Library/Search Paths&lt;/h3&gt;

&lt;p&gt;Say goodbye to the IDE's Library path. It was great back in 1995, when we had a few third party libraries and a few projects and we just upgraded the projects to deal with library versioning (just get on the latest). It's simply incompatible with the notion of using multiple versions of the same libraries these days.&lt;/p&gt;

&lt;p&gt;I rarely change major versions of a library during the lifespan of a major release of my products, I might however take minor updates for bugfixes or performance improvements. The way to deal with this is simply to use the Project Search path. Project A can use version 1 of a library, Project 2 can use version 9, all quite safely (design time components do complicate this).&lt;/p&gt;

&lt;p&gt;Where a project targets multiple platforms, installing a package should install for all platforms it supports, but it should be possible for the user to specify which platforms they need the package installed for.&lt;/p&gt;

&lt;h3&gt;Design time Component Installation&lt;/h3&gt;

&lt;p&gt;The Rad Studio IDE only allows one version of a design time package to be installed at a time. So when switching projects, which might use different versions of a component library, we would need a system that is aware of component versions, and can uninstall/install components on the fly, as projects are loaded.&lt;/p&gt;

&lt;p&gt;I suspect this will be one of the biggest project hurdles to overcome, it will requires someone with very good open tools api knowledge (ie, not me!).&lt;/p&gt;

&lt;h3&gt;Dependencies&lt;/h3&gt;

&lt;p&gt;Libraries that depend on other libraries will need to specify those dependencies in a metadata file, such that they can resolved during installation. As I mentioned above, binary compatibility issues make dependency resolution somewhat more complicated, but not insurmountable. The resolution algorithm will need to take into account compiler version and platform. The algorithm will also need to handle when a package is compiled from source, for example, binary only packages should not be allowed to depend on source only packages (to ensure compatibility). If we end up with install time package compilation, then some serious work will be needed on the dependency tree algorithm to work our what else needs to be done during install (ie, do any dependencies need to be recompiled?).&lt;/p&gt;

&lt;p&gt;This is certainly more complicated than other platforms, and a significant amount of work to get right (ps, if you think it isn't, you haven't considered all the angles!)&lt;/p&gt;

&lt;h2&gt;General Considerations&lt;/h2&gt;

&lt;h3&gt;Package Install/Restore&lt;/h3&gt;

&lt;p&gt;The user should be able to choose from a list packages to install. When installing the package, this would be recorded either in the dproj, or a separate file alongside the drproj. The install process will update the project search paths accordingly. Package meta data would control what gets added to the search paths, my preference would be for 1 folder per package, as that would keep the search path shorter which improves compile times.&lt;/p&gt;

&lt;p&gt;When a project is loaded, the dproj (or packages config file) would be checked, and any missing packages restored automatically. This should also handle the situation where a project is loaded in a different IDE version.&lt;/p&gt;

&lt;h3&gt;Security&lt;/h3&gt;

&lt;p&gt;We should allow for signing of packages, such that the signatures can be verified by the client(s). Clients should be able to chose whether to only allow signed packages, or allow signed and unsigned, and what to do when signature verification fails. This will allow users certainty in the authenticity and integrity of the package (ie where it comes from and whether it's been modified/tampered with).&lt;/p&gt;

&lt;h2&gt;Clients&lt;/h2&gt;

&lt;p&gt;It is envisaged that will be at least 2 clients, a command line tool, and a Rad Studio IDE plugin. Clients will download packages, add those packages to project/config search paths. A local package cache will help with performance, avoiding repetitive package downloads and also reduce disk space demands. The clients will also detect available updates to packages, and package dependency conflicts.&lt;/p&gt;

&lt;h3&gt;Command line Client&lt;/h3&gt;

&lt;p&gt;The command like tool will be similar to nuget or npm, which provide the ability to create packages, install or restore missing packages, update packages etc. The tool should allow the specification of compiler versions and platforms, as this is not possible to detect from the dproj alone. This is where the project is currently focused (along with the core package handling functionality).&lt;/p&gt;

&lt;h3&gt;RAD Studio IDE Client&lt;/h3&gt;

&lt;p&gt;An IDE plugin client will provide the ability to search for, install, restore, update or remove packages, in a similar manner to the Nuget Visual Studio IDE support (hopefully faster!). This plugin will share the core code with the the command line client (ie, it will not call out to the command line tool). I have not done any work on this yet (help wanted).&lt;/p&gt;

&lt;h2&gt;Delphi/Rad Studio Version Support&lt;/h2&gt;

&lt;p&gt;Undecided at the moment. I'm developing with XE7, but it's possible the code will compile with earlier versions, or be made to compile with minor changes.&lt;/p&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;Simply put, I want/need a package manager for Delphi, one that works as well as nuget, npm, yarn etc. I'm still fleshing out how this might all work, and I'd love some feedback, suggestions, ideas etc. I'd like to get some people with the right skills 'signed up' to help, particularly people with open tools api expertise.&lt;/p&gt;

&lt;h2&gt;Get Involved!&lt;/h2&gt;

&lt;p&gt;I have set up a home for the project on GitHub - &lt;a href="https://github.com/DelphiPackageManager/PackageManagerRFC"&gt;The Delphi Package Manager Project - RFC&lt;/a&gt;. We'll use issues for discussion, and the wiki to document the specifications as we develop them. I have created a few issues with things that need some dicusssion. I hope to publish the work I have already done on this in the next few days (needs tidying up).&lt;/p&gt;
</description><guid isPermaLink="false">777</guid></item><item><title>Windows 10 Fall Creators Update</title><link>https://www.finalbuilder.com/resources/blogs/postid/756/windows-10-fall-creators-update</link><category>Automise,Delphi,FinalBuilder,Windows</category><pubDate>Tue, 17 Oct 2017 09:55:38 GMT</pubDate><description>The &lt;a href="https://blogs.windows.com/windowsexperience/2017/10/17/get-windows-10-fall-creators-update" title="How do I get the Fall Update?"&gt;Windows 10 Fall Creators Update has only been out a few hours&lt;/a&gt;, but we're already getting questions about it.&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
In our limited testing, FinalBuilder 8 and Automise 5 run fine.&lt;br /&gt;
&lt;br /&gt;
I've only been running the Fall Update for a few hours, but so far I have not noticed any issues. The applications I use daily all run fine.&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
The "Windows 10 Creators Update" (ie the one before the Fall Update - stupid release naming imho) &lt;a href="https://quality.embarcadero.com/browse/RSP-17972" title="Embarcadero issue tracker. Requires registration/login to view."&gt;broke the Delphi debugger&lt;/a&gt; when using runtime packages. Aparently the issue was caused by a library loader optiimisation, not taking into account that dll's can have multiple import tables. I never did see a full explaination or acknowledgement of the problem from Microsoft. &lt;br /&gt;
&lt;br /&gt;
This only affected the debugger (all native code debuggers, not just Delphi), which would load and unload each dll many times (based on the number of imports, for FinalBuilder's core package, it was in the hundreds). Sometimes the application would launch, only for the debugger to crash, sometimes it would just hang, sometimes the Delphi IDE would get out of memory errors.&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
For me, this was a big issue, since FinalBuilder and Automise use runtime packages. This affected all versions of Delphi, even the latest 10.2 (Tokyo). Embarcadero did eventually ship an update to 10.2 that mostly resolved the problem (not an easy thing as it involved major linker changes), but that didn't help us as we're using an older version (for reasons I won't go into here!). &lt;br /&gt;
&lt;br /&gt;
So since April 2017, I've been really hamstrung when it comes to debugging. Fortunately we discovered the issue before the Creators Update was installed on our other Delphi development machines (and it's a been a constant battle with windows update nagging to install it ever since) so we were still able debug, just not on my dev machine. Frustrating to say the least.&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
The good news is that the Fall Update (mostly) fixes the problem.&amp;nbsp; I still see some dlls/packages getting unloaded and reloaded again, but the application launches and I can debug.&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
As far as windows functionality in the Fall Update goes, well the Task Manager has a new GPU section on the performance tab which is mildly interesting, but since I don't use a Pen, or wear a VR headset while working, I'm not noticing much to get excited about. Hopefully, it's just a lot of bug fixes and performance enhancements, minus the show stoppers!!&amp;nbsp;</description><guid isPermaLink="false">756</guid></item><item><title>Windows Manifest Files</title><link>https://www.finalbuilder.com/resources/blogs/postid/753/windows-manifest-files</link><category>Delphi,FinalBuilder,XML</category><pubDate>Mon, 28 Aug 2017 12:35:00 GMT</pubDate><description>&lt;p&gt;In this post I'm going to look at Windows Manifest Files, what they do, why we need them and how to use them in Delphi and FinalBuilder.&lt;/p&gt;

&lt;p&gt;We often get asked questions about UAC prompts, High DPI settings, Windows Themes etc when compiling Delphi &amp; C++Builder projects in FinalBuilder. In this post we'll dissect windows manifest files, and look at how the project settings in Rad Studio interact with the manifest file, and why you should use a custom manifest file.&lt;/p&gt;

&lt;h3&gt;What is a manifest file and what's it for?&lt;/h3&gt;

&lt;p&gt;A manifest is an xml file, which is typically embedded as a resource (it can be a separate file, but it's not a good practice and is not recommended) in your native windows executable (x86 or x64). This file has information that tells windows (vista or later) what parts of windows it supports, what permissions it needs (UAC), what common control dependencies it has (&lt;a href="https://en.wikipedia.org/wiki/Side-by-side_assembly" target="_blank"&gt;Windows Side-by-Side loading&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Without a manifest resource, windows has no idea what permissions your application needs, and will not treat your application kindly. You will find things like common controls (file dialogs etc) look strange, attempts to write to files failing and other general misery. In fact your application may fail to run at all on some systems.&lt;/p&gt;

&lt;p&gt;Ok, so now we know we really need a manifest, what does that look like.&lt;/p&gt;

&lt;pre class="brush:xml; toolbar:false;"&gt;
&lt;assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"&gt;
    &lt;assemblyIdentity 
        name="VSoftTechnologies.FinalBuilder" 
        processorArchitecture="x86" 
        version="8.0.0.0" 
        type="win32"
    /&gt;
    &lt;description&gt;FinalBuilder is a GUI-based build automation tool for Windows developers.&lt;/description&gt;
    &lt;dependency&gt;
        &lt;dependentAssembly&gt;
            &lt;assemblyIdentity 
                type="win32"    
                name="Microsoft.Windows.Common-Controls" 
                version="6.0.0.0"
                processorArchitecture="x86" 
                publicKeyToken="6595b64144ccf1df" 
                language="*" 
            /&gt;
        &lt;/dependentAssembly&gt;
    &lt;/dependency&gt;
    &lt;trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"&gt;
        &lt;security&gt;
            &lt;requestedPrivileges&gt;
                &lt;requestedExecutionLevel level="asInvoker" uiAccess="false" /&gt;
            &lt;/requestedPrivileges&gt;
         &lt;/security&gt;
    &lt;/trustInfo&gt;
    &lt;compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"&gt;
        &lt;application&gt;
            
            &lt;supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/&gt; 
            
            &lt;supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/&gt;
            
            &lt;supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/&gt;
            
            &lt;supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/&gt;
            
            &lt;supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/&gt;
        &lt;/application&gt;
    &lt;/compatibility&gt;
&lt;/assembly&gt;
&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;The above example is actually the manifest file used in the FinalBuilder IDE. Lets break it down.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h4&gt;AssemblyIdentity&lt;/h4&gt;

&lt;p&gt;The assemblyIdentity tells windows about your application and what the system architecture requirements are. This should be unique. Note that the type, name and version attributes are required. Typically, the version field just has the major version info, I guess you could update it with the exact version each time, but I've never found the need to do that.&lt;/p&gt;

&lt;h4&gt;Description&lt;/h4&gt;

&lt;p&gt;The description field is pretty self explanatory.&lt;/p&gt;

&lt;h4&gt;Dependency&lt;/h4&gt;

&lt;p&gt;The dependency section is where you describe the side by side dll dependencies, which for Delphi/C++ Builder applications means windows common controls. This is pretty standard stuff, but it's important because without it, your application will have pretty strange looking file dialogs, if it loads at all.&lt;/p&gt;

&lt;h4&gt;TrustInfo&lt;/h4&gt;

&lt;p&gt;The trustinfo section is all about security, it tells windows what sort of permissions your application should be given. The requestedExecutionLevel level attribute has 3 possible values :&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;asInvoker&lt;/strong&gt; - requesting no additional permissions. This level requires no additional trust prompts.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;highestAvailable&lt;/strong&gt; - requesting the highest permissions available to the parent process. When a standard user runs the application, it will behave the same as asInvoker, ie no UAC prompt. If an administrator runs the application, they will see a UAC prompt.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;requireAdministrator&lt;/strong&gt; - requesting full administrator permissions. All users will see a UAC prompt, standard users will be required to enter an administrator password.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;The uiAccess attribute Indicates whether the application requires access to protected user interface elements. Most of the time, this should be set to false. The typical use case for setting it to true is when creating remote desktop style application (like teamviewer etc). If you do set it to true, your application needs to be signed - see this post for code signing in FinalBuilder(&lt;a href="/resources/blogs/code-signing-changes-for-2016"&gt;https://www.finalbuilder.com/resources/blogs/code-signing-changes-for-2016&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h4&gt;High DPI support.&lt;/h4&gt;

&lt;p&gt;I'm not going go into to detail on this, it's a complex issue with major differences between windows versions, and limited High DPI support in Delphi. I will say, think very carefully before you enable this, High DPI support in Delphi depends very much on the version of delphi, and third party control support. Don't just enable High DPI support without serious testing. See the msdn doco link at the bottom of this post.&lt;/p&gt;

&lt;h4&gt;Compatibility&lt;/h4&gt;

&lt;p&gt;The compatibility section tells windows what versions of windows your application supports. It enables windows functionality in your application. Manifests without a compatibility section default to Windows Vista level functionality.&lt;/p&gt;

&lt;p&gt;One of the areas where the compatibility section is very important is detecting the windows version. On Windows 8.1 and 10, in applications that do not specify compatibility with them, GetVersion and GetVersionEx will return 6.2.0.0 for the windows version, rather than 6.3.* for Windows 8.1 and 10.0.* for Windows 10. So your application will think it's running on Windows 8 (or Server 2012) and quite possibly disable functionality.&lt;/p&gt;

&lt;h4&gt;Don't use Rad Studio's default or auto generated manifest!&lt;/h4&gt;

&lt;p&gt;I'll explain why in a minute, but first lets look at delphi's support for manifests. Delphi's manifest support differs quite a lot depending on which version of Delphi you are using. I don't have every version installed to check on.&lt;/p&gt;

&lt;p&gt;The earliest version I have installed at the moment is D2010, which just has a cryptically named check box :&lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;img alt="" src="https://cdn.finalbuilder.com/blog/vincent/windows-manifest/d2010-enable-themes.png" /&gt;&lt;/p&gt;

&lt;p&gt;This option will include a default manifest in the projectname.res file. No options to change anything about that manifest. The manifest included is woefully inadequate.&lt;/p&gt;

&lt;h5&gt;Fast forward to XE7 :&lt;/h5&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;img alt="" src="https://cdn.finalbuilder.com/blog/vincent/windows-manifest/xe7-enable-themes.png" /&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Things got slightly better (not sure in which XE? version though) as you can now point Rad Studio at a custom manifest file (and you should!) to be included with your application. The default manifest included is still woefully inadequate.&lt;/p&gt;

&lt;h5&gt;Fast forward again, to Seattle:&lt;/h5&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;img alt="" src="https://cdn.finalbuilder.com/blog/vincent/windows-manifest/seattle-manifest-file.png" /&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Things look different again here, now you can set the badly named "Enable High DPI" and "Enable Administrator Privileges" options. I say badly named, because that's not what those options do. Checking "Enable High DPI" won't make your application support High DPI, it just tells windows it does (when really, it doesn't unless embarcadero fixed it while I wasn't looking). The same applies to the "Enable Administrator Privileges" - it won't give your application Administrator Privileges, it just tells windows your application needs them to run. Semantics shemantics... but I know this has confused many a developer.&lt;/p&gt;

&lt;p&gt;Note that the auto generated manifest uses a template, default_app.manifest, which lives in the bin folder, which is typically under program files, so you might need admin access to modify. It's probably a bad idea to modify it anyway, as it will result in a "works on my machine" moment. This template is different in Seattle and later, as it has some "variables" that get substituted by the IDE when building, this file can't be used when building with FinalBuilder as we have no way to get at those variables.&lt;/p&gt;

&lt;p&gt;The manifest included is slightly better than before, but still inadequate.&lt;/p&gt;

&lt;p&gt;Berlin &amp; Tokyo manifest options are the same as Seattle, just some layout/styling changes. The auto generated manifests have the same limitations as Seattle.&lt;/p&gt;

&lt;p&gt;So I said earlier, "Don't use Rad Studio's default or auto generated manifest", and said that the auto generated manifests are inadequate, here's why : they are simply missing information.&lt;/p&gt;

&lt;p&gt;There's no assemblyIdentity element, which according to microsoft is required. There's no description element. The High DPI option just sets the dpiAware element to "True/PM", or not at all. You should use a manifest file that is specific to and reflects your application.&lt;/p&gt;

&lt;p&gt;For the versions of Rad Studio that support specifying a custom manifest file, just do that. For versions without custom manifest support, uncheck the "Enable runtime themes" option, and add a resource to your project that includes the manifest :&lt;/p&gt;

&lt;p&gt;Example manifest.rc&lt;/p&gt;

&lt;pre class="brush:delphi; gutter:false; toolbar:false; "&gt;
1 24 "E:\\Source\\app\\myapp.manifest"
&lt;/pre&gt;

&lt;h3&gt;Using Manifests in FinalBuilder&lt;/h3&gt;

&lt;p&gt;FinalBuilder has had support for manifest files for a long time (2007, in FB 5), way before Delphi mentioned the word manifest! On the resource compiler tab of the Delphi and C++Builder actions, there is a field to specify the manifest file.&lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;img alt="" src="https://cdn.finalbuilder.com/blog/vincent/windows-manifest/fb8-resource-tab.png" /&gt;&lt;/p&gt;

&lt;p&gt;That's all there is to it, FinalBuilder will add that manifest to the projectname.res file (along with the icon and version info).&lt;/p&gt;

&lt;p&gt;One last thing, don't forget to add your custom manifest file to your version control, it's source code after all.&lt;/p&gt;

&lt;h4&gt;References :&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://msdn.microsoft.com/en-us/library/aa374191%28v=vs.85%29.aspx?f=255&amp;MSPPError=-2147217396"&gt;MSDN - Application Manifests&lt;/a&gt;&lt;/p&gt;
</description><guid isPermaLink="false">753</guid></item><item><title>Delphi VersionInfo errors</title><link>https://www.finalbuilder.com/resources/blogs/postid/752/delphi-versioninfo-errors</link><category>Delphi,FinalBuilder</category><pubDate>Thu, 17 Aug 2017 11:44:15 GMT</pubDate><description>&lt;p&gt;Over the last year or so, we have seen more and more "bug reports" about compiling Delphi projects with FinalBuilder, in particular, reporting issues with compiling version info resources when using Delphi 10.1 (Berlin) and Delphi 10.2 (Tokyo). &lt;/p&gt;
&lt;p&gt;This only happens if you tell the Delphi action in FinalBuilder to load version info from the dproj.&lt;/p&gt;
&lt;p style="text-align: center;"&gt;
&lt;img src="/blogimages/vincent/versioninfo/action-settings.png" alt="delphi action settings" /&gt;
&lt;/p&gt;
&lt;p&gt;The error typically looks something like this :&lt;/p&gt;
&lt;p style="text-align: center;"&gt;
&lt;img src="/blogimages/vincent/versioninfo/fbreserror.png" alt="resource compiler error" /&gt;
&lt;/p&gt;
&lt;p&gt;or this :&lt;/p&gt;
&lt;p style="text-align: center;"&gt;
&lt;img src="/blogimages/vincent/versioninfo/fbreserror2.png" alt="resource compiler error" /&gt;
&lt;/p&gt;
&lt;p&gt;"What's this ModuleName variable?? What's com.embarcadero.$(ModuleName) ? I didn't put that there...." &lt;/p&gt;
&lt;p&gt;Or "what's this MSBuildProjectName variable?"&lt;/p&gt;
&lt;p&gt;This all stems from Embarcadero's support for non windows platforms (in this case I would suggest andriod). The default values for version info Berlin and later have "$(ModuleName)" in the FileDescription, ProductName and ProgramID fields.&lt;/p&gt;
&lt;p style="text-align: center;"&gt;
&lt;img src="/blogimages/vincent/versioninfo/default-version-info.png" alt="default version info" /&gt;
&lt;/p&gt;
&lt;p&gt;This of course is nonsense for the Windows platform, but some bright new embarcadero hire obviously thought this would be a good idea (well that's what I think, who knows what was behind the decision). The problem is, $(ModuleName) is completely unknown outside of the IDE or MSBuild. So when we compile from the command line (using dcc32, dcc64 etc), if your Delphi Action is set to read the version values from the dproj, then you will get this error. &lt;/p&gt;
&lt;p&gt;There are three options to resolve this :&lt;/p&gt;
&lt;ol style="margin: 10px;"&gt;
    &lt;li&gt;Change the FileDescription field in your delphi project settings to something more meaningful, rather than an ad for Embarcadero, like ummm, oh I know, your product name!&lt;/li&gt;
    &lt;li&gt;Define the ModuleName variable in FinalBuilder - but this still gets the FileDescription field saying com.embarcadero.YourProductName (hey, it's not a java app!). &lt;/li&gt;
    &lt;li&gt;Don't load the version info from the dproj, let FinalBuilder handle it completely. After all, you are using FinalBuilder to create your production builds, and version information is part of the release process, not the development process. &lt;strong&gt;*This would be my recommended option.*&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;</description><guid isPermaLink="false">752</guid></item><item><title>Delphi Language Enhancements</title><link>https://www.finalbuilder.com/resources/blogs/postid/750/delphi-language-enhancements</link><category>Delphi</category><pubDate>Tue, 06 Dec 2016 14:07:00 GMT</pubDate><description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; - The Delphi language is very verbose, dated and unattractive to younger developers. Suggestions for improvements below.&lt;/p&gt;

&lt;p&gt;The Delphi/Object Pascal language really hasn't changed all that much in the last 20 years. Yes there have been some changes, but they were mostly just tinkering around the edges. Probably the biggest change was the addition of Generics and Anonymous methods. Those two language features alone enabled a raft of libraries that were simply not possible before, for example auto mocking (Delphi Mocks, DSharp), dependency injection and advanced collections (Spring4D).&lt;/p&gt;

&lt;p&gt;Some of the features I list below have the potential to spur on the development of other new libraries which can only be a good thing. I have several abandoned projects on my hard drive that were only abandoned because what I wanted to do required language features that just didn't exist in Delphi, or in some cases, the generics implementation fell short of what was needed. Many of these potential features would help reducing verbosity, which helps with maintainability. These days I prefer to write less lines of more expressive code.&lt;/p&gt;

&lt;p&gt;I have tried to focus on language enhancements that would have zero impact on existing code, i.e. they are completely optional. I have often seen comments about language features where people don't want the c#/java/whatever features polluting their pure pascal code. My answer to that is, if you don't like it don't use it!! There are many features in Delphi that I don't like, I just don't use them, but that doesn't mean they should be removed. Each to his own and all that. Another argument put forward is "feature x is just syntactic sugar, we don't need it". That's true, in fact we don't need any language if we are ok with writing binary code! If a feature is sugar, and it helps me write less code, and it's easier to read/comprehend/maintain, then I love sugar, load me up with sugar.&lt;/p&gt;

&lt;h3&gt;Inspiration&lt;/h3&gt;

&lt;p&gt;Lots of the examples below borrow syntax from other languages, rather than try to invent some contrived "pascalish" syntax. The reality is that most developers these days don't just work with one programming language, they switch between multiple (I use Delphi, C#, Javascript &amp; Typescript on a daily basis, with others thrown in on occasion as needed). Trying to invent a syntax just to be different is pointless, just borrow ideas as needed from other languages (just like they did from delphi in the past!) and get on with it!&lt;/p&gt;

&lt;p&gt;I have not listed any functional programing features here, I have yet to spend any real time with functional programming, so won't even attempt to offer suggestions.&lt;/p&gt;

&lt;p&gt;I don't have any suggestions for how any of these features would be implemented in the compiler, having not written a real compiler before I know my limitations!&lt;/p&gt;

&lt;p&gt;Ok, so lets get to it, these are not listed in any particular order.&lt;/p&gt;

&lt;h3&gt;&lt;a id="localvarinit"&gt;&lt;/a&gt;Local Variable Initialisation&lt;/h3&gt;

&lt;p&gt;Allow initialisation of local variables when declaring them, eg :&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	procedure Something;
	var
	  x : integer = 99;
	begin
	.........
	&lt;/pre&gt;

&lt;p&gt;Benefits : 1 less line of code to write/maintain, per variable, initial value is shown next to the declaration, easier to read.&lt;/p&gt;

&lt;h3&gt;&lt;a id="typeinference"&gt;&lt;/a&gt;Type Inference&lt;/h3&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	var
	  x = 99; //it's an integer
	  s = 'hello world'; //it's a string
	begin
	........
	&lt;/pre&gt;

&lt;p&gt;Benefits : less ceremony when declaring variables, still easy to understand.&lt;/p&gt;

&lt;h3&gt;&lt;a id="inlinevars"&gt;&lt;/a&gt;Inline variable declaration, with type inference and block scope&lt;/h3&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	procedure Blah;
	begin
      .......
	  var x : TStrings := TStringList.Create; //no type inference
	//or
	  var x := TStringList.Create; // it's a TStringList, no need to declare the type
	  .......
	end;
	&lt;/pre&gt;

&lt;p&gt;Inline declared variables should have block scope :&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	if test = 0 then
	begin
	  var x := TListString.Create;
	  ....
	end;
	x.Add('bzzzzz'); //Compiler error, x not known here!
&lt;/pre&gt;

&lt;p&gt;Benefits : Declare variables when they are needed, makes it easier to read/maintain as it results in less eye movement, block scope reduces unintended variable reuse.&lt;/p&gt;

&lt;h3&gt;&lt;a id="loopvars"&gt;&lt;/a&gt;Loop variable inline declaration&lt;/h3&gt;

&lt;p&gt;Declare your loop or iteration variable inline ( and they would have loop block scope)&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	for var item in collection do
	begin
	  item.Foo;
	end;
	item.Bar; //error item unknown.
	
	for var i : integer := 0 to count do
    ....
	//or
	for var i := 0 to count do //using type inference
    ....
	&lt;/pre&gt;

&lt;p&gt;Benefits : Avoid the old variable loop value not available outside the loop error, same benefits as inline/block scope etc.&lt;/p&gt;

&lt;h3&gt;&lt;a id="shortcutprops"&gt;&lt;/a&gt;Shortcut property declaration&lt;/h3&gt;

&lt;p&gt;Creating properties that don't have getter/setter methods in Delphi is unnecessarily verbose in Delph&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	
    type
	  TMyClass = class
	  private
	    FName : string;
	  public
	    property Name : string read FName write FName;
	  end;
	&lt;/pre&gt;

&lt;p&gt;All that is really needed is :&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	type
	  TMyClass = class
	  public
	    property Name : string;
	  end;
	&lt;/pre&gt;

&lt;p&gt;Whilst this might seem the same as declaring a public variable, RTTI would be generated differently if it was a variable rather than a property.&lt;/p&gt;

&lt;p&gt;Benefits : Cuts down on boilerplate code.&lt;/p&gt;

&lt;h3&gt;&lt;a id="interfacehelpers"&gt;&lt;/a&gt;Interface Helpers&lt;/h3&gt;

&lt;p&gt;Add interface helpers just like for classes and records. Also, remove the limit of one helper per type per unit (without this the above is not really usable). Have a look at how prevalent extension methods are in C#, Linq is a prime example, it's essentially just a bunch of extension methods.&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	type
	  TIDatabaseConnectionHelper = interface helper for IDatabaseConnection
	    function Query&lt;t&gt; : IQuerable;
	  end;
	&lt;/t&gt;&lt;/pre&gt;

&lt;p&gt;The above is actually a class that extends the interface when it's containing unit is used. This would make implementing something like LINQ possible.&lt;/p&gt;

&lt;h3&gt;&lt;a id="nonordinalcase"&gt;&lt;/a&gt;Strings (and other non ordinals) in Case Statements&lt;/h3&gt;

&lt;p&gt;This has to be the most requested feature by far in the history of delphi imho, sure to make many long time Delphi fans happy.&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	case s of
	  'hello' : x := 1;
	  'goodbye' : x := 2;
	  sWorld : x := 3; //sWorld is a string constant
	end;
	&lt;/pre&gt;

&lt;p&gt;Case sensitivity could be possibly be dealt with at compile time via CaseSensitive 'helper', (or perhaps an attribute). The above example is case insensitive, the example below is case sensitive :&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	case s.CaseSensitive of
	  'hello' : x := 1;
	  'goodbye' : x := 2;
	  sWorld : x := 3; //sWorld is a string constant
	end;
    //or
	case [CaseSensitive]s of
	  'hello' : x := 1;
	  'goodbye' : x := 2;
	  sWorld : x := 3; //sWorld is a string constant
	end;
	&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;How about :&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	case x.ClassType of
	  TBar : x := 1;
	  TFoo : x := 2;
	end;
	&lt;/pre&gt;

&lt;p&gt;Benefits : Simpler, less verbose code.&lt;/p&gt;

&lt;h3&gt;&lt;a id="ternaryoperator"&gt;&lt;/a&gt;Ternary Operator&lt;/h3&gt;

&lt;p&gt;A simpler way of writing :&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	If y = 0 then
	  x := 0
	else
	  x := 99;
	&lt;/pre&gt;

&lt;p&gt;Syntax : x := bool expr ? true value, false value&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	//eg
	x := y = 0 ? 0 : 99;
	&lt;/pre&gt;

&lt;p&gt;Benefits : Simpler, more succinct code.&lt;/p&gt;

&lt;h3&gt;&lt;a id="tryexceptfinally"&gt;&lt;/a&gt;Try/Except/Finally&lt;/h3&gt;

&lt;p&gt;Probably the equal most requested language feature, allowing for try/except/finally without nesting try blocks.&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	try
	...
	except
	..
	finally
	...
	end;
	&lt;/pre&gt;

&lt;p&gt;Much cleaner than:&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	try
	  try
	    ...
	  except
	    ...
	  end;
	finally
	  ....
	end;
	&lt;/pre&gt;

&lt;p&gt;Benefits : Neater, Tidier, Nicer&lt;/p&gt;

&lt;h3&gt;&lt;a id="namedargs"&gt;&lt;/a&gt;Named Arguments&lt;/h3&gt;

&lt;p&gt;Say for example, we have this procedure, with more than one optional parameter :&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	procedure TMyClass.DoDomething(const param1 : string; const param2 : ISomething = nil; const param3 : integer = 0);
	&lt;/pre&gt;

&lt;p&gt;To call this method, if I want to pass a value for param3, I have to also pass a value for parm2&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	x.DoSomething('p1', nil,99);
	&lt;/pre&gt;

&lt;p&gt;With named parameters, this could be :&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	x.DoSomething('p1', param3 = 99);
	&lt;/pre&gt;

&lt;p&gt;Yes, this means I have to type more, but it's much more readable down the track when maintaining the code. I also don't need to lookup the order of the parameters, or provide redundant values for parameters that I want to just use their default values for. I also don't end up adding a bunch of overloaded methods to make the method easier to call.&lt;/p&gt;

&lt;p&gt;Benefits : More expressive method calls, less overloads.&lt;/p&gt;

&lt;h3&gt;&lt;a id="varargs"&gt;&lt;/a&gt;Variable method arguments&lt;/h3&gt;

&lt;p&gt;Steal this from C# (which probably borrowed the idea from c++ varargs ... feature)&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	procedure DoSomething(params x : array of integer);
	&lt;/pre&gt;

&lt;p&gt;The method can be called passing ether an array param&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	procedure TestDoSomething;
	var
	   p : array of integer;
	begin
	...... //(fill out the p array)
	  DoSomething(p);
	  //or
	  DoSomething(1);
	  DoSomething(1,2);
	  DoSomething(1,2,3);
	  ........
	&lt;/pre&gt;

&lt;p&gt;Benefits : Flexibilty in how a method is called.&lt;/p&gt;

&lt;h3&gt;&lt;a id="lambdas"&gt;&lt;/a&gt;Lambdas&lt;/h3&gt;

&lt;p&gt;Delphi's anonymous method syntax is just too damned verbose, wouldn't you prefer to write/read this:&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	var rate := rates.SingleOrDefault(x =&gt; x.Currency = currency.Code);
	&lt;/pre&gt;

&lt;p&gt;rather than this :&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	var
	  rate : IRate;
	begin
	  rate := rates.SingleOrDefault(function(x : IRate) : boolean;
	                                begin
	                                  result := x.Currency = currency.Code;
	                                end);
	...
	&lt;/pre&gt;

&lt;p&gt;Ok, so I did sneak in an inline type inferenced local var in the first example, and both snippets rely on the existence of interface helpers (rates would be IEnumerable &lt;rate&gt;) ;)&lt;/rate&gt;&lt;/p&gt;

&lt;p&gt;Benefits : Less code to write/maintain, the smiles on the faces of developers who switch between delphi and c# all the time!&lt;/p&gt;

&lt;h3&gt;&lt;a id="linq"&gt;&lt;/a&gt;LINQ!&lt;/h3&gt;

&lt;p&gt;With Lambdas and multiple type helpers per type per unit, a LINQ like feature would possible. Whilst the Delphi Spring library has had Linq like extensions to IEnumerable &lt;t&gt; for a while, this would formalise the interfaces and provides an implementation used by the collection classes. Providers for XML and Database (eg FireDac) would be possible.&lt;/t&gt;&lt;/p&gt;

&lt;p&gt;Even a Linq 2 VCL &amp; Linq 2 FMX would be possible. A common scenario, update a bunch of controls based on some state change :&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	Self.Controls.Where( x =&gt; x.HasPropertyWithValue&lt;boolean&gt;('ForceUpdate', true) or x.IsType&lt;iforceupdate&gt;).Do( c =&gt; c.Refresh); //or something like that.
&lt;/pre&gt;

&lt;p&gt;This would make it possible to operate on controls on a form, without a) knowing their names, b) having references to them, or c) knowing if the control actually exists.&lt;/p&gt;

&lt;p&gt;Being able to do this with something like a linq expression would be a massive improvement.. all that's needed is a linq provider for each control framework. Sorta Like jQuery for the VCL/FMX!&lt;/p&gt;

&lt;p&gt;Benefits : Too many to list here!&lt;/p&gt;

&lt;p&gt;Caveats : Microsoft have a &lt;a href="https://www.google.com/patents/US8285708"&gt;patent on LINQ&lt;/a&gt; - so perhaps this isn't really doable? Perhaps with a slightly different syntax. Or challenge the patent!&lt;/p&gt;

&lt;h3&gt;&lt;a id="asyncawait"&gt;&lt;/a&gt;Async/Await&lt;/h3&gt;

&lt;p&gt;Bake the parallel library features into the language/compilers, much like C# and other languages have done over recent years (ala async, await). That makes it possible/easier to write highly scalable servers, over the top of asynchronous I/O. Yes, it's technically possible now, but it's so damned difficult to get right/prove it's right that very few have attempted it. This also make it possible to use the Promise pattern, something along these lines - https://github.com/Real-Serious-Games/C-Sharp-Promise to handle async tasks.&lt;/p&gt;

&lt;p&gt;Benfits : Write scalable task oriented server code without messing with low level threading, write responsive non blocking client code.&lt;/p&gt;

&lt;p&gt;Caveats : Microsoft have a &lt;a href="https://www.google.com.au/patents/US9092564"&gt; patent on Async/Await&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;&lt;a id="nonrefinterfaces"&gt;&lt;/a&gt;Non reference counted interfaces&lt;/h3&gt;

&lt;p&gt;Make it possible to use have interfaces without reference counting. I use interfaces a lot, even on forms and frames, I like to limit what surface is exposed when passing these objects around, but it can be painful when the compiler tries to call _Release on a form that is being destroyed. Obviously, there are ways to deal with this (careful clean up) but it's an easy trap to fall in and very difficult to debug.&lt;/p&gt;

&lt;p&gt;Possible syntax :&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	[NoRefCount] // &lt;&lt; decorate interface with attribute to tell compiler reference counting not required.
	IMyInterface = interface
	....
	end;
	&lt;/pre&gt;

&lt;p&gt;There would have to be some limits imposed (using the next feature in this list), for example not allowing use of the attribute on an interface that descends from another interface which is reference counted. It would cause mayhem if passed to a method that takes the base interface (for which the compiler would then try generate addref/release calls).&lt;/p&gt;

&lt;p&gt;Benefits : Remove the overhead of reference counting, avoid unwanted side effects from compiler generated _Release calls.&lt;/p&gt;

&lt;h3&gt;&lt;a id="attributeconstraints"&gt;&lt;/a&gt;Attribute Constraints&lt;/h3&gt;

&lt;p&gt;(RSP-13322)&lt;/p&gt;

&lt;p&gt;Delphi attributes do not currently have any constraint feature that allows the developer to limit their use, so for example an attribute designed to be applied to a class can currently be applied to a method.&lt;/p&gt;

&lt;h3&gt;&lt;a id="operatoroverloading"&gt;&lt;/a&gt;Operator overloading on classes.&lt;/h3&gt;

&lt;p&gt;Currently operator overloading is only available on records, adding them to classes would make it possible to create some interesting libraries (DSL's even).&lt;/p&gt;

&lt;p&gt;I had discussions with Allen Bauer (and others over) many years ago about about this. Memory management was always the stumbling block, with ARC this would not be big issues. Even without ARC, I think delphi people are capable of dealing with memory management requirements, just like we always have.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edit&lt;/em&gt; : I believe this feature is actually available on the ARC enabled compilers.&lt;/p&gt;

&lt;h3&gt;&lt;a id="genericonstraints"&gt;&lt;/a&gt;Improve Generic Constraints&lt;/h3&gt;

&lt;p&gt;Add additional constraint types to generics, for example :&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	type
	  TToken&lt;t:enum&gt; = class
	    .....
	  end;
	&lt;/t:enum&gt;&lt;/pre&gt;

&lt;p&gt;Benefits : more type safety, less runtime checking code required.&lt;/p&gt;

&lt;h3&gt;&lt;a id="fixienumerable"&gt;&lt;/a&gt;Fix IEnumerable &lt;t&gt;&lt;/t&gt;&lt;/h3&gt;

&lt;p&gt;Not so much a language change rather than a library change, please borrow spring4d's version - much easier to implement in 1 class (delphi's version is impossible to implement in 1 class as it confuses the compiler!).&lt;/p&gt;

&lt;h3&gt;&lt;a id="yield"&gt;&lt;/a&gt;Yield return - Iterator blocks&lt;/h3&gt;

&lt;p&gt;The yield keyword in C# basically generates Enumerator implementations at compile time, which allows the developer to avoid writing a bunch of enumerator classes, which are essentially simple state machines. These enumerators should be relatively easy for the compiler to generate.&lt;/p&gt;

&lt;p&gt;This a a good example (sourced from &lt;a href="https://stackoverflow.com/questions/39476/what-is-the-yield-keyword-used-for-in-c"&gt;this stackoverflow post&lt;/a&gt;&lt;/p&gt;

&lt;pre class="brush:c#; toolbar:false;"&gt;
	public IEnumerable&lt;t&gt; Read&lt;t&gt;(string sql, Func&lt;idatareader, t=""&gt; make, params object[] parms)
	{
	  using (var connection = CreateConnection())
	  {
	    using (var command = CreateCommand(CommandType.Text, sql, connection, parms))
	    {
	      command.CommandTimeout = dataBaseSettings.ReadCommandTimeout;
	      using (var reader = command.ExecuteReader())
	      {
	        while (reader.Read())
	        {
	          yield return make(reader);
	        }
	      }
	    }
      }
	}
	&lt;/idatareader,&gt;&lt;/t&gt;&lt;/t&gt;&lt;/pre&gt;

&lt;p&gt;The example above will read the records in from the database as they are consumed, rather than reading them all into a collection first, and then returning the collection. This is far more memory efficient when there are a lot of rows returns. In essence, the consumer/caller is "pulling" the records from the database when required, this could for example be pulling messages from a queue.&lt;/p&gt;

&lt;p&gt;I guess for delphi, this could be a simple Yield() method( or YieldExit() to more more explicit).&lt;/p&gt;

&lt;p&gt;Benefits : less boilerplate enumerator code, lower memory usage when working with large or unbounded datasets or queues etc.&lt;/p&gt;

&lt;h3&gt;&lt;a id="partialclasses"&gt;&lt;/a&gt;Partial classes&lt;/h3&gt;

&lt;p&gt;Yes I know, this one is sure to kick up a storm of complaints (I recall an epic thread about this topic on the newsgroups about this years ago). Like everything else, if you don't like it, don't use it. I don't often use this feature in C#, but it is indispensable for one particular scenario, working with generated code. Imagine generating code from an external model or tool for example type libraries, uml tools, database schema, orm, idl etc. The generated code would typically be full of warning comments about how it's generated code and shouldn't be modified. Partial classes get around this, by allowing you to Add code to the generated classes, and the next time they are regenerated, your added code remains intact. Simple, effective.&lt;/p&gt;

&lt;p&gt;Benefits : Enables code generation scenarios without requiring base classes.&lt;/p&gt;

&lt;h3&gt;&lt;a id="multipleuses"&gt;&lt;/a&gt;Allow Multiple Uses clauses&lt;/h3&gt;

&lt;p&gt;(RSP-13777)&lt;/p&gt;

&lt;p&gt;This is something that would make commenting/uncommenting units from the uses clause a lot easier, and also make tooling of the uses clause easier.&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	uses
	sharemem, System.SysUtils, System.Classes, vcl.graphics{$ifdef debug},logger{$endif};
	&lt;/pre&gt;

&lt;p&gt;The above syntax is easily messed up by the IDE.&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	uses sharemem;
	uses System.SysUtils, System.Classes;
	uses vcl.graphics;
    {$IFDEF debug}uses logger;{$endif}
	&lt;/pre&gt;

&lt;p&gt;This makes commenting-out and reorganising the library names more convenient. It would also make refactoring and other tooling easier.&lt;/p&gt;

&lt;h3&gt;&lt;a id="interfacegenerics"&gt;&lt;/a&gt;Allow non parameterized interfaces to have parameterized methods&lt;/h3&gt;

&lt;p&gt;(RSP-13725)&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	IContainer = interface
	['{2B7B3956-7101-4619-A6DA-C8AF61EE4A81}']
	  function Resolve&lt;t&gt;: T;
	end;
	&lt;/t&gt;&lt;/pre&gt;

&lt;p&gt;That won't compile, but this code works as expected:&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:false;"&gt;
	TContainer = class
	  function Resolve&lt;t&gt;: T;
	end;
    &lt;/t&gt;&lt;/pre&gt;

&lt;p&gt;This is a limitation I have come across many times when trying to port code from C# to Delphi.&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;That's 20+ useful, optional and simple to implement (just kidding) language features that I would personally like to see in Delphi (and I would use every one of them). I could have gone on adding a lot more features, but I think these are enough to make my point.&lt;/p&gt;

&lt;p&gt;Here's my suggestion to Embarcadero, invest in the language and make up for lost time! While you are at it, sponsor some developers to try porting some interesting and complex open source libraries to delphi, and when they hit road blocks in the language or compiler(and they will), make it work, iterate until baked. I tried porting ReactiveX https://reactivex.io/ to delphi a while back, but hit too many roadblocks in the language and compiler (internal compiler errors, limitations in the generics implementation).&lt;/p&gt;

&lt;p&gt;The end result would be a modern, capable language that can handle anything thrown at it.&lt;/p&gt;
</description><guid isPermaLink="false">750</guid></item><item><title>VSoft.CommandLineParser for Delphi - Updated</title><link>https://www.finalbuilder.com/resources/blogs/postid/740/vsoftcommandlineparser-for-delphi-updated</link><category>Delphi,Open Source</category><pubDate>Thu, 10 Dec 2015 11:24:20 GMT</pubDate><description>&lt;p&gt;A while back I published the VSoft.CommandLineParser library on github, which makes it simple to handle command line options in delphi applications. The first version only did enough to satisfy the needs I had in DUnitX. &lt;/p&gt;
&lt;p&gt;In another project I&amp;rsquo;m working on, I needed a command mode, where each command had a unique set of options, but keeping the ability to have global options.&amp;nbsp; I have tried to implement the command mode in a backwards compatable manner, and so far the only change I had to make to an existing project was adding a const to a parameter. &lt;/p&gt;
&lt;h3&gt;Adding Commands&lt;/h3&gt;
&lt;p&gt;Adding commands is quite simple, using TOptionsRegistry.RegisterCommand. &lt;/p&gt;
&lt;pre class="brush:delphi; toolbar:true;"&gt;cmd := TOptionsRegistry.RegisterCommand('help','h','get some help','','commandsample help [command]'); 
option := cmd.RegisterUnNamedOption&amp;lt;string&amp;gt;('The command you need help for', 
  procedure(const value : string) 
  begin 
    THelpOptions.HelpCommand := value; 
  end);&lt;/pre&gt;
&lt;p&gt;Note: this method returns a TCommandDefinition record that you can add options to. The reason for using a record rather than an interface here, is because delphi interfaces do not suport generic methods. Records do, so we use the record type as a wrapper around the ICommandDefinition interface.&lt;/p&gt;
&lt;p&gt;The helpstring parameter allows you to specify a longer help message that can be displayed when showing command usage.&lt;/p&gt;
&lt;h3&gt;Handling Commands&lt;/h3&gt;
&lt;p&gt;The ICommandLineParseResult interface has a new Command property (string) which is used to determine the selected command. It&amp;rsquo;s up to you how to actually run the commands. &lt;/p&gt;
&lt;h3&gt;Showing Usage&lt;/h3&gt;
&lt;p&gt;The PrintUsage method now has some overloads and has some formatting improvements, and TOptionsRegistry also has new EnumerateCommands and EmumerateCommandOptions methods which make it relatively simple to handle showing usage etc yourself if you want to. &lt;/p&gt;
&lt;h3&gt;Where is it?&lt;/h3&gt;
&lt;p&gt;The source with samples is available on GitHub - &lt;a title="https://github.com/VSoftTechnologies/VSoft.CommandLineParser" href="https://github.com/VSoftTechnologies/VSoft.CommandLineParser" target="_blank"&gt;https://github.com/VSoftTechnologies/VSoft.CommandLineParser&lt;/a&gt;&lt;/p&gt;</description><guid isPermaLink="false">740</guid></item><item><title>Modifying XML Manifest files with FinalBuilder</title><link>https://www.finalbuilder.com/resources/blogs/postid/739/modifying-xml-manifest-files-with-finalbuilder</link><category>.NET,DelphiFinalBuilder,General,XML</category><pubDate>Mon, 07 Dec 2015 11:37:47 GMT</pubDate><description>This topic is something that I pulled from our support system, it's something we get asked about more that once a year, that is, how do I modify the xml manifest file using FinalBuilder. Typically its the assembly version attribute that users want to modify, so that's what I'll show here, but you can use the same technique to edit other parts of the manifest file.&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
So lets define our XML Document by adding an &lt;a href="https://wiki.finalbuilder.com/display/FB8/XML+Document+Define+Action" target="_blank" title="XML Document Define Action Documentation"&gt;XML Document Define Action&lt;/a&gt;, and point it at our manifest file.&lt;br /&gt;
&lt;br /&gt;
&lt;p style="text-align: center;"&gt;
&lt;img src="/blogimages/vincent/manifest/manifest-xml-doc.png" alt="Define XML Document" /&gt;
&lt;/p&gt;
&lt;br /&gt;
If you open your manifest file in notpad, you will notice assembly element looks something like this :&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:xml; toolbar:true;"&gt;&amp;lt;assembly xmlns="urn:schemas-microsoft-com:asm.v1"  manifestVersion="1.0" &amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
Note the xmlns attribute, this is what causes users problems with the xml actions in FinalBuilder, XML Namespaces. The MXSML Parser is very strict when it comes to namespaces, and it requires that we make use of them when using XPath to select nodes.&amp;nbsp;On the XML Document action, switch to the MSXML Parser tab and in the Extra Namespaces grid, add the following.&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
&lt;p style="text-align: center;"&gt;
&lt;img src="/blogimages/vincent/manifest/manifest-xml-doc2.png" alt="Namespace Prefix" /&gt;
&lt;/p&gt;
&lt;br /&gt;
What we are doing here is assigning a prefix (x in this case) to the namespace. This prefix will be used in our XPath statements.&lt;br /&gt;
&lt;br /&gt;
Add an&lt;a href="https://wiki.finalbuilder.com/display/FB8/Edit+XML+File+Action" target="_blank" title="Edit XML File Action documentation"&gt; Edit XML File action&lt;/a&gt; - set the XML File to use an XML Document and select the document we defined with the previous action. Now we need to define the XPath statement to the version attribute that we are going to modify.&lt;br /&gt;
&lt;br /&gt;
&lt;p style="text-align: center;"&gt;
&lt;img src="/blogimages/vincent/manifest/manifest-xml-edit-version.png" alt="Edit XML" /&gt;
&lt;/p&gt;
&lt;br /&gt;
And finally, add a Save XML Document Action to save our changes to the file. Note that if you are editing other parts of the manifest file, make sure you add the namespaces and different prefixes, and use this prefixes appropriately in your XPath statements.&lt;br /&gt;
&lt;br /&gt;
Note, all of this could be done in a single Edit XML File action, however, if you want to make more than one modification to the manifest file then it's more efficient to use the xml document define action to avoid loading/parsing/saving the document for each edit.&amp;nbsp;&lt;br /&gt;</description><guid isPermaLink="false">739</guid></item><item><title>Delphi Code Coverage with Continua CI</title><link>https://www.finalbuilder.com/resources/blogs/postid/738/delphi-code-coverage-with-continua-ci</link><category>Continua CI,Delphi</category><pubDate>Sun, 08 Nov 2015 12:35:00 GMT</pubDate><description>&lt;p&gt;Testing code is something we all do. Whether it be manual usability testing, unit testing, or integration testing, knowing how much of the application is covered by the tests is important. Without knowing what parts of the application are covered, there is no way to know if key features are tested.&lt;br /&gt;
	&lt;br /&gt;
	When performing unit testing there is an analytical way to determine what parts of the source code are covered by the tests. This is typically call source code coverage. Working with Delphi, one of the tools that performs this task is called DelphiCodeCoverage (open source). It can be located on &lt;a href="https://github.com/NeonGraal/DelphiCodeCoverage"&gt;GitHub&lt;/a&gt; (more recent fork) and &lt;a href="https://sourceforge.net/projects/delphicodecoverage"&gt;SourceForge&lt;/a&gt;. Under the hood this tool simply marks each line of source code as "hit" when the application calls it at least once. From there it can generate a detailed report giving the overall coverage statistics for the project, as well as the individual lines not hit in the testing.&lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;img alt="" src="https://www.finalbuilder.com/blogImages/jason/DelphiCodeCoverage/CodeCoverage_ContinuaCoverageReport.png" style="width: 800px; height: 266px; vertical-align: middle; text-align: center;" /&gt;&lt;/p&gt;

&lt;h2&gt;Code Coverage&lt;/h2&gt;

&lt;p&gt;What I will go through below is how to setup code coverage on a unit test project, and hook that into a continuous integration process using Continua CI. I will assume that if you require knowledge on how to setup a project on Continua CI you will refer to the &lt;a href="https://wiki.finalbuilder.com/display/continua/Part+1%3A+Create+your+First+Project"&gt;Create your First Project&lt;/a&gt; wiki page. &lt;br /&gt;
	&lt;br /&gt;
	The code that I would like to get a code coverage report on is the &lt;a href="https://github.com/VSoftTechnologies/DelphiCodeCoverageExample/blob/master/Core/Core.Card.pas" target="_blank"&gt;Core.Card.pas&lt;/a&gt; unit. The unit tests for this class are located in the tests folder and have a corresponding name of &lt;a href="https://github.com/VSoftTechnologies/DelphiCodeCoverageExample/blob/master/Tests/Core.CardTests.pas" target="_blank"&gt;Core.CardTests.pas&lt;/a&gt;. You may have noticed that some of the code paths are not fully covered in my unit tests. This is intentional, and something that we will come to a little later on. &lt;br /&gt;
	&lt;br /&gt;
	An extra consideration to have with a unit testing project is to make sure it can run under continuous integration. This means that it should run to completion and produce an output file that is able to be imported into the build summary. With this in mind I have created a "CI" &lt;a href="https://wiki.finalbuilder.com/display/continua/Configurations" target="_blank"&gt;configuration&lt;/a&gt; on my unit testing project. This conditionally compiles the unit testing project so that it does not wait for user input (something my debug configuration does) and generates an XML output file. &lt;br /&gt;
	&lt;br /&gt;
	All this code and other related scripts are located in the &lt;a href="https://github.com/VSoftTechnologies/DelphiCodeCoverageExample"&gt;VSoftTechnologies/DelphiCodeCoverageExample&lt;/a&gt; GitHub repository. Feel free to clone it to get a better sense of code coverage and the project structure I am using. &lt;br /&gt;
	 &lt;/p&gt;

&lt;h2&gt;DelphiCodeCoverage&lt;/h2&gt;

&lt;p&gt;To generate a code coverage report I decided to use DelphiCodeCoverage. The tool has a number of command line options, all of which are spelt out on the GitHub page. Some of the options are a little overwhelming in the effort they require. An example of this is passing a file that contains all the source directories to search for classes to include in the code coverage report. Thankfully there is a wizard supplied with DelphiCodeCoverage that will help generate a batch file containing the correct parameters to pass to DelphiCodeCoverage. &lt;br /&gt;
	&lt;br /&gt;
	In my project I have placed DelphiCodeCoverage into a sub-folder call "CodeCoverage" and included it into source control. There are two reasons I am doing this;&lt;br /&gt;
	1. The code coverage executable is now available everywhere the source is pulled to. &lt;br /&gt;
	2. It simplifies the script I will need for the CI Server. &lt;br /&gt;
	If your uncomfortable with placing binaries into your source control, this can be altered without affecting the produced report. &lt;br /&gt;
	&lt;br /&gt;
	Running the code coverage wizard your presented with a page to enter the executable, map file, source, and output directory locations. Below are the settings I have used:&lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;br /&gt;
	&lt;br /&gt;
	&lt;img alt="" src="https://www.finalbuilder.com/blogImages/jason/DelphiCodeCoverage/CodeCoverageWizard_Executable.png" style="width: 500px; height: 187px; text-align: center; vertical-align: middle;" /&gt;&lt;br /&gt;
	&lt;br /&gt;
	&lt;img alt="" src="https://www.finalbuilder.com/blogImages/jason/DelphiCodeCoverage/CodeCoverageWizard_Source.png" style="width: 500px; height: 176px; vertical-align: middle;" /&gt;&lt;br /&gt;
	&lt;br /&gt;
	&lt;img alt="" src="https://www.finalbuilder.com/blogImages/jason/DelphiCodeCoverage/CodeCoverageWizard_Output.png" style="width: 500px; height: 299px; vertical-align: middle;" /&gt;&lt;br /&gt;
	&lt;br /&gt;
	&lt;img alt="" src="https://www.finalbuilder.com/blogImages/jason/DelphiCodeCoverage/CodeCoverageWizard_Settings.png" style="width: 500px; height: 160px; vertical-align: middle;" /&gt;&lt;br /&gt;
	 &lt;/p&gt;

&lt;p&gt;The last option for the wizard allows for making all paths relative. This is exactly what we require to have our generated batch file run on any system, however at the time of writing it does not work correctly. This meant that I had to manually change all paths to a version that was relative to the folder in which DelphiCodeCoverage was located.&lt;/p&gt;

&lt;h4&gt;dcov_execute.bat before&lt;/h4&gt;

&lt;pre class="brush:delphi; toolbar:true;"&gt;
"I:\Examples\DUnitX_CodeCoverage\CodeCoverage\CodeCoverage.exe" 
-e "I:\Examples\DUnitX_CodeCoverage\Win32\Debug\DUnitX_And_CodeCoverage.exe" 
-m "I:\Examples\DUnitX_CodeCoverage\Win32\Debug\DUnitX_And_CodeCoverage.map" 
-uf dcov_units.lst -spf dcov_paths.lst 
-od "I:\Examples\DUnitX_CodeCoverage\CodeCoverage\Output\" -lt -html
&lt;/pre&gt;

&lt;h4&gt;dcov_execute.bat after&lt;/h4&gt;

&lt;pre class="brush:delphi; toolbar:true;"&gt;
"CodeCoverage.exe" 
-e "..\Win32\CI\DUnitX_And_CodeCoverage.exe" 
-m "..\Win32\CI\DUnitX_And_CodeCoverage.map" 
-ife -uf dcov_units.lst -spf dcov_paths.lst -od ".\Output\" -lt -html
&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;Note: Line breaks are only included above for readability. There are none in the resulting batch files.&lt;/em&gt;&lt;br /&gt;
	&lt;br /&gt;
	Another alteration that I have made to the batch file is to include the "-ife" option. The option will include file extensions. This means that it will stop a unit like "Common.Encoding" being 'converted' to "Common". As in my project I have unit called "Core.Cards.pas" this option is required to have it included in generated code coverage report. &lt;br /&gt;
	&lt;br /&gt;
	Next the relative path change should be applied to the two generated list files &lt;a href="https://github.com/VSoftTechnologies/DelphiCodeCoverageExample/blob/master/CodeCoverage/dcov_paths.lst"&gt;dcov_paths.lst&lt;/a&gt; and &lt;a href="https://github.com/VSoftTechnologies/DelphiCodeCoverageExample/blob/master/CodeCoverage/dcov_units.lst"&gt;dcov_units.lst&lt;/a&gt;. The paths file should be the only one that has path in need of altering to be relative. Both however need to be checked to make sure they contain everything to be covered in the report. If there are source folders missing they need to be added to the dcov_paths.lst file. If there are unit names missing they need to be added to the dcov_units.lst file. &lt;br /&gt;
	&lt;br /&gt;
	Now that the batch file and list files have been corrected running the dcov_executable.bat should produce summary out similar to that below. Note that the unit test project needs to be compiled as DelphiCodeCoverage runs the unit test executable.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:true;"&gt;
**********************************************************************
*              DUnitX - (c) 2013 Vincent Parrett                     *
*                    vincent@finalbuilder.com                        *
*                                                                    *
*        License - https://www.apache.org/licenses/LICENSE-2.0        *
**********************************************************************
  Fixture : Core
  -------------------------------------------------
     Fixture : Core.CardTests
     -------------------------------------------------
        Fixture : Core.CardTests.TCardTest
        -------------------------------------------------
          Test : Core.CardTests.TCardTest.A_Card_FacingUp_Once_Flipped_Is_Facing_Down
          -------------------------------------------------
          Executing Test : A_Card_FacingUp_Once_Flipped_Is_Facing_Down
            Success.
         Running Fixture Teardown Method : Destroy

         Done testing.
         Tests Found   : 1
         Tests Ignored : 0
         Tests Passed  : 1
         Tests Leaked  : 0
         Tests Failed  : 0
         Tests Errored : 0

Summary:
+-----------+-----------+-----------+
|   Lines   |  Covered  | Covered % |
+-----------+-----------+-----------+
|        15 |        11 |      73 % |
+-----------+-----------+-----------+
&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;Continuous Integration&lt;/h2&gt;

&lt;p&gt;With the code coverage batch file we are now able to run code coverage on any system, include on a continuous integration system. Our goal with the continuous integration is to have the unit tests built and run each time a set of code is checked into source control. This will allow us to then track if any unit tests fail, and changes in the code coverage. &lt;br /&gt;
	&lt;br /&gt;
	To achieve this I have create a &lt;a href="https://wiki.finalbuilder.com/display/continua/Configurations" target="_blank"&gt;Continua CI configuration&lt;/a&gt; that builds my unit test project, runs the unit tests under code coverage, and then import the unit test results into the build summary. &lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;br /&gt;
	&lt;img alt="" src="https://www.finalbuilder.com/blogImages/jason/DelphiCodeCoverage/CodeCoverage_ContinuaActions.png" /&gt;&lt;/p&gt;

&lt;p&gt;The FinalBuilder action calls the FinalBuilder project responsible for compiling the DUnitX unit test project. It uses the CI configuration so that the unit tests executable will run to completion, and will produce an NUnit XML results file in the same directory as the executable. It is important to build the unit tests each time as the source code for our project would have changed each time we run the continuous integration. Note that you do not have to use FinalBuilder, you can also use MSBuild to build your DUnitX Project - see &lt;a href="/resources/blogs/integrating-dunitx-unit-testing-with-continua-ci" target="_blank"&gt;Integrating DUnitX Unit Testing with Continua CI&lt;/a&gt;.&lt;br /&gt;
	&lt;br /&gt;
	The &lt;a href="https://wiki.finalbuilder.com/display/continua/Execute+Program+Action" target="_blank"&gt;execute program action&lt;/a&gt; simply runs the code coverage batch file generated above. This batch file will run the unit test project we compiled and log code coverage information as it does. The result will be a summary written out to our build log while also html files written to the report folder we specified in the batch file. It is these html files which we will attach to the continuous build report a little later. &lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;br /&gt;
	&lt;img alt="" src="https://www.finalbuilder.com/blogImages/jason/DelphiCodeCoverage/CodeCoverage_ContinuaExecuteProgram.png" style="width: 720px; height: 230px;" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
	Lastly we want to import the actual unit test results. These are written out by DUnitX as a NUnit compatible XML file which we can import with the "Import NUnit Tests" action. The results from the XML file will be attached to the build report presented by Continua CI.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;br /&gt;
	&lt;img alt="" src="https://www.finalbuilder.com/blogImages/jason/DelphiCodeCoverage/CodeCoverage_ContinuaImportNUnit.png" style="width: 720px; height: 231px;" /&gt;&lt;/p&gt;

&lt;p&gt;As all builds for Continua CI are run on agents, and all build reports come from the server, we need to transfer the code coverage report back to the server. This is done through &lt;a href="https://wiki.finalbuilder.com/display/continua/Workspace+Rules" target="_blank"&gt;workspace rules&lt;/a&gt; on the build stage. In this example DelphiCodeCoverage writes out all html report files to a relative directory of ".\Output\". This means if we run the DelphiCodeCoverage batch file from "Source&lt;span&gt;\Output\CodeCoverage\" the report should appear in "Source\Output\CodeCoverage\Output" (Note that $Source.DelphiCodeCoverage.Path$ was mapped to the \Source\ folder on the agent). Workspace rules use the greater than symbol to signal the files should be copied from the server to the agent, and the less than symbol to copy from the agent to the server. This therefore leaves use the workspace rule of "“/Output/CodeCoverage/ &lt; \Source\CodeCoverage\Output\*.html" to get all code coverage report files back to the server. &lt;/span&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;br /&gt;
	&lt;img alt="" src="https://www.finalbuilder.com/blogImages/jason/DelphiCodeCoverage/CodeCoverage_ContinuaWorkspaceRules.png" style="width: 500px; height: 190px;" /&gt;&lt;/p&gt;

&lt;p&gt;Now that the html reports are on the server, we need to show them against the Continua CI build. To achieve this we use the &lt;a href="https://wiki.finalbuilder.com/display/continua/Reports" target="_blank"&gt;reports section&lt;/a&gt; of our Continua CI configuration. The reports section allows us to specify a file to attach to the build as a report to be displayed or offered as a download. In this case we want to display the report summary html file. All reports work from the server point of view, and each build has it own workspace on the server. To this end the report we want to be display would have been copied to "$Workspace$\Output\CodeCoverage\CodeCoverage_summary.html". &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;br /&gt;
	&lt;img alt="" src="https://www.finalbuilder.com/blogImages/jason/DelphiCodeCoverage/CodeCoverage_ContinuaCreateReport.png" style="width: 500px; height: 132px;" /&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h2&gt;The Code Coverage Report&lt;/h2&gt;

&lt;p&gt;The end report appearing in the report section of the Continua CI build summary. &lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;br /&gt;
	&lt;img alt="" src="https://www.finalbuilder.com/blogImages/jason/DelphiCodeCoverage/CodeCoverage_ContinuaCoverageReport.png" style="width: 800px; height: 266px; vertical-align: middle;" /&gt;&lt;/p&gt;

&lt;p&gt;As shown in the report the example project has some code that is not covered during unit testing. This reduces the overall coverage to 73%. If I had more than one unit each would have their own code coverage summary. In addition I could click on each file and get a line by line report to see what section of the unit is not covered. &lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;br /&gt;
	&lt;img alt="" src="https://www.finalbuilder.com/blogImages/jason/DelphiCodeCoverage/CodeCoverage_ContinuaCoverageMissing.png" /&gt;&lt;/p&gt;

&lt;h2&gt;Final Notes&lt;/h2&gt;

&lt;p&gt;It is worth mentioning that code coverage is only one arrow in a software testing quiver. In my example I purposely chose to include code that was not covered. This showed the power of code coverage in picking up where unit testing should potentially be directed to next. I also included code where the unit tests cover the code, however not fully. The code testing Core.Card.Flip only tests one path through the code, not all the possible paths. Currently the test sees if the code works when going from face up to face down, not from face down to face up. Although in this example it might be benign, it shows that other tools are needed to help cover this gap.&lt;/p&gt;
</description><guid isPermaLink="false">738</guid></item><item><title>Delphi-Mocks Parameter Matchers</title><link>https://www.finalbuilder.com/resources/blogs/postid/737/delphi-mocks-parameter-matchers</link><category>Delphi,GeneralGit,Open Source</category><pubDate>Tue, 22 Sep 2015 10:15:11 GMT</pubDate><description>&lt;p&gt;
We recently updated Delphi Mocks to allow for better parameter matching on Expectations registered with the Mock. This allows the developer to place tighter controls on verifying that a mocked interface/object method is called.
Below is a simple example of when the parameter matchers can be used.
&lt;/p&gt;
&lt;pre class="brush:delphi; toolbar:true;  highlight:[14,15,16,17]"&gt;procedure TExample_InterfaceImplementTests.Implement_Multiple_Interfaces;
var
  sutProjectSaver : IProjectSaveCheck;
  mockProject : TMock&amp;lt;IProject&amp;gt;;
begin
  //Test that when we check and save a project, and its dirty, we save.
  //CREATE - The project saver under test.
  sutProjectSaver := TProjectSaveCheck.Create;
  //CREATE - Mock project to control our testing. 
  mockProject := TMock&amp;lt;IProject&amp;gt;.Create;
  //SETUP - Mock project will show as dirty and will expect to be saved.  
  mockProject.Setup.WillReturn(true).When.IsDirty;

  //NEW! - Add expectation that the save will be called as dirty is returning true. 
  //       As we don't care about the filename value passed to us we 
  //       allow any string to be passed to report this expectation as met. 
  mockProject.Setup.Expect.Once.When.Save(It(0).IsAny&amp;lt;string&amp;gt;());
    
  //TEST - Visit the mock element to see if our test works.
  sutProjectSaver.Execute(mockProject);
  //VERIFY - Make sure that save was indeed called.
  mockProject.VerifyAll;
end;
&lt;/pre&gt;
&lt;p&gt;
Previously the developer writing this test would have to provide the exact filename to be passed to the mocked Save method. As we don't know what the projects filename is going to be (in our example case), we would either have to;
1. Forgo doing this test.
2. Implement a project object to test with.
Both of these options are not ideal.
&lt;/p&gt;
&lt;p&gt;Parameter matchers resolve this situation. It is now simple to either restrict or broaden the parameters passed to mocked methods that will satisfy the expectation defined. To achieve this Delphi-Mocks offers eleven new functions; &lt;/p&gt;
&lt;pre class="brush:delphi; toolbar:true;"&gt;function It(const AParamIndx : Integer) : ItRec;
function It0 : ItRec;
function It1 : ItRec;
function It2 : ItRec;
function It3 : ItRec;
function It4 : ItRec;
function It5 : ItRec;
function It6 : ItRec;
function It7 : ItRec;
function It8 : ItRec;
function It9 : ItRec;
&lt;/pre&gt;
&lt;p&gt;The first "function It(const AParamIndx : Integer) : ItRec;" allows the developer to specify the index of the parameter they wish to set for the next expectation setup of a mock method. It(0) will refer to the first parameter, It(1) the second and so forth. Note that the reason for specifying the parameter index is that Delphi's parameter evaluation order is not defined, so we could not rely on the parameters being evaluated in order (which is what we did when we initially wrote this feature). Interestingly, with the 64 bit Delphi compiler, parameter evaluation does appear to happen in order, but we could not be certain this will always be the case.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The other ten functions It0 through to It9 are simply wrappers of the index call passing the index in their name. All these functions return an ItRec. The ItRec has the function structure;&lt;/p&gt;
&lt;pre class="brush:delphi; toolbar:true;"&gt;ItRec = record
  var
    ParamIndex : cardinal;
  constructor Create(const AParamIndex : Integer);
  function IsAny&amp;lt;T&amp;gt;() : T ;
  function Matches&amp;lt;T&amp;gt;(const predicate: TPredicate&amp;lt;T&amp;gt;) : T;
  function IsNotNil&amp;lt;T&amp;gt; : T;
  function IsEqualTo&amp;lt;T&amp;gt;(const value : T) : T;
  function IsInRange&amp;lt;T&amp;gt;(const fromValue : T; const toValue : T) : T;
  function IsIn&amp;lt;T&amp;gt;(const values : TArray&amp;lt;T&amp;gt;) : T; overload;
  function IsIn&amp;lt;T&amp;gt;(const values : IEnumerable&amp;lt;T&amp;gt;) : T; overload;
  function IsNotIn&amp;lt;T&amp;gt;(const values : TArray&amp;lt;T&amp;gt;) : T; overload;
  function IsNotIn&amp;lt;T&amp;gt;(const values : IEnumerable&amp;lt;T&amp;gt;) : T; overload;
  {$IFDEF SUPPORTS_REGEX} //XE2 or later
  function IsRegex(const regex : string; const options : TRegExOptions = []) : string;
  {$ENDIF}
end;
&lt;/pre&gt;
&lt;p&gt;Each of the functions creates a different matcher. For example the IsAny&amp;lt;T&amp;gt; will cause the expectation to be met when the parameter passed to the mock is of any value that has the type T. In the example above this type would be a string. You will also notice that each function returns the type T. This is so that each call can be placed within the mock methods call directly. Doing so helps with making sure parameter types match the testing value.&lt;/p&gt;
&lt;p&gt;IsEqualTo&amp;lt;T&amp;gt; requires that the parameter matches exactly to the value passed into the IsEqualTo&amp;lt;T&amp;gt;. This could be used to restrict the expectation to a tighter test of the functionality under test.&lt;/p&gt;
&lt;pre class="brush:delphi; toolbar:true;"&gt;//Match on the filename being "temp.txt" only.
mockProject.Setup.Expect.Once.When.Save(It(0).IsEqualTo&amp;lt;string&amp;gt;('temp.txt'));
//VERIFY - Make sure that save was indeed called.
mockProject.VerifyAll;
&lt;/pre&gt;
&lt;p&gt;In the future we are looking to provide &amp;ldquo;And&amp;rdquo;\&amp;rdquo;Or&amp;rdquo; operators. These operators might also live on the ItRec and allow combining with as many other matchers using the same type.&lt;/p&gt;
&lt;pre class="brush:delphi; toolbar:true;"&gt;//Match on the filename being "temp.txt" or "temp.doc" only.
mockProject.Setup.Expect.Once.When.Save(
       It(0).Or(It(0).IsEqualTo&amp;lt;string&amp;gt;('temp.txt'), 
                It(0).IsEqualTo&amp;lt;string&amp;gt;('temp.doc'));
//VERIFY - Make sure that save was indeed called.
mockProject.VerifyAll;
&lt;/pre&gt;
&lt;p&gt;There might be a better way to make the resulting code a bit cleaner. It would make the tests easier to read, instead of using regex which is also possible in this case. As a result we believe this would be a good edition to the library.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/VSoftTechnologies/Delphi-Mocks"&gt;Feel free to clone the repository from GitHub&lt;/a&gt;. If you have some time to spare submit a pull requests or two with your ideas/improvements. We believe this is a great little project worthy of some attention. Let us know what you think of the changes so far.&lt;/p&gt;</description><guid isPermaLink="false">737</guid></item><item><title>FinalBuilder 8 Released!</title><link>https://www.finalbuilder.com/resources/blogs/postid/733/finalbuilder-8-released</link><category>.NET,Delphi,FinalBuilder</category><pubDate>Thu, 20 Aug 2015 19:02:00 GMT</pubDate><description>&lt;p&gt;It's very nearly 5 years since FinalBuilder 7 was released. Since it's release we have shipped &lt;a href="/downloads/finalbuilder/finalbuilder-7-version-history"&gt;many official updates&lt;/a&gt;, nearly every update including new features or improvements. This program of continuous improvement has worked well, with customers not having to wait for major new versions to arrive to get support for new versions of Visual Studio or Delphi etc, but it has limited our ability to make major changes. So it's time for a new major version of FinalBuilder.&lt;/p&gt;

&lt;h2&gt;What's new in FinalBuilder 8&lt;/h2&gt;

&lt;h3&gt;IDE Themes&lt;/h3&gt;

&lt;p&gt;The IDE has two new themes, Dark and Light (yes, imaginatively named!). The IDE defaults to Dark on first run, however you can change the theme in the options quite easily.&lt;/p&gt;

&lt;table style="border: none; width: 100%;"&gt;
	&lt;tbody&gt;
		&lt;tr&gt;
			&lt;td style="width: 50%;"&gt;&lt;img alt="IDE Light theme" height="276" src="https://cdn.finalbuilder.com/blog/vincent/fb8-beta/fb8-ide-light-small.png" width="400" /&gt;&lt;/td&gt;
			&lt;td style="width: 50%;"&gt;&lt;img alt="IDE Light theme" height="276" src="https://cdn.finalbuilder.com/blog/vincent/fb8-beta/fb8-ide-dark-small.png" width="400" /&gt;&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;Debugger&lt;/h3&gt;

&lt;p&gt;One of the most asked for features now available in FinalBuilder 8, &lt;strong&gt;stepping into included projects&lt;/strong&gt;. In FinalBuilder 7 and earlier, you could only step over included projects, and wait for them to return. In FinalBuilder 8, you can step into the included project, if it is not already opened the IDE will open the project and switch to it automatically. To make this possible, there are now "Step Into" and "Step Over" functions. The Step into/over now also applies to targets (see below).&lt;br /&gt;
	&lt;br /&gt;
	Debugger breakpoints now have conditions :&lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;img alt="IDE Light theme" height="276" src="https://cdn.finalbuilder.com/blog/vincent/fb8-beta/fb8-breakpoint-props.png" style="text-align: center;" width="400" /&gt;&lt;/p&gt;

&lt;h3&gt;Actionlists renamed to Targets&lt;/h3&gt;

&lt;p&gt;ActionLists have been renamed to Targets. Targets can now also define dependencies, so you can for example define Clean, Build, Test, and have Test depend on Build. If you execute the Test target, and Build has not already been executed, it will be executed first before Test. Targets can be specified on the command line.&lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;img alt="IDE Light theme" height="276" src="https://cdn.finalbuilder.com/blog/vincent/fb8-beta/fb8-target-depend.png" style="text-align: center;" width="400" /&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;In FinalBuilder 7 and earlier, projects had a Main and an OnFailure (global error handler) actionlist. In FinalBuilder 8, projects just have a Default Target. Older projects will be imported such that the Main and OnFailure Targets are called from the Default Target inside a try/catch block.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;Run Target Action&lt;/h3&gt;

&lt;p&gt;You can now return values from Targets (ie out parameters) .&lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;img alt="IDE Light theme" height="276" src="https://cdn.finalbuilder.com/blog/vincent/fb8-beta/fb8-target-outparams.png" style="text-align: center;" width="400" /&gt;&lt;/p&gt;

&lt;h3&gt;New Help System&lt;/h3&gt;

&lt;p&gt;The help has moved online in the form of a wiki. This enables us to do inline help updates without needing to ship new builds. The new help is still being worked on, lots of screenshots are missing etc.. &lt;/p&gt;

&lt;h2&gt;Non Visible Changes&lt;/h2&gt;

&lt;h3&gt;Stepping Engine&lt;/h3&gt;

&lt;p&gt;The stepping engine was rewritten to enable stepping into included projects, and to enable target dependencies. This, work, together with the new variables architecture is where the bulk of effort/time was spent in the FinalBuilder 8 development cycle.&lt;/p&gt;

&lt;h3&gt;Variables Architecture&lt;/h3&gt;

&lt;p&gt;The variables architecture and the expression evaluator were rewritten to resolve several corner case issues that we were not able to resolve in FinalBuilder 7. The expression evaulator has a new parser that will allow us to more easily extend the syntax in the future. The User variable namespace was removed, it caused too many problems with projects not running under other users, not running on the build server etc. Use Project variables instead.&lt;/p&gt;

&lt;h3&gt;Core Messaging&lt;/h3&gt;

&lt;p&gt;Changes to the messaging has allowed us to improve the performance of the stepping engine and logging, with much less thread switching. This also improved the IDE performance.&lt;/p&gt;

&lt;h3&gt;CLR Hosting&lt;/h3&gt;

&lt;p&gt;The minimum CLR version is now .NET 4.0 (ie FinalBuilder requires .net 4.0 to be installed). FinalBuilder 8 also requires Powershell 3.0 or later.&lt;/p&gt;

&lt;h3&gt;Code Changes&lt;/h3&gt;

&lt;p&gt;In addition to the architectural changes, we also spent a lot of time refactoring the code, running static analysis tools over the source, looking for memory leaks, potential bugs etc. One of the results of this is reduced memory usage during a build compared to FB7. The FB8 IDE does use slightly more memory than the FB7 IDE at startup (mostly due to the heavy use of delphi generics), however the runtime memory usage is much lower.A large  part of the refactoring involved unit testing (we created a new &lt;a href="https://github.com/VSoftTechnologies/DUnitX" target="_blank"&gt;unit test framework&lt;/a&gt; to suite our needs!) and creating a suite of integration tests. &lt;/p&gt;

&lt;h3&gt;FBCmd&lt;/h3&gt;

&lt;p&gt;The command line parameters have changed to be more consistent and easier to specify. You can also specify one or more targets to execute (when not specified, the default target is executed).&lt;/p&gt;

&lt;h3&gt;New Project File Formats&lt;/h3&gt;

&lt;p&gt;FinalBuilder has used an xml file format since version 1, however a common complaint over the years, has been that it is difficult to diff file versions. FinalBuilder 8 has tackled this in two ways.&lt;/p&gt;

&lt;p&gt;A new DSL style project file format (.fbp8) is now the default format, it is very easy to diff.&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:true;"&gt;
project
begin
    projectid = {04710B72-066E-46E7-84C7-C04A0D8BFE18}
    target
    begin
        name = Default
        targetid = {E6DE94D6-5484-45E9-965A-DB69885AA5E2}
        rootaction
        begin
            action.group
            begin
                id = {D860420B-DE46-4806-959F-8A92A0C86429}
            end
        end
    end
end
&lt;/pre&gt;

&lt;p&gt;A new xml format (.fbx8), much less verbose than the old format.&lt;span style="white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;/p&gt;

&lt;pre class="brush:xml; toolbar:true;"&gt;
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;finalbuilder&gt;
    &lt;project&gt;
        &lt;projectid&gt;{6A717C24-D00F-4983-9FD0-148B2C609634}&lt;/projectid&gt;
        &lt;target&gt;
            &lt;name&gt;Default&lt;/name&gt;
            &lt;targetid&gt;{E6DE94D6-5484-45E9-965A-DB69885AA5E2}&lt;/targetid&gt;
            &lt;rootaction&gt;
                &lt;action.group&gt;
                    &lt;id&gt;{D860420B-DE46-4806-959F-8A92A0C86429}&lt;/id&gt;
                &lt;/action.group&gt;
            &lt;/rootaction&gt;
        &lt;/target&gt;
    &lt;/project&gt;
&lt;/finalbuilder&gt;
&lt;/pre&gt;

&lt;p&gt;Compressed project files (.fbz8) use the dsl format internally (compressed projects are just a zip file with a project.fbp8 inside it).&lt;/p&gt;

&lt;p&gt;The default project file encoding is now UTF-8, which is more version control friendly (some version control systems treat utf-16 as binaries).&lt;/p&gt;

&lt;h3&gt;New Actions&lt;/h3&gt;

&lt;p&gt;FinalBuilder 8 includes new actions for Chocolatey, Bower, NPM, Gulp, Grunt, Rake, Fake, Mocha, along with Redgate SQL Compare and SQL Data Compare actions.&lt;/p&gt;

&lt;p&gt;TFS 2015 XAML builds are also supported, a VSO task will be available soon (will be published on github).&lt;/p&gt;

&lt;h3&gt;License Key installation&lt;/h3&gt;

&lt;p&gt;We implemented a new more reliable trial mechanism for FinalBuilder 8, and made it simpler to install license keys. You can log into your account on our website directly in the FinalBuilder IDE and download &amp; install license keys&lt;/p&gt;

&lt;p&gt;The trial mechanism also uses license keys, which is more reliable than the mechansim used in earlier versions.&lt;/p&gt;

&lt;h3&gt;Where's my license key?&lt;/h3&gt;

&lt;p&gt;If you had an active Software Assurance Subscription for FinalBuilder 7 as of 20th August 2015, FinalBuilder 8 license keys were generated and added to your account today. You should have received an email notification.&lt;/p&gt;

&lt;h3&gt;How do I purchase an upgrade?&lt;/h3&gt;

&lt;p&gt;If you had a subscription for FinalBuilder 7, and it expired, you can upgrade by &lt;a href="/store/section/customers?page=subscriptions"&gt;Renewing your subscription&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have a license for FinalBuilder 6 or earlier, you can &lt;a href="/store/section/customers?page=upgrades"&gt;Purchase an upgrade here.&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Can I safely install FinalBuilder 8 on a machine with FinalBuilder x?&lt;/h3&gt;

&lt;p&gt;Yes. FinalBuilder 8 installs into a separate folder (as did all older versions of FinalBuilder).&lt;/p&gt;

&lt;h3&gt;Can FinalBuilder 8 open an run my old projects?&lt;/h3&gt;

&lt;p&gt;Yes, FinalBuilder 8 can open and run any projects from any earlier version of FinalBuilder. When you save the projects in FinalBuilder 8, it will save it as a FinalBuilder 8 project (new file).&lt;/p&gt;

&lt;h3&gt;Can older versions of FinalBuilder open FinalBuilder 8 projects?&lt;/h3&gt;

&lt;p&gt;No, FinalBuilder 8 projects use a different file format.&lt;/p&gt;

&lt;h3&gt;Does FinalBuilder 8 work with FinalBuilder Server 7?&lt;/h3&gt;

&lt;p&gt;No. FinalBuilder 8 does not work with FB Server 7, nor can it be made to work. FinalBuilder Server was discontinued over 2 years ago, if you need Continuous Integration then consider migrating to &lt;a href="/continua-ci"&gt;Continua CI.&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;I have questions!&lt;/h3&gt;

&lt;p&gt;Feel free to contact support@finalbuilder.com with any questions you might have.&lt;/p&gt;
</description><guid isPermaLink="false">733</guid></item><item><title>FinalBuilder 8 Beta</title><link>https://www.finalbuilder.com/resources/blogs/postid/729/finalbuilder-8-beta</link><category>.NET,Delphi,FinalBuilder,General</category><pubDate>Tue, 05 May 2015 20:06:36 GMT</pubDate><description>&lt;p&gt;It's almost 5 years since FinalBuilder 7 was released. Since it's release we have shipped &lt;a href="/downloads/finalbuilder/finalbuilder-7-version-history"&gt;44 official updates&lt;/a&gt;, nearly every update including new features or improvements. This program of continuous improvement has worked well, with customers not having to wait for major new versions to arrive to get support for new versions of Visual Studio or Delphi etc, but it has limited our ability to make major changes. So it's time for a new major version of FinalBuilder. &lt;/p&gt;

&lt;h2&gt;What's new in FinalBuilder 8&lt;/h2&gt;

&lt;h3&gt;IDE Themes&lt;/h3&gt;

&lt;p&gt;The IDE has two new themes, Dark and Light (yes, imaginatively named!). The IDE defaults to Dark on first run, however you can change the theme in the options quite easily. The themes are still a work in progress, we are waiting on an update from a third party control vendor to resolve some issues.&lt;/p&gt;

&lt;table style="border: none; width: 100%;"&gt;
	&lt;tbody&gt;
		&lt;tr&gt;
			&lt;td style="width: 50%;"&gt;&lt;img alt="IDE Light theme" height="276" src="https://cdn.finalbuilder.com/blog/vincent/fb8-beta/fb8-ide-light-small.png" width="400" /&gt;&lt;/td&gt;
			&lt;td style="width: 50%;"&gt;&lt;img alt="IDE Light theme" height="276" src="https://cdn.finalbuilder.com/blog/vincent/fb8-beta/fb8-ide-dark-small.png" width="400" /&gt;&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;Debugger&lt;/h3&gt;

&lt;p&gt;One of the most asked for features now available in FinalBuilder 8, &lt;strong&gt;stepping into included projects&lt;/strong&gt;. In FinalBuilder 7 and earlier, you could only step over included projects, and wait for them to return. In FinalBuilder 8, you can step into the included project, if it is not already opened the IDE will open the project and switch to it automatically. To make this possible, there are now "Step Into" and "Step Over" functions. The Step into/over now also applies to targets (see below).&lt;br /&gt;
	&lt;br /&gt;
	Debugger breakpoints now have conditions :&lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;img alt="IDE Light theme" height="276" src="https://cdn.finalbuilder.com/blog/vincent/fb8-beta/fb8-breakpoint-props.png" style="text-align: center;" width="400" /&gt;&lt;/p&gt;

&lt;h3&gt;Actionlists renamed to Targets&lt;/h3&gt;

&lt;p&gt;ActionLists have been renamed to Targets. Targets can now also define dependencies, so you can for example define Clean, Build, Test, and have Test depend on Build. If you execute the Test target, and Build has not already been executed, it will be executed first before Test. Targets can be specified on the command line.&lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;img alt="IDE Light theme" height="276" src="https://cdn.finalbuilder.com/blog/vincent/fb8-beta/fb8-target-depend.png" style="text-align: center;" width="400" /&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;In FinalBuilder 7 and earlier, projects had a Main and an OnFailure (global error handler) actionlist. In FinalBuilder 8, projects just have a Default Target. Older projects will be imported such that the Main and OnFailure Targets are called from the Default Target inside a try/catch block.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;Run Target Action&lt;/h3&gt;

&lt;p&gt;You can now return values from Targets (ie out parameters) .&lt;/p&gt;

&lt;p style="text-align: center;"&gt;&lt;img alt="IDE Light theme" height="276" src="https://cdn.finalbuilder.com/blog/vincent/fb8-beta/fb8-target-outparams.png" style="text-align: center;" width="400" /&gt;&lt;/p&gt;

&lt;h3&gt;New Help System&lt;/h3&gt;

&lt;p&gt;The help has moved online in the form of a wiki. This enables us to do inline help updates without needing to ship new builds. The new help is still being worked on, lots of screenshots are missing etc.. &lt;/p&gt;

&lt;h2&gt;Non Visible Changes&lt;/h2&gt;

&lt;h3&gt;Stepping Engine&lt;/h3&gt;

&lt;p&gt;The stepping engine was rewritten to enable stepping into included projects, and to enable target dependencies. This, work, together with the new variables architecture is where the bulk of effort/time was spent in the FinalBuilder 8 development cycle.&lt;/p&gt;

&lt;h3&gt;Variables Architecture&lt;/h3&gt;

&lt;p&gt;The variables architecture and the expression evaluator were rewritten to resolve several corner case issues that we were not able to resolve in FinalBuilder 7. The expression evaulator has a new parser that will allow us to more easily extend the syntax in the future. The User variable namespace was removed, it caused too many problems with projects not running under other users, not running on the build server etc. Use Project variables instead.&lt;/p&gt;

&lt;h3&gt;Core Messaging&lt;/h3&gt;

&lt;p&gt;Changes to the messaging has allowed us to improve the performance of the stepping engine and logging, with much less thread switching. This also improved the IDE performance.&lt;/p&gt;

&lt;h3&gt;CLR Hosting&lt;/h3&gt;

&lt;p&gt;The minimum CLR version is now .NET 4.0 (ie FinalBuilder requires .net 4.0 to be installed).&lt;/p&gt;

&lt;h3&gt;Code Changes&lt;/h3&gt;

&lt;p&gt;In addition to the architectural changes, we also spent a lot of time refactoring the code, running static analysis tools over the source, looking for memory leaks, potential bugs etc. One of the results of this is reduced memory usage during a build compared to FB7. The FB8 IDE does use slightly more memory than the FB7 IDE at startup (mostly due to the heavy use of delphi generics), however the runtime memory usage is much lower.A large  part of the refactoring involved unit testing (we created a new &lt;a href="https://github.com/VSoftTechnologies/DUnitX" target="_blank"&gt;unit test framework&lt;/a&gt; to suite our needs!) and creating a suite of integration tests. &lt;/p&gt;

&lt;h3&gt;FBCmd&lt;/h3&gt;

&lt;p&gt;The command line parameters have changed to be more consistent and easier to specify. You can also specify one or more targets to execute (when not specified, the default target is executed).&lt;/p&gt;

&lt;h3&gt;New Project File Formats&lt;/h3&gt;

&lt;p&gt;FinalBuilder has used an xml file format since version 1, however a common complaint over the years, has been that it is difficult to diff file versions. FinalBuilder 8 has tackled this in two ways.&lt;/p&gt;

&lt;p&gt;A new DSL style project file format (.fbp8) is now the default format, it is very easy to diff.&lt;/p&gt;

&lt;pre class="brush:delphi; toolbar:true;"&gt;
project
begin
    projectid = {04710B72-066E-46E7-84C7-C04A0D8BFE18}
    target
    begin
        name = Default
        targetid = {E6DE94D6-5484-45E9-965A-DB69885AA5E2}
        rootaction
        begin
            action.group
            begin
                id = {D860420B-DE46-4806-959F-8A92A0C86429}
            end
        end
    end
end
&lt;/pre&gt;

&lt;p&gt;A new xml format (.fbx8), much less verbose than the old format.&lt;span style="white-space: pre-wrap;"&gt; &lt;/span&gt;&lt;/p&gt;

&lt;pre class="brush:xml; toolbar:true;"&gt;
&lt;!--?xml version="1.0" encoding="UTF-8"?--&gt;
&lt;finalbuilder&gt;
    &lt;project&gt;
        &lt;projectid&gt;{6A717C24-D00F-4983-9FD0-148B2C609634}&lt;/projectid&gt;
        &lt;target&gt;
            &lt;name&gt;Default&lt;/name&gt;
            &lt;targetid&gt;{E6DE94D6-5484-45E9-965A-DB69885AA5E2}&lt;/targetid&gt;
            &lt;rootaction&gt;
                &lt;action.group&gt;
                    &lt;id&gt;{D860420B-DE46-4806-959F-8A92A0C86429}&lt;/id&gt;
                &lt;/action.group&gt;
            &lt;/rootaction&gt;
        &lt;/target&gt;
    &lt;/project&gt;
&lt;/finalbuilder&gt;
&lt;/pre&gt;

&lt;p&gt;Compressed project files (.fbz8) use the dsl format internally (compressed projects are just a zip file with a project.fbp8 inside it).&lt;/p&gt;

&lt;p&gt;The default project file encoding is now UTF-8, which is more version control friendly (some version control systems treat utf-16 as binaries).&lt;/p&gt;

&lt;h3&gt;New Actions&lt;/h3&gt;

&lt;p&gt;There are no new actions at the moment, although several are in development, they will be added to the beta builds as they are completed. &lt;/p&gt;

&lt;h3&gt;How do I get the Beta?&lt;/h3&gt;

&lt;p&gt;Links to the beta downloads will be published to the &lt;a href="https://www.finalbuilder.com/downloads/finalbuilder"&gt;FinalBuilder Downloads&lt;/a&gt; page. &lt;br /&gt;
	 &lt;/p&gt;

&lt;h3&gt;What if I find a bug?&lt;/h3&gt;

&lt;p&gt;We have created a Beta forum on our forums, or you can email support (please added Beta to the subject). When reporting an issue, be sure to include the beta build number and details about your environment. Please test with the latest beta build before reporting bugs. &lt;br /&gt;
	&lt;br /&gt;
	We are particularly keen for people to load up their existing projects from older (ie 7 or earlier) versions of FinalBuilder, save them in FB8 format, and load them again and confirm that everything loaded ok. &lt;br /&gt;
	 &lt;/p&gt;

&lt;h3&gt;When will it be released?&lt;/h3&gt;

&lt;h3&gt; &lt;/h3&gt;

&lt;p&gt;When it's ready ;)&lt;/p&gt;
</description><guid isPermaLink="false">729</guid></item><item><title>Introducing VSoft.CommandLineParser for Delphi</title><link>https://www.finalbuilder.com/resources/blogs/postid/719/introducing-vsoftcommandline-for-delphi</link><category>Delphi,Open Source</category><pubDate>Sat, 26 Jul 2014 14:20:12 GMT</pubDate><description>&lt;h2&gt;Command line parsing&lt;/h2&gt;
&lt;p&gt;Pretty much every delphi console application I have ever written or worked on had command line options, and every one of the projects tried different ways for defining and parsing the supplied options.
Whilst working on DUnitX recently, I needed to add some command line options, and wanted to find a nice way to add them and make it easy to add more in the future. The result is &lt;a href="https://github.com/VSoftTechnologies/VSoft.CommandLineParser" target="_blank"&gt;VSoft.CommandLineParser&lt;/a&gt;
(copies of which are included with the latest DUnitX).&lt;/p&gt;
&lt;h3&gt;Defining Options&lt;/h3&gt;
&lt;p&gt;One of the things I really wanted, was to have the parsing totally decoupled from definition and the storage of the options values. Options are defined by registering them with the TOptionsRegistry, via
TOptionsRegistry.RegisterOption&amp;lt;T&amp;gt; - whilst it makes use of generics, only certain types can be used, the types are checked at runtime, as generic constraints are not flexible enough to specify
which types we allow at compile time. Valid types are string, integer, boolean, enums &amp;amp; sets and floating point numbers. &lt;/p&gt;
&lt;p&gt;Calling RegisterOption will return a definition object which implements IOptionDefinition. This definition object allows you to set various settings (such as Required).
When registering the option, you specify the long option name, the short option name, help text (will be used when showing the usage) and a TProc&amp;lt;T&amp;gt; anonymous method that will take the parsed value as a parameter.&lt;/p&gt;
&lt;pre class="brush:delphi; toolbar:true;"&gt;procedure ConfigureOptions;
var
  option : IOptionDefintion;
begin
  option := TOptionsRegistry.RegisterOption&amp;lt;string&amp;gt;('inputfile','i','The file to be processed',
    procedure(value : string)
    begin
        TSampleOptions.InputFile := value;
    end);
  option.Required := true;

  option := TOptionsRegistry.RegisterOption&amp;lt;string&amp;gt;('outputfile','o','The processed output file',
    procedure(value : string)
    begin
        TSampleOptions.OutputFile := value;
    end);
  option.Required := true;

  option := TOptionsRegistry.RegisterOption&amp;lt;boolean&amp;gt;('mangle','m','Mangle the file!',
    procedure(value : boolean)
    begin
        TSampleOptions.MangleFile := value;
    end);
  option.HasValue := False;

  option := TOptionsRegistry.RegisterOption&amp;lt;boolean&amp;gt;('options','','Options file',nil);
  option.IsOptionFile := true;
end;
&lt;/pre&gt;
&lt;p&gt;For options that are boolean in nature, ie they have do not value part, the value passed to the anonymous method will be true if the option was specified, otherwise the anonymous method will not be called. The 'mangle' option in the above example shows this scenario. &lt;/p&gt;
&lt;p&gt;You can also specify that an option is a File, by setting the IsOptionFile property on the option definition. This tells the parser the value will be a file, which contains other options to be parsed (in the same format as the command line). This is useful for working around windows command line length limitations.&lt;/p&gt;
&lt;p&gt;Currently the parser will accept&lt;br /&gt;
-option:value&lt;br /&gt;
--option:value&lt;br /&gt;
/option:value
&lt;/p&gt;
&lt;p&gt;Note the : delimiter between the option and the value.&lt;/p&gt;
&lt;p&gt;Unnamed parameters are registered via the TOptionsRegistry.RegisterUnNamedOption&amp;lt;T&amp;gt; method. Unlike named options, unnamed options are positional, but only when more than one is registered, as they will
be passed to the anonymous methods in the order they are registered.&lt;/p&gt;
&lt;h3&gt;Parsing the options.&lt;/h3&gt;
&lt;p&gt;Parsing the options is as simple as calling TOptionsRegistry.Parse, which returns a ICommandLineParseResult object. Check the HasErrors property to see if the options were valid, the ErrorText property has the parser error messages.&lt;/p&gt;
&lt;h3&gt;Printing Usage&lt;/h3&gt;
&lt;p&gt;If the parser reports errors, then typically you would show the user what the valid options are and exit the application, e.g:&lt;/p&gt;
&lt;pre class="brush:delphi; toolbar:true;"&gt;    parseresult := TOptionsRegistry.Parse;
    if parseresult.HasErrors then
    begin
      Writeln(parseresult.ErrorText);
      Writeln('Usage :');
      TOptionsRegistry.PrintUsage(
        procedure(value : string)
        begin
          Writeln(value);
        end);
    end
    else
        ..start normal execution here
&lt;/pre&gt;
&lt;p&gt;The TOptionsRegistry.PrintUsage makes it easy to print the usage to the command line.&lt;/p&gt;
&lt;p&gt;When I started working on this library, I found some really complex libraries (mostly .net) out there with a lot of options, but I decided to keep mine as simple as possible and only cover off the scenarios I need right now. So it's entirely possible this doesn't do everything people might need, but it's pretty easy to extend. The &lt;a href="https://github.com/VSoftTechnologies/VSoft.CommandLineParser" target="_blank"&gt;VSoft.CommandLineParser&lt;/a&gt; library (just three units) is open source and available on Github, with a sample application and unit tests (DUnitX) included.&lt;/p&gt;</description><guid isPermaLink="false">719</guid></item></channel></rss>