Skip to content
pb-diff Help

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.

pb-diff Compare Summary with orders.pbl from release 1.5 on the Old side and the orders.pbl folder of the same release converted to a PowerBuilder 2025 Solution on the New side. Every object is listed as unchanged.
Release 1.5 as a classic library on the Old side and as a PowerBuilder 2025 Solution PBL folder on the New side: every object compares identical, because the export header and the comment line are framing, not content. Select the image to view it at full size.

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.

pb-diff Compare Summary of two PowerBuilder 2025 Solutions, release 1.5 and release 1.6: the UTF-8 sources of the orders.pbl folders are paired by object, with n_order_service and n_invoice_export modified and the other objects unchanged, and the project order_desk.pbproj is modified while the solution order_desk.pbsln is unchanged.
Two Solution folders compared: pb-diff walks the PBL folders, pairs the sources by object, compares the solution and the project beside them, and leaves the compiler's output folders alone. Select the image to view it at full size.

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.

pb-diff comparing n_order_service from two PowerBuilder 2025 Solution releases. The function of_price is selected, and the panes show the new quantity threshold and discount rate highlighted within the changed line.
Two UTF-8 Solution sources compared exactly like exports. A merge saved over one of them stays UTF-8, so the Solution still builds. Select the image to view it at full size.

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.