PowerBuilder 2025 Solutions
PowerBuilder 2025 introduced the Solution format beside the classic workspace. pb-diff compares, reports on and merges the object sources of PowerBuilder 2025 Solutions, as PowerBuilder 2025 and later write them, and a source it merges builds in the Solution. This was verified on PowerBuilder 2025 R2 build 6430. PowerBuilder 2025 R1 writes the same format and is covered on that basis: Appeon documents no change to it in R2. Appeon offers the Solution format in the CloudPro and Professional editions of PowerBuilder 2025, not in Standard.
What a Solution looks like to pb-diff
Convert Workspace to Solution turns
app.pbw into app.pbsln, app.pbt
into app.pbproj, and each library a.pbl into a
folder called a.pbl. The folder holds one
source file per object, such as w_main.srw, in place of the
binary library:
| In the Solution | What pb-diff does with it |
|---|---|
a.pbl\w_main.srw and the other .sr*
files |
Parses and compares them as PowerBuilder objects, and merges them.
They are UTF-8, with a byte-order mark unless pb.ini sets
DefaultEncoding=64. |
a.pbl\w_main.bin |
The binary data of an OLE control, which an export would append to
the .srw. Compared as binary: the same or different, never
as text. |
app.pbsln, app.pbproj |
The solution's projects, and each project's settings, deploy configurations and library list: compared and merged as build files, and taken from a folder with the sources. See Project and build files. |
a.pbl\a.pblmeta, a.pbl\a.pra |
The library comment and the application's fonts and icon. Compared as text when named; not certified. |
.pb\ and build\ beside the
.pbproj |
The compiler's output. pb-diff never walks into them. |
_BackupFiles\ |
What the conversion kept of the old workspace. pb-diff never walks into it. |
Every object source is the object's library source with two
differences that pb-diff takes into account. There is no
$PBExportHeader$ line, and the object comment is a first
line reading //objectcomments <text> instead of
$PBExportComments$<text>.
Comparing Solution sources
Compare two .sr* files from two Solutions exactly as you
would compare two exports: in New Comparison, from the
command line, or from your source-control client. Compare two versions
of a whole Solution in a File
Selection: add one Solution folder, or one PBL folder, to Old and
the other to New, and choose Compare. Naming the two
folders on the command line,
pb-diff.exe <old> <new>, opens the same
summary. New Comparison takes files, not folders. The summary pairs
every object by name, skips the compiler's folders and the backup, and
lists each .bin companion as its own row, compared by
content and with nothing to drill into.
You can also compare a classic library with a Solution. This is the
comparison to run when you migrate: give the last release's
.pbl as Old and the new Solution's PBL folder as New. The
export header and the two spellings of the object comment are framing,
not content, so an object that did not change compares identical. One
difference remains for a window with an OLE control, because the library
carries its binary data inside the object and the Solution keeps it in
the .bin.
A PBL folder is a folder, not a library file. The headless
pb-diff-cli tool compares one object by object, against
another or against a library, with compare-lib and the
summary and summary-changes reports, as the
desktop application does. Every other command refuses a PBL folder with
exit code 2 and a message saying so: to compare, parse or merge one
object, name its .sr* file inside the folder.
Merging Solution sources
A merged Solution source stays in the Solution's own form. The
two-way merge writes the New side back, and the three-way merge and
pb-diff-cli merge3 write the Base. When that file is UTF-8,
the saved file is UTF-8 too, with or without a byte-order mark exactly
as it was. It gains no $PBExportHeader$ line. Every line
the merge did not decide is copied byte for byte, including the lines
PowerBuilder itself ends with a bare LF. A merge that decided nothing
reproduces the file exactly, and Git shows only the lines you
changed.
This matters because the Solution compiler reads UTF-8 only. A
UTF-16LE file in a PBL folder, which is what the Library painter's
export format and every other merge write, fails the build with
UTF-16 (LE) byte order mark detected ... but encoding is not supported.
When you merge a library export into a Solution, put the Solution file
on the side the merge writes: New in a two-way merge, Base in a
three-way merge.
After saving, the merged file is simply a file in the PBL folder.
There is nothing to import. Let PowerBuilder pick it up, which may take
reopening the Solution, and build it in the IDE or with PBAutoBuild250
before committing. The consistency rules of every merge apply unchanged:
restoring a control rewrites its .create and
.destroy calls and its place in the control list. See How merging works.
Try it: a migration and a release
solution/release-1.5 is release 1.5 of Order Desk
converted to a Solution, and solution/release-1.6 is the
next release; see The Order Desk
examples. Start with the migration: open File ▸ New File
Selection, add libraries/release-1.5/orders.pbl to
Old and the PBL folder solution/release-1.5/orders.pbl to
New, and choose Compare. Every object compares
identical, although no file is byte for byte the same as the library
entry it came from: the Solution sources are UTF-8 and carry
//objectcomments instead of an export header.
Then compare the two Solution folders,
solution/release-1.5 and solution/release-1.6,
the same way, or start pb-diff with them:
pb-diff.exe solution\release-1.5 solution\release-1.6.
pb-diff walks the PBL folders and pairs the sources by object. In
release 1.6, n_order_service changed its volume discount
and n_invoice_export names its file with the date.
Double-click n_order_service.sru, or compare the two
source files directly, and select of_price. A Solution
source is compared exactly like an export.
The CLI compares the sources and merges them; the merged file stays UTF-8 (migration, release, merge, merged file):
pb-diff-cli compare libraries/release-1.5/orders.pbl!n_order_service.sru solution/release-1.5/orders.pbl/n_order_service.sru --format json
pb-diff-cli compare solution/release-1.5/orders.pbl/n_order_service.sru solution/release-1.6/orders.pbl/n_order_service.sru --format json
pb-diff-cli merge3 solution/release-1.6/orders.pbl/n_order_service.sru solution/release-1.5/orders.pbl/n_order_service.sru solution/release-1.5/orders.pbl/n_order_service.sru --output solution/merged/n_order_service.sru --format json
The migration returns exit code 0, the release comparison 1, and the merge 0: File1 changed what the Base had and File2 did not, so File1's change is taken and nothing conflicts. A PBL folder is not a library file, so the CLI refuses one with exit code 2 (result):
pb-diff-cli info solution/release-1.5/orders.pbl --format json
Source control and the IDE
A Solution works with PowerBuilder's native Git and SVN integration
only; Appeon does not support the PBNative or SCC API there. The
Diff Viewer set-up in From the
PowerBuilder IDE: see what you changed is the same for a Solution as
for a workspace, and so are the Tortoise and other-client configurations. When
a client hands pb-diff a file whose name carries no type,
-Detect H types a Solution source from its content. The
exception is an object inherited from another of your objects, such as
w_sheet from w_basesheet: nothing in that file says it is a
window. Keep the extension in the name for those, or use
-Detect F when the client appends a suffix.