Chilkat for Progress OpenEdge
use the Chilkat .NET assembly from ABL's built-in .NET support
OpenEdge 11.x, 12.x, and 13.x on Windows, 32-bit or 64-bit, using ABL's .NET class access
· GUI client, character and batch clients, and PAS for OpenEdge · this page focuses on the Chilkat
.NET Framework 4.8 assembly · for Linux or modern .NET (-clrnetcore), see
Linux and modern .NET
There is no separate OpenEdge package to install. ABL (formerly Progress 4GL) can create and call .NET
objects directly, so the standard Chilkat .NET assembly (ChilkatDotNet48.dll) gives your ABL code
the Chilkat .NET API: HTTP/REST, JSON, email, FTP, SFTP/SSH, Zip, PDF, digital signatures, encryption, and
everything else. You list the assembly once in your project's assemblies.xml, and then Chilkat
classes are ordinary ABL types: NEW Chilkat.Http() creates an object, http:QuickGetStr(url)
calls a method, and http:LastErrorText reads a property. This works in the GUI client, in character and
batch sessions, and in PAS for OpenEdge agents, so the same code serves a desktop screen, a nightly batch job, or a
REST service.
The 60-second version
- Find out whether your OpenEdge session is 32-bit or 64-bit (see below) and download the matching Chilkat .NET 4.8 assembly.
- Unzip it and copy
ChilkatDotNet48.dllinto your project folder (or the folder you pass with-assemblies). - Add it to
assemblies.xmlas a local assembly (Developer Studio: project Properties » Progress OpenEdge » Assemblies » Add), paste the sample procedure, and run it.
The walkthrough below goes through each step.
First: match OpenEdge's bitness
The Chilkat DLL's bitness must match the OpenEdge process, not Windows. The Chilkat .NET assembly is a mixed-mode assembly: it has a managed .NET API, but the core inside it is native code. A 32-bit process can only load the 32-bit (win32) DLL, and a 64-bit process can only load the 64-bit (x64) DLL. OpenEdge ships both 32-bit and 64-bit clients, and many sites still run 32-bit GUI clients on 64-bit Windows. If you load the wrong DLL, the first Chilkat call fails with "An attempt was made to load a program with an incorrect format".
To check which one you have, use any of these:
- In ABL, run
MESSAGE PROCESS-ARCHITECTURE VIEW-AS ALERT-BOX.It shows32or64. - The executable:
prowin.exeis the 64-bit GUI client andprowin32.exeis the 32-bit GUI client. Character and batch sessions (_progres.exe) and PAS for OpenEdge agents have the bitness of the OpenEdge installation. - Windows Task Manager: a 32-bit process shows as
prowin32.exe (32 bit).
If you have both kinds of session, for example a 32-bit GUI client and 64-bit PAS for OpenEdge, each one needs its own copy of the matching DLL in its own assemblies directory.
Download
Download the 64-bit build for 64-bit OpenEdge and the 32-bit build for 32-bit OpenEdge. These are the full-version downloads, and they are fully functional for a 30-day evaluation. Other .NET Framework versions and the NuGet packages are on the Chilkat .NET download page. For OpenEdge 11 and later, the 4.8 build above is the one to use.
-clrnetcore, OpenEdge 11
and later run ABL's .NET support on the .NET Framework 4 runtime, and .NET Framework 4.8 is an in-place update of that
runtime. So for OpenEdge 11 and later on Windows, use the Chilkat 4.8 build on machines where .NET Framework 4.8 is
installed and supported for your OpenEdge release. For older OpenEdge and Windows combinations, confirm the supported
.NET Framework version in Progress's Platform & Product Availability Guide. .NET Framework 4.8 is already included in Windows 10 (version 1903 and later), Windows 11, and Windows Server 2022 and later.
On an older system, install .NET Framework 4.8 from Microsoft (a free download). OpenEdge 10.2B runs on the
older .NET 3.5 runtime and needs the Chilkat .NET 2.0 build from the
.NET download page instead.
.zip, choose Properties, and if the
dialog shows an Unblock checkbox, check it and click OK. Otherwise Windows marks every extracted file
as "downloaded from the Internet", and the .NET runtime inside OpenEdge can refuse to load a marked assembly
(see Troubleshooting).
Walkthrough: unlock Chilkat and fetch a URL
This walkthrough builds an ABL procedure that does the same thing as these few lines of C#:
Chilkat.Global glob = new Chilkat.Global();
bool success = glob.UnlockBundle("Anything for 30-day trial");
if (!success) { /* show glob.LastErrorText */ }
Chilkat.Http http = new Chilkat.Http();
string s = http.QuickGetStr("https://www.chilkatsoft.com/helloworld.txt");
if (!http.LastMethodSuccess) { /* show http.LastErrorText */ }
- Put the DLL in the assemblies directory. ABL finds third-party .NET assemblies in its
assemblies directory, the folder that holds
assemblies.xml. By default that is the session's working directory, which in Progress Developer Studio for OpenEdge is the project's top-level folder. To use another folder, start the session with the-assembliesstartup parameter, for example-assemblies C:\myapp\assemblies. CopyChilkatDotNet48.dllinto that folder. - Add the assembly to
assemblies.xml. Every .NET assembly your ABL code uses must be listed inassemblies.xml, both to compile and to run. Let the tools write the entry for you:- Progress Developer Studio for OpenEdge: right-click the project and choose
, then click
Add. On the Local Assemblies tab, browse to
ChilkatDotNet48.dllin the assemblies directory, add it, and click OK. (You can also right-click Referenced Assemblies in the Project Explorer and choose Add Assembly References.) - Without Developer Studio: run the Assembly References Tool (
proasmref.exein%DLC%\bin) and add the DLL the same way.
assemblies.xmllooks like this:<?xml version="1.0" encoding="utf-8"?> <references xsi:noNamespaceSchemaLocation="assemblies.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <assembly name="ChilkatDotNet48, Version=11.6.0.0, Culture=neutral, PublicKeyToken=eb5fc1fc52ef09bd"/> </references>
TheVersionis the version of the DLL you downloaded. The public key tokeneb5fc1fc52ef09bdis the same for every Chilkat .NET release. To print the exact full name of your copy of the DLL, run this in PowerShell:[System.Reflection.AssemblyName]::GetAssemblyName("C:\myapp\assemblies\ChilkatDotNet48.dll").FullName - Progress Developer Studio for OpenEdge: right-click the project and choose
, then click
Add. On the Local Assemblies tab, browse to
- Write the procedure. Create
chilkat_hello.pin the project with this code:/* chilkat_hello.p : unlock Chilkat and fetch a URL */ USING Chilkat.* FROM ASSEMBLY. DEFINE VARIABLE glob AS Chilkat.Global NO-UNDO. DEFINE VARIABLE http AS Chilkat.Http NO-UNDO. DEFINE VARIABLE response AS LONGCHAR NO-UNDO. /* Unlock once at startup. Any string starts the 30-day trial. */ glob = NEW Chilkat.Global(). IF NOT glob:UnlockBundle("Anything for 30-day trial") THEN DO: MESSAGE glob:LastErrorText VIEW-AS ALERT-BOX ERROR. RETURN. END. http = NEW Chilkat.Http(). response = http:QuickGetStr("https://www.chilkatsoft.com/helloworld.txt"). IF NOT http:LastMethodSuccess THEN DO: MESSAGE http:LastErrorText VIEW-AS ALERT-BOX ERROR. RETURN. END. MESSAGE STRING(response) VIEW-AS ALERT-BOX INFORMATION.Chilkat classes are in theChilkatnamespace. TheUSINGstatement is optional when you write the full type names, as this page does. - Run it. In Developer Studio, right-click the procedure and choose . From a command prompt, run it with the client that matches the DLL's bitness:
prowin.exe -p chilkat_hello.p -assemblies C:\myapp\assemblies _progres.exe -b -p chilkat_hello.p -assemblies C:\myapp\assemblies
The message showsHello World!. In a batch session (-b),MESSAGEwrites to standard output instead of an alert box.
UnlockBundle sets a flag in memory that lasts for the life of the
process. There is no license file, and it doesn't contact a server. Call it once at startup, for example in your
application's startup procedure. In PAS for OpenEdge, a good place is the agent's session startup procedure
(sessionStartupProc), so every ABL session in the agent is unlocked before it handles requests.
Working with the Chilkat API in ABL
| In C# you'd write… | In ABL you write… |
|---|---|
Chilkat.Http http = new Chilkat.Http(); | DEFINE VARIABLE http AS Chilkat.Http NO-UNDO.http = NEW Chilkat.Http(). |
http.QuickGetStr(url) | http:QuickGetStr(url). A method whose return value you don't
need can be called as a statement, e.g. json:UpdateString("name", "Widget"). |
http.ConnectTimeout = 10; or x = http.LastErrorText; | http:ConnectTimeout = 10.
or x = http:LastErrorText. |
bool, int, long, string | LOGICAL, INTEGER,
INT64, and CHARACTER or LONGCHAR. ABL converts between them automatically. Use
LONGCHAR for anything that can be larger than about 32 KB, such as an HTTP response body or a JSON
document, because a CHARACTER value is limited to 32 KB. |
A method that takes a Chilkat object, e.g. http.HttpJson(verb, url, json, contentType, resp) |
Create the JsonObject and HttpResponse with NEW and pass the object
references (see the example below). |
byte[] arguments and return values | Prefer the Chilkat methods that work with a
Chilkat.BinData object or with encoded strings (base64, hex). ABL doesn't convert a .NET byte array
to a MEMPTR automatically. |
| Disposal / end of scope | Nothing to do. When no ABL variable refers to a Chilkat object anymore, ABL releases it and the .NET garbage collector frees it. |
The Chilkat reference documentation and examples for C# apply directly: the class, method, and property names
are the same in ABL. Chilkat methods don't throw exceptions for ordinary failures. They return
FALSE (or set LastMethodSuccess to FALSE), and LastErrorText
explains why. So check the return value or LastMethodSuccess as the examples on this page do, rather
than relying on CATCH or NO-ERROR.
Example: POST JSON to a REST API
This procedure builds a JSON body, POSTs it, and reads a value from the JSON response. It shows Chilkat objects
being passed as arguments and a large string going into a LONGCHAR. (httpbin.org is a public test
service that echoes the request back.)
/* chilkat_rest.p : POST JSON and parse the JSON response */
DEFINE VARIABLE http AS Chilkat.Http NO-UNDO.
DEFINE VARIABLE json AS Chilkat.JsonObject NO-UNDO.
DEFINE VARIABLE resp AS Chilkat.HttpResponse NO-UNDO.
DEFINE VARIABLE jsonResp AS Chilkat.JsonObject NO-UNDO.
DEFINE VARIABLE body AS LONGCHAR NO-UNDO.
/* Assumes Chilkat was already unlocked at startup (see the walkthrough). */
json = NEW Chilkat.JsonObject().
json:UpdateString("name", "Widget").
json:UpdateInt("qty", 5).
http = NEW Chilkat.Http().
http:ConnectTimeout = 10. /* seconds */
http:ReadTimeout = 30. /* seconds */
resp = NEW Chilkat.HttpResponse().
IF NOT http:HttpJson("POST", "https://httpbin.org/post", json, "application/json", resp) THEN DO:
MESSAGE http:LastErrorText VIEW-AS ALERT-BOX ERROR.
RETURN.
END.
body = resp:BodyStr.
IF resp:StatusCode <> 200 THEN DO:
MESSAGE "HTTP status" resp:StatusCode VIEW-AS ALERT-BOX ERROR.
RETURN.
END.
jsonResp = NEW Chilkat.JsonObject().
jsonResp:Load(body).
MESSAGE "The server received name =" jsonResp:StringOf("json.name")
VIEW-AS ALERT-BOX INFORMATION.
For many more tasks, the Chilkat C# examples
translate line for line: replace new with NEW, . with :
for members, and ; with . at the end of each statement.
Progress events
Chilkat's progress events (PercentDone, AbortCheck, ProgressInfo, and
others) are .NET events. Progress documents that character clients, batch clients, and AppServer / PAS for OpenEdge
agents cannot handle .NET events, and most ABL code doesn't need them. Call the methods synchronously, and set a
timeout property such as ConnectTimeout or ReadTimeout where the class has one. In the GUI
client, .NET events are subscribed to with ABL's Subscribe() syntax; see Progress's documentation on
handling .NET events.
Deploying your application
On each machine that runs your ABL code with Chilkat, whether a user's PC or a PAS for OpenEdge server:
| Requirement | Notes |
|---|---|
ChilkatDotNet48.dll and assemblies.xml | Both go in the assemblies directory: the
session's working directory, or the folder named by -assemblies. Deploy the same
assemblies.xml you compiled with. |
| Same bitness | Deploy the x64 DLL for 64-bit sessions and the win32 DLL for 32-bit sessions (see above). |
| .NET Framework 4.8 | Included with Windows 10 (version 1903 and later), Windows 11, and Windows Server 2022 and later. On older Windows versions, install it from Microsoft. |
| Visual C++ runtime | The Chilkat .NET 4.8 assembly needs the Microsoft Visual C++ v14 Redistributable (the one that covers Visual Studio 2017 and later) in the same bitness as the OpenEdge process: x64 for 64-bit, x86 for 32-bit. Development machines usually have it already. On target machines, install the latest supported version from Microsoft's VC++ Redistributable downloads. |
| PAS for OpenEdge | Add -assemblies with the folder's full path to the agent startup parameters
(agentStartupParam in openedge.properties), and restart the instance. |
Updating to a new Chilkat version
Each Chilkat release has a new assembly version, and compiled r-code refers to the exact version listed in
assemblies.xml. To upgrade:
- Stop the sessions that have the DLL loaded (Developer Studio's AVM, running clients, the PAS for OpenEdge instance). A process keeps the DLL locked until it exits.
- Replace
ChilkatDotNet48.dllwith the new version. - Update the
Version=in theassemblies.xmlentry. You can remove the old reference and add the new DLL again, or edit the version by hand (the PowerShell command in step 2 prints it). - Recompile the code that uses Chilkat, and deploy the new DLL,
assemblies.xml, and r-code together.
Troubleshooting
"Could not load file or assembly 'ChilkatDotNet48' or one of its dependencies"
- "An attempt was made to load a program with an incorrect format": the DLL's bitness doesn't match the OpenEdge process. Use the other download (see Match OpenEdge's bitness).
- "The specified module could not be found": the Visual C++ v14 runtime of the same bitness isn't installed. Install it (see Deploying).
- "Operation is not supported" (HRESULT 0x80131515): .NET treats the DLL as coming from a remote source. This happens when the DLL is marked as downloaded from the Internet or is loaded from a network share. Right-click the DLL, choose Properties, check Unblock, then restart the session. Keep the DLL on a local drive.
- "The located assembly's manifest definition does not match the assembly reference": the DLL in the
assemblies directory is a different version from the one in
assemblies.xmlor the one the r-code was compiled with. See Updating to a new Chilkat version.
The compiler can't find Chilkat.Http (or another Chilkat class)
The session didn't find the Chilkat entry in assemblies.xml. Check that assemblies.xml is in
the session's working directory or in the folder given by -assemblies, that it lists
ChilkatDotNet48, and that ChilkatDotNet48.dll is in the same folder. In Developer Studio, check
the project's page.
Linux and modern .NET with -clrnetcore
OpenEdge 12.7 and later on Windows, and OpenEdge 12.8 and later on Linux, can use modern .NET instead of the .NET
Framework. It is selected with the -clrnetcore startup parameter; without it, OpenEdge on Windows loads the
.NET Framework. On Windows it works in the GUI clients, the character and batch clients, and PAS for OpenEdge agents.
On Linux it works in the character client, the batch client, and PAS for OpenEdge agents. This is the way to use Chilkat's .NET API
from OpenEdge on Linux. Use the Chilkat .NET Core assembly, ChilkatDnCore, instead of
ChilkatDotNet48.dll. Your ABL code doesn't change: the namespace, class, method, and property names are
the same.
- Install the .NET runtime on the machine. OpenEdge doesn't include it. Use a .NET version certified for
your OpenEdge release, as listed in Progress's Platform & Product Availability Guide. When several .NET versions
are installed, OpenEdge picks the highest one; the
Progress.clrbridge.netcore.runtimeconfig.jsonfile in$DLC/bincontrols that choice. - Get the two Chilkat files. On nuget.org, use the Download package link for
ChilkatDnCore and for
ChilkatNativeLib, taking the same version of each.
A
.nupkgfile is a zip archive. From ChilkatDnCore, takelib/net6.0/ChilkatDnCore.dll(it runs on .NET 6 and later). From ChilkatNativeLib, take the native library for your platform, for exampleruntimes/linux-x64/native/libchilkatDnNative.so,runtimes/linux-arm64/native/libchilkatDnNative.so, orruntimes/win-x64/native/chilkatDnNative.dll. - Copy both files into the assemblies directory and list the assembly in
assemblies.xml. With-clrnetcore, OpenEdge ignores the version inassemblies.xml, so the entry can be just the name:<?xml version="1.0" encoding="utf-8"?> <references xsi:noNamespaceSchemaLocation="assemblies.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <assembly name="ChilkatDnCore"/> </references>
- Start every session with
-clrnetcoreand your-assembliesfolder, including the session you compile in. R-code compiled for the .NET Framework can't be used with-clrnetcore, and the reverse, so compile in the same mode you run in.
Other options
ActiveX. On Windows, ABL can also use the Chilkat ActiveX through
COM Automation, with a COM-HANDLE variable:
DEFINE VARIABLE hHttp AS COM-HANDLE NO-UNDO.
CREATE "Chilkat.Http" hHttp.
MESSAGE hHttp:QuickGetStr("https://www.chilkatsoft.com/helloworld.txt") VIEW-AS ALERT-BOX.
RELEASE OBJECT hHttp.
The .NET assembly is the better choice for new code. It doesn't need registration with regsvr32, ABL
checks the class and member names when you compile, and Developer Studio can show the Chilkat classes. The same
bitness rule applies to the ActiveX.
Documentation & Next Steps
- 📖 Chilkat .NET (C#) Reference Documentation — class, method, and property names are the same in ABL
- 💻 Chilkat C# Sample Code — each example translates line for line to ABL
- 📦 All Chilkat .NET downloads
- ✉ Contact Chilkat support
Progress, OpenEdge, and Progress Developer Studio for OpenEdge are trademarks or registered trademarks of Progress Software Corporation or one of its subsidiaries or affiliates in the U.S. and other countries.