<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Peter + AI</title>
    <description>The latest articles on Forem by Peter + AI (@petercode).</description>
    <link>https://forem.com/petercode</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3347513%2F4a1c0e8e-e972-46bf-a9a9-61ed40aa709d.png</url>
      <title>Forem: Peter + AI</title>
      <link>https://forem.com/petercode</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/petercode"/>
    <language>en</language>
    <item>
      <title>Uniface 10.4: Understanding the $ALLOW_NOBREAK_SPACE Configuration Parameter</title>
      <dc:creator>Peter + AI</dc:creator>
      <pubDate>Sun, 30 Nov 2025 13:59:53 +0000</pubDate>
      <link>https://forem.com/petercode/uniface-104-understanding-the-allownobreakspace-configuration-parameter-1fac</link>
      <guid>https://forem.com/petercode/uniface-104-understanding-the-allownobreakspace-configuration-parameter-1fac</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When working with Uniface ProcScript, you might encounter mysterious syntax errors that seem to point at perfectly valid code. The culprit could be invisible non-breaking space characters (0xA0) lurking in your source files. This article explains the $ALLOW_NOBREAK_SPACE configuration parameter and how it can help you deal with this common issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is $ALLOW_NOBREAK_SPACE?
&lt;/h2&gt;

&lt;p&gt;$ALLOW_NOBREAK_SPACE is a configuration parameter in Uniface 10.4 that controls whether non-breaking spaces (hexadecimal value 0xA0) are allowed in ProcScript code. By default, these characters cause syntax errors when the Uniface compiler encounters them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Syntax:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ALLOW_NOBREAK_SPACE = 1 | 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Values:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  1 - Non-breaking spaces (0xA0) are allowed in ProcScript&lt;/li&gt;
&lt;li&gt;  0 - Non-breaking spaces cause syntax errors&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Default:&lt;/strong&gt; None (not set, behaves like 0)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;p&gt;The parameter is configured in the &lt;strong&gt;client assignment file&lt;/strong&gt; under the [SETTINGS] section:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[SETTINGS]
$ALLOW_NOBREAK_SPACE = 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Understanding Non-Breaking Spaces
&lt;/h2&gt;

&lt;p&gt;Non-breaking spaces (Unicode U+00A0, hex 0xA0) differ from regular spaces (0x20). They're designed to prevent line breaks between words, commonly used in word processors and web content. However, in source code, they're usually unintentional and problematic.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Do They Get Into Your Code?
&lt;/h3&gt;

&lt;p&gt;Non-breaking spaces typically sneak into ProcScript through:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Copy-pasting from documents&lt;/strong&gt; - Word documents, PDFs, or web pages often contain 0xA0 characters&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Text editors&lt;/strong&gt; - Some editors insert non-breaking spaces automatically&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Legacy code migration&lt;/strong&gt; - Older systems or documentation may include these characters&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;International keyboards&lt;/strong&gt; - Certain keyboard layouts can insert them accidentally&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Common Problems Without This Parameter
&lt;/h2&gt;

&lt;p&gt;When $ALLOW_NOBREAK_SPACE is not enabled, you may experience:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Invisible Syntax Errors
&lt;/h3&gt;

&lt;p&gt;Error: Syntax error at line 42&lt;/p&gt;

&lt;p&gt;Your code looks perfect, but the compiler disagrees. The 0xA0 character is visually identical to a regular space, making debugging extremely difficult.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Environment-Specific Issues
&lt;/h3&gt;

&lt;p&gt;Code that compiles fine on one developer's machine fails on another, depending on their configuration settings.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Migration Headaches
&lt;/h3&gt;

&lt;p&gt;When importing legacy code or documentation examples, you might face compilation failures that are hard to trace.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  When to Enable It
&lt;/h3&gt;

&lt;p&gt;Set $ALLOW_NOBREAK_SPACE = 1 when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Working with legacy codebases that may contain these characters&lt;/li&gt;
&lt;li&gt;  Your team frequently copies code from external sources&lt;/li&gt;
&lt;li&gt;  Experiencing unexplained syntax errors in seemingly correct code&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Long-Term Solution
&lt;/h3&gt;

&lt;p&gt;While enabling this parameter is a practical workaround, the ideal approach is to clean your codebase:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Use a hex editor&lt;/strong&gt; or specialized tool to find and replace 0xA0 with 0x20&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Configure your IDE&lt;/strong&gt; to highlight non-breaking spaces&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Establish coding standards&lt;/strong&gt; to prevent these characters from entering your codebase&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Use version control pre-commit hooks&lt;/strong&gt; to detect and warn about 0xA0 characters&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Detection and Cleanup
&lt;/h2&gt;

&lt;p&gt;Here's a simple approach to find non-breaking spaces in your code:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Visual Studio Code:&lt;/strong&gt; Use the find and replace feature with regex enabled and search for \xA0&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Command-line tools:&lt;/strong&gt; Use grep or similar tools to scan files&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Uniface IDE:&lt;/strong&gt; Check compiler error messages carefully for unexpected character warnings&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;The $ALLOW_NOBREAK_SPACE parameter is a useful configuration option for managing non-breaking spaces in Uniface ProcScript. While it provides a quick fix for syntax errors caused by 0xA0 characters, the best practice is to maintain clean source code that only contains standard spaces (0x20).&lt;/p&gt;

&lt;p&gt;Understanding this parameter can save hours of debugging time and prevent frustration when working with ProcScript code from various sources.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;References:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Uniface 10.4 Official Documentation - Configuration Reference&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Have you encountered non-breaking space issues in your Uniface projects? Share your experiences in the comments!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>uniface</category>
      <category>procscript</category>
      <category>debugging</category>
      <category>configuration</category>
    </item>
    <item>
      <title>Unlocking Multi-Threading in Uniface: Mastering $ALLOW_FOREIGN_THREADS for COM Integration</title>
      <dc:creator>Peter + AI</dc:creator>
      <pubDate>Sun, 30 Nov 2025 13:48:34 +0000</pubDate>
      <link>https://forem.com/petercode/unlocking-multi-threading-in-uniface-mastering-allowforeignthreads-for-com-integration-2g45</link>
      <guid>https://forem.com/petercode/unlocking-multi-threading-in-uniface-mastering-allowforeignthreads-for-com-integration-2g45</guid>
      <description>&lt;p&gt;&lt;strong&gt;Legacy enterprise systems meet modern demands.&lt;/strong&gt; Uniface, the powerhouse for complex backend applications, isn't natively multi-threaded. But when integrating with COM components from external systems, $ALLOW_FOREIGN_THREADS becomes your gateway to safe thread handling. This setting serializes foreign thread calls, preventing crashes in high-load environments like healthcare or finance systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Uniface Needs Thread Control
&lt;/h2&gt;

&lt;p&gt;Uniface excels in single-threaded operations but struggles with "foreign threads" – those spawned outside Uniface by calling applications via COM (Component Object Model). Without proper handling, concurrent access leads to race conditions, deadlocks, or instability.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Classic Problem&lt;/strong&gt;: External C#/.NET apps or Windows services invoke Uniface COM objects simultaneously.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Impact&lt;/strong&gt;: Data corruption, application hangs, or silent failures in production.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Real-World Context&lt;/strong&gt;: Common in hybrid legacy-modern stacks where Uniface APIs serve multi-threaded clients.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Configuration: Step-by-Step Setup
&lt;/h2&gt;

&lt;p&gt;Add this to your &lt;strong&gt;client assignment file&lt;/strong&gt; under the [SETTINGS] section:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[SETTINGS]
$ALLOW_FOREIGN_THREADS = 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Values&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  1: Enables serialization of COM invocations from foreign threads.&lt;/li&gt;
&lt;li&gt;  0: Disables (default: none/unset).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Critical Prerequisite&lt;/strong&gt;: Run the &lt;strong&gt;Uniface COM Configuration Utility&lt;/strong&gt; (ucomcfg.exe) from the Windows Start menu &amp;gt; Uniface group. This sets up thread synchronization – skipping it risks undefined behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works Under the Hood
&lt;/h2&gt;

&lt;p&gt;When enabled, Uniface queues incoming COM calls from external threads and processes them sequentially. This mimics a thread-safe singleton pattern:&lt;/p&gt;

&lt;p&gt;External Thread 1 → Queue → Uniface processes → Response&lt;br&gt;
External Thread 2 → Queue (waits) → Uniface processes → Response&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance Trade-off&lt;/strong&gt;: No true parallelism, but stability first. Ideal for throughput &amp;lt;100 concurrent calls/sec.&lt;/p&gt;
&lt;h2&gt;
  
  
  Common Pitfalls &amp;amp; Troubleshooting
&lt;/h2&gt;

&lt;p&gt;Uniface devs often hit these in practice:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Issue&lt;/th&gt;
&lt;th&gt;Symptoms&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Deadlocks&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;App freezes on COM invoke&lt;/td&gt;
&lt;td&gt;Verify COM Utility sync settings; test with single thread first.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Performance Drop&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High latency under load&lt;/td&gt;
&lt;td&gt;Profile with $PROC_TRACING; consider async alternatives like Uniface Router.\&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Crashes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AV on multi-thread access&lt;/td&gt;
&lt;td&gt;Ensure $ALLOW_FOREIGN_THREADS=1 + COM config; check Windows Event Logs.\&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Silent Fails&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No errors, wrong data&lt;/td&gt;
&lt;td&gt;Enable logging ($PROC_LOG_FILE); validate serialization order.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Pro Tip&lt;/strong&gt;: Test in isolated env – spawn threads via C# Task.Run() calling your Uniface COM object.&lt;/p&gt;
&lt;h2&gt;
  
  
  Example: C# Client Calling Uniface COM
&lt;/h2&gt;

&lt;p&gt;Here's a practical integration demo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// C# Client (Multi-threaded)
public class UnifaceInvoker
{
    private readonly UnifaceCOMObject _unifaceObj;

    public async Task&amp;lt;string&amp;gt; ProcessAsync(string data)
    {
        return await Task.Run(() =&amp;gt; _unifaceObj.InvokeMethod(data)); // Foreign thread
    }
}

// Usage: Multiple tasks hit Uniface simultaneously
var tasks = Enumerable.Range(1, 5).Select(i =&amp;gt; invoker.ProcessAsync($"Data-{i}"));
await Task.WhenAll(tasks);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With $ALLOW_FOREIGN_THREADS=1, all calls serialize safely. Without? Expect chaos.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use (and Avoid) It
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Use Cases&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  COM bridges to .NET/C# services.&lt;/li&gt;
&lt;li&gt;  Legacy Uniface APIs exposed to IIS-hosted apps.&lt;/li&gt;
&lt;li&gt;  Enterprise integrations (e.g., ERP + Uniface).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Avoid If&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Pure Uniface-to-Uniface comms (use messages instead).&lt;/li&gt;
&lt;li&gt;  High-throughput needs (&amp;gt;500 TPS) – explore Uniface Router multi-threading.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Modern Alternatives &amp;amp; Future-Proofing
&lt;/h2&gt;

&lt;p&gt;Rocket Software's Uniface 10.4+ pushes cloud-native patterns. Consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Uniface Router&lt;/strong&gt;: Built-in multi-threaded load balancer.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;REST/JSON APIs&lt;/strong&gt;: Bypass COM entirely.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Migration Path&lt;/strong&gt;: Containerize with Docker/K8s for true parallelism.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;$ALLOW_FOREIGN_THREADS bridges the gap – use it wisely to extend legacy Uniface lifespans.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Disclosure&lt;/strong&gt;: _This article was generated with assistance from an AI language model, based on official Uniface 10.4 documentation and verified sources. Code examples are illustrative and should be tested in your environment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Questions for you&lt;/strong&gt;: Integrating with specific C# frameworks? Share your stack for tailored advice!&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>backend</category>
      <category>architecture</category>
      <category>performance</category>
    </item>
    <item>
      <title>Understanding $ACTIVE_FIELD in Uniface 10.4</title>
      <dc:creator>Peter + AI</dc:creator>
      <pubDate>Sun, 30 Nov 2025 13:27:09 +0000</pubDate>
      <link>https://forem.com/petercode/understanding-activefield-in-uniface-104-3f9e</link>
      <guid>https://forem.com/petercode/understanding-activefield-in-uniface-104-3f9e</guid>
      <description>&lt;p&gt;*This article was created with the assistance of AI and is based on the official Rocket Software Uniface 10.4 documentation.*&lt;/p&gt;

&lt;p&gt;The $ACTIVE_FIELD setting allows developers to control the visual appearance of the field that currently holds focus in a Uniface desktop application. This immediate visual feedback helps users track their cursor position, improving usability in data-heavy forms.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Configure $ACTIVE_FIELD
&lt;/h2&gt;

&lt;p&gt;This setting is defined in the [SETTINGS] section of your assignment file (e.g., usys.asn or your application-specific .asn file).&lt;/p&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ACTIVE_FIELD {=} Attribute {, Attribute, ...}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Available Video Attributes
&lt;/h3&gt;

&lt;p&gt;The following attributes can be combined to style the active field:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;HLT&lt;/strong&gt;: Highlights the field using the system's default highlight color.
&lt;em&gt;Note: This attribute takes precedence over other color settings if combined.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;BOR&lt;/strong&gt;: Draws a border around the active field.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;UND&lt;/strong&gt;: Underlines the text in the field.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;INV&lt;/strong&gt;: Inverts the foreground and background colors.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;BRI&lt;/strong&gt;: Displays text in a bright or bold weight (device-dependent).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;COL=n&lt;/strong&gt;: Applies a specific color combination (see calculation below).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Calculating Custom Colors (COL=n)
&lt;/h2&gt;

&lt;p&gt;If you need a specific color combination instead of the system default (HLT), you must calculate the color code n. Uniface uses a standard formula based on an 8-color palette (indices 0-7).&lt;/p&gt;

&lt;h3&gt;
  
  
  The Formula
&lt;/h3&gt;

&lt;p&gt;Code = (Foreground × 8) + Background&lt;/p&gt;

&lt;h3&gt;
  
  
  Color Indices
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Index&lt;/th&gt;
&lt;th&gt;Color&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;Black&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Blue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Green&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Cyan&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Red&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Magenta&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Brown/Yellow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;White&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Example Calculation
&lt;/h3&gt;

&lt;p&gt;To display &lt;strong&gt;White text&lt;/strong&gt; on a &lt;strong&gt;Blue background&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Foreground (White):&lt;/strong&gt; 7&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Background (Blue):&lt;/strong&gt; 1&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Calculation:&lt;/strong&gt; (7 × 8) + 1 = 56 + 1 = 57&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Result:&lt;/strong&gt; $ACTIVE_FIELD = COL=57&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Important Prerequisites &amp;amp; Precedence
&lt;/h2&gt;

&lt;p&gt;Two critical factors determine whether your $ACTIVE_FIELD setting will actually work.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The "Cursor Video" Property
&lt;/h3&gt;

&lt;p&gt;The $ACTIVE_FIELD setting is ignored unless the field itself allows it. You must enable the &lt;strong&gt;Cursor Video&lt;/strong&gt; property for the specific field (or model) in the Uniface IDE (Property Inspector &amp;gt; Interface).&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Precedence Rules (Who Wins?)
&lt;/h3&gt;

&lt;p&gt;When multiple settings try to control the field's appearance, Uniface follows a strict hierarchy. By default, the order of precedence (highest to lowest) is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;ProcScript ($fieldvideo)&lt;/strong&gt;: Code executed in triggers usually overrides assignment settings.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;$ACTIVE_FIELD&lt;/strong&gt;: Your global assignment setting.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;$DEF_CUROCC_VIDEO&lt;/strong&gt;: Settings for the current occurrence.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;How to Override ProcScript:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
If you want your global $ACTIVE_FIELD setting to always take precedence, even over specific ProcScript commands, add this to your assignment file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[SETTINGS]
$ACTIVE_FIELD_FIRST = T
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Common Pitfalls
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Web/DSP Limitations:&lt;/strong&gt; $ACTIVE_FIELD is primarily for Desktop/GUI applications. For Web (DSP) applications, use CSS pseudo-classes like :focus instead.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;"HLT" Override:&lt;/strong&gt; If you define $ACTIVE_FIELD = (HLT, COL=57), the HLT attribute will win, and your custom blue background (COL=57) will be ignored.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;System Themes:&lt;/strong&gt; The HLT attribute respects the OS theme. On Windows 10/11, this might look different depending on whether the user has Dark Mode or High Contrast mode enabled.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Here is a complete snippet for your usys.asn file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[SETTINGS]
; Sets the active field to White text on Blue background (57) with a Border
$ACTIVE_FIELD = (COL=57, BOR)

; Optional: Ensures this setting overrides local ProcScript
; $ACTIVE_FIELD_FIRST = T
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Uniface Deployment 101: Mastering $SEARCH_RESOURCES and Avoiding the "It Works in the IDE" Trap</title>
      <dc:creator>Peter + AI</dc:creator>
      <pubDate>Sun, 30 Nov 2025 13:16:25 +0000</pubDate>
      <link>https://forem.com/petercode/uniface-deployment-101-mastering-searchresources-and-avoiding-the-it-works-in-the-ide-trap-5gcm</link>
      <guid>https://forem.com/petercode/uniface-deployment-101-mastering-searchresources-and-avoiding-the-it-works-in-the-ide-trap-5gcm</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;If you are migrating from older versions of Uniface (like 9.7) to Uniface 10, you might have stumbled upon the .asn (Assignment) file.&lt;/p&gt;

&lt;p&gt;One setting in this file causes more confusion during deployment than any other: $SEARCH_RESOURCES.&lt;/p&gt;

&lt;p&gt;In this post, we’ll demystify what this setting actually does, why Uniface 10 treats it differently than its predecessors, and how to configure it for a rock-solid deployment pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is $SEARCH_RESOURCES?
&lt;/h3&gt;

&lt;p&gt;In simple terms, $SEARCH_RESOURCES tells the Uniface Runtime (the kernel) &lt;strong&gt;where&lt;/strong&gt; to look for the compiled objects (Forms, Services, Reports) it needs to execute.&lt;/p&gt;

&lt;p&gt;There are generally two places Uniface can look for code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;The Repository (DB):&lt;/strong&gt; This is where your source code lives during development.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;UAR Files (Uniface Archive) or Directories:&lt;/strong&gt; These are your compiled, portable application files.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The $SEARCH_RESOURCES setting defines whether the runtime should look at the source code in the database or strictly use the compiled archives.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Configuration: resources_only
&lt;/h3&gt;

&lt;p&gt;In the [SETTINGS] section of your assignment file, you will typically see this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\[SETTINGS\]
$SEARCH\_RESOURCES = resources\_only
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In &lt;strong&gt;Uniface 10&lt;/strong&gt;, this is the standard for deployment.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;In the past (Uniface 9):&lt;/strong&gt; You might have used resources_first or resources_last, which allowed the application to "fall back" to the database if a compiled file wasn't found.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Modern Way:&lt;/strong&gt; resources_only forces the application to look &lt;strong&gt;exclusively&lt;/strong&gt; in the files defined in the [RESOURCES] section. If a component isn't there, the application throws an error (usually -16 Component not found).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why is this better?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Performance:&lt;/strong&gt; Accessing a local file (or loading into memory via $MEMORY_ZIP) is significantly faster than querying a database for every component load.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Stability:&lt;/strong&gt; You guarantee that what you tested is exactly what is running. No accidental "developer versions" sneaking in from a connected database.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The [RESOURCES] Section: First Match Wins
&lt;/h3&gt;

&lt;p&gt;Once $SEARCH_RESOURCES is active, Uniface looks at the [RESOURCES] section to find the actual files. The most important rule here is &lt;strong&gt;sequence matters&lt;/strong&gt;. Uniface scans this list from top to bottom and stops at the first match.&lt;/p&gt;

&lt;p&gt;Here is a typical setup for a deployment environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[RESOURCES]
; 1. Hotfixes (Highest Priority)
.\\patches\\urgent_fix.uar

; 2. The Main Application
.\\bin\\my_erp_system.uar

; 3. Uniface System Libraries (Required)
usys:usys.uar
usys:usysicon.uar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Scenario:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You have a bug in FRM_LOGIN.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; You fix it and compile it into urgent_fix.uar.&lt;/li&gt;
&lt;li&gt; You place this file in the patches folder.&lt;/li&gt;
&lt;li&gt; Because urgent_fix.uar is listed &lt;strong&gt;before&lt;/strong&gt; my_erp_system.uar, Uniface loads the new login form from the patch.&lt;/li&gt;
&lt;li&gt; For all other components, it continues down the list to the main archive.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Common Pitfalls
&lt;/h3&gt;

&lt;p&gt;Here are the "Gotchas" to watch out for when moving to a strict resources_only environment:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. The "Shadowing" Problem
&lt;/h4&gt;

&lt;p&gt;If you deploy a new my_erp_system.uar but forget to remove an old test_debug.uar that is listed higher up in the assignment file, Uniface will happily load the old code. It never warns you that duplicate objects exist.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Relative vs. Absolute Paths
&lt;/h4&gt;

&lt;p&gt;Be careful with paths in your assignment file.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  .\bin\app.uar relies on the startup directory.&lt;/li&gt;
&lt;li&gt;  If your shortcut starts in a different folder, the runtime won't find your resources.&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Tip:&lt;/em&gt; Use logical paths defined in [FILES] or absolute paths generated during your build process.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3. The "It Works in the IDE" Syndrome
&lt;/h4&gt;

&lt;p&gt;The Uniface IDE usually connects to the Repository. If you forget to compile a specific Global Proc into your UAR, it will work fine on your machine (because the IDE sees the DB), but it will crash instantly in the Test environment where &lt;code&gt;$SEARCH_RESOURCES = resources_only&lt;/code&gt; is active.&lt;/p&gt;

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

&lt;p&gt;To ensure a smooth migration to Uniface 10:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Set

&lt;code&gt;$SEARCH_RESOURCES = resources_only&lt;/code&gt;

in all non-development environments.&lt;/li&gt;
&lt;li&gt; Treat your UAR files as immutable artifacts.&lt;/li&gt;
&lt;li&gt; Keep your [RESOURCES] list clean and ordered.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Note: This article was created with the assistance of AI based on official Uniface 10.4 documentation to explain core security concepts and provide practical implementation details.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>uniface</category>
      <category>legacymodernization</category>
      <category>deployment</category>
      <category>devops</category>
    </item>
    <item>
      <title>Mastering the [SETTINGS] Section in Uniface Assignment Files</title>
      <dc:creator>Peter + AI</dc:creator>
      <pubDate>Sun, 30 Nov 2025 13:02:19 +0000</pubDate>
      <link>https://forem.com/petercode/mastering-the-settings-section-in-uniface-assignment-files-1nd7</link>
      <guid>https://forem.com/petercode/mastering-the-settings-section-in-uniface-assignment-files-1nd7</guid>
      <description>&lt;p&gt;If you are developing enterprise applications with Uniface, you know that the Assignment File (.asn) is the nervous system of your application's runtime configuration. While sections like [ENTITIES] or [DRIVER_SETTINGS] often get the spotlight during database setup, the &lt;strong&gt;[SETTINGS]&lt;/strong&gt; section is where the battle for a stable, environment-agnostic runtime is won.&lt;/p&gt;

&lt;p&gt;In this post, we’ll dive into what the [SETTINGS] section actually does, the correct syntax for resource loading (fixing common misconceptions), and how to architect it for Development vs. Production environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the [SETTINGS] Section?
&lt;/h2&gt;

&lt;p&gt;The [SETTINGS] section is used to define &lt;strong&gt;Uniface Logicals&lt;/strong&gt; and &lt;strong&gt;Kernel settings&lt;/strong&gt;. These are environment variables specific to the Uniface runtime that are loaded &lt;em&gt;before&lt;/em&gt; your application logic starts. They control &lt;strong&gt;how&lt;/strong&gt; Uniface behaves—how it finds code, where it logs errors, and how it handles dates or strings.&lt;/p&gt;

&lt;p&gt;The syntax is straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[SETTINGS]
$VARIABLE_NAME = value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Core Strategy: Resource Loading
&lt;/h2&gt;

&lt;p&gt;The single most critical setting in modern Uniface (9.7 through 10.4) is $SEARCH_RESOURCES. This logical controls the order in which Uniface looks for compiled components (Forms, Services, DSPs).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⚠️ Common Pitfall: "Filesystem First"&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
A common mistake is trying to use a value like filesystem_first. &lt;strong&gt;This is not a valid keyword.&lt;/strong&gt; If you want Uniface to look at your local files before checking the UAR archives, you must use &lt;strong&gt;resources_last&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Here are the valid strategies:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;resources_only (Production Standard)&lt;/strong&gt;
Uniface completely ignores the file system and &lt;strong&gt;only&lt;/strong&gt; looks inside the UAR (Uniface Archive) files defined in the [RESOURCES] section. This is mandatory for high-performance, secure production environments.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;resources_last (Development Standard)&lt;/strong&gt;
Uniface checks your local folders (e.g., \uo) first. If it doesn't find the object there, &lt;em&gt;then&lt;/em&gt; it checks the UARs. This is ideal for development because you can compile a form and test it immediately without rebuilding a UAR.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;resources_excluded (Default)&lt;/strong&gt;
Uniface never looks in UAR files.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Abstracting Environments with Logicals
&lt;/h2&gt;

&lt;p&gt;Never hardcode paths in your ProcScript or C# bridges. Instead, define them in [SETTINGS] and access them via $logical.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In your ASN file:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[SETTINGS]
$EXPORT_DIR = C:\\MyApp\\Exports
$LOG_DIR    = C:\\MyApp\\Logs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;In your Uniface Code:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; Instead of "filedump/append field, 'C:\\MyApp\\Logs\\err.log'"
filedump/append vErrorField, "%%$logical("LOG_DIR")%%%\\error.log"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This abstraction makes migrating your app from Windows to Linux (or Docker containers) as simple as swapping the ASN file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration Templates
&lt;/h2&gt;

&lt;p&gt;Here is how you should structure your assignment files for different stages of your pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  A. The Development Setup
&lt;/h3&gt;

&lt;p&gt;In development, you need flexibility and verbose logging.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[SETTINGS]
; STRATEGY: Check local files (./uo) first, check UARs last.
$SEARCH_RESOURCES = resources_last

; LOGGING: Redirect the output window to a file for analysis
; Note: Use the correct underscore syntax for Uniface 10+
$PUTMESS_LOG_FILE = .\\logs\\uniface_dev.log

; DEBUGGING: Enable extended IO info in the log
$IOPRINT = 255

; Custom App Settings
$APP_ENV = DEV
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  B. The Production Setup
&lt;/h3&gt;

&lt;p&gt;In production, you need speed, security, and immutability.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[SETTINGS]
; STRATEGY: Only load signed/packaged code from UARs
$SEARCH_RESOURCES = resources_only

; DISABLE DEBUGGING features
$TEST_MODE = 0

; Custom App Settings
$APP_ENV = PROD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Troubleshooting Guide
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem&lt;/th&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Solution&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Object Not Found&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;You compiled a form, but the app still runs the old version.&lt;/td&gt;
&lt;td&gt;You likely have $SEARCH_RESOURCES = resources_only set locally. Switch to resources_last so your local compilation takes precedence over the usys.uar.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Log File Missing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$PUTMESS_LOGFILE isn't working.&lt;/td&gt;
&lt;td&gt;In newer Uniface versions (especially 10.4), ensuring the syntax is $PUTMESS_LOG_FILE (with the extra underscore) resolves ambiguity.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Linux/Docker Issues&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Paths work on Windows but fail on Linux.&lt;/td&gt;
&lt;td&gt;Uniface logicals in [SETTINGS] are case-sensitive on Linux. Ensure your logical names (e.g., $EXPORT_DIR) match exactly in your code and ASN.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;The [SETTINGS] section is your control center for the Uniface runtime. By correctly utilizing $SEARCH_RESOURCES = resources_last for development and resources_only for production, you create a robust workflow that supports both rapid iteration and stable deployment.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Note: This article was created with the assistance of AI based on official Uniface 10.4 documentation to explain core security concepts and provide practical implementation details.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>uniface</category>
      <category>legacy</category>
      <category>devops</category>
      <category>configuration</category>
    </item>
    <item>
      <title>Uniface 10.4: How to Bulletproof Your Apps with Certification (And Why You Must)</title>
      <dc:creator>Peter + AI</dc:creator>
      <pubDate>Sun, 30 Nov 2025 07:58:05 +0000</pubDate>
      <link>https://forem.com/petercode/uniface-104-how-to-bulletproof-your-apps-with-certification-and-why-you-must-23l</link>
      <guid>https://forem.com/petercode/uniface-104-how-to-bulletproof-your-apps-with-certification-and-why-you-must-23l</guid>
      <description>&lt;p&gt;&lt;em&gt;Note: This article was created with the assistance of AI based on official Uniface 10.4 documentation to explain core security concepts and provide practical implementation details.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Hello everyone!&lt;/p&gt;

&lt;p&gt;In today's IT landscape, security is no longer a "nice-to-have"—it's an absolute necessity. This is especially true for enterprise applications that process sensitive data. If you are working with &lt;strong&gt;Uniface 10.4&lt;/strong&gt; (specifically 10.4.03 and later), you have a powerful tool at your disposal to ensure the integrity and security of your applications: &lt;strong&gt;Application Certification&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this article, we'll dive deep into this feature, explaining how it works, why it's critical, and—most importantly—how to implement it correctly in your .asn files.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Application Certification in Uniface?
&lt;/h2&gt;

&lt;p&gt;Certifying a deployed Uniface application is effectively digitally signing your software binaries. It protects your data privacy by verifying the validity of your application at runtime. This ensures that your database connection settings cannot be misused by unauthorized applications.&lt;/p&gt;

&lt;p&gt;The goal is to verify two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Integrity:&lt;/strong&gt; That your application has not been tampered with.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Authorization:&lt;/strong&gt; That your database connection is used &lt;em&gt;exclusively&lt;/em&gt; by your authorized Uniface applications.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why is this important?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Protection against tampering&lt;/strong&gt;: Once a Uniface application is certified, Uniface validates the integrity of every supported resource file. Any malicious attempt to modify the application files is detected and blocked immediately.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Securing sensitive connection data&lt;/strong&gt;: Your assignment files (.asn) contain critical information such as usernames, passwords, and paths to your databases. By certifying, you bind the database connection to your specific application signature. Unauthorized or tampered applications trying to use your .asn file will be denied access because they lack the matching private key signature.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How does certification work? (Public/Private Key)
&lt;/h2&gt;

&lt;p&gt;The core of certification is a standard cryptographic key pair (RSA 2048-bit).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Generate Key Pair&lt;/strong&gt;: You create a key pair, e.g., my_private.pem and my_public.pem.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Sign Application&lt;/strong&gt;: You use the cert.exe utility (introduced in recent 10.4 updates) to sign your application archive (UAR) or resources using the private key.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Configure Database&lt;/strong&gt;: You explicitly link the public key (my_public.pem) to your database connection in the assignment file.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Runtime Validation&lt;/strong&gt;: When the application starts, Uniface checks if the running application's signature matches the public key defined in the driver settings. If they don't match, the database connection is refused.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Technical Deep Dive: The Critical .asn Configuration
&lt;/h2&gt;

&lt;p&gt;Many developers understand the concept but stumble on the implementation. The crucial link happens in your assignment file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Setup:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
You do not just "place" the key; you must reference it in your DBMS connector settings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example .asn Snippet:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;[DRIVER_SETTINGS]&lt;br&gt;
; Linking the public key to the MSSQL driver&lt;br&gt;
MSS = U1.0, $DBMS_DEF:my_public_key_string&lt;/p&gt;

&lt;p&gt;[LOGICALS]&lt;br&gt;
; Ideally, keep the key content out of plain sight or use references if supported&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: In practice, the public key is often provided as a string or file reference within the driver parameters ($DBMS_DEF) to enforce the check.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Technical Key Limits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Private Keys&lt;/strong&gt;: Max 4096 characters (PEM format, RSA PKCS#8).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Public Keys&lt;/strong&gt;: Max 1024 characters.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Practical Example: The "Rogue App" Scenario
&lt;/h2&gt;

&lt;p&gt;Imagine you have an HR application connecting to an Oracle database. The .asn file has the connection string ORA:HR_DB|user|password.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Scenario A (No Certification):&lt;/strong&gt; A developer copies your .asn file to their local machine, points it to their own unauthorized Uniface component, and connects. They now have full read/write access to production HR data.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Scenario B (With Certification):&lt;/strong&gt; You sign your official HR app with your &lt;strong&gt;Private Key&lt;/strong&gt;. In the production .asn, you add the &lt;strong&gt;Public Key&lt;/strong&gt; to the Oracle driver settings.

&lt;ul&gt;
&lt;li&gt;  When the rogue developer tries to connect using their unsigned component (or a component signed with a different key) and your .asn file, the Uniface driver checks the signature against the public key.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Result:&lt;/strong&gt; Mismatch. The connection is rejected instantly. The stolen credentials are useless without the signed application binary.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common Pitfalls &amp;amp; Best Practices
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Key Management is King&lt;/strong&gt;: If you lose your private key, you cannot release updates. If it's stolen, the security model is broken. Store my_private.pem in a secure vault and only access it during the build pipeline.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Automate with cert.exe&lt;/strong&gt;: Do not sign manually. Integrate cert.exe into your CI/CD pipeline to sign builds automatically before deployment.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Performance Check&lt;/strong&gt;: While the overhead is minimal (RSA validation happens at connection time), always test startup times, especially if your app creates frequent new database connections rather than pooling them.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Application certification in Uniface 10.4 is a critical security mechanism that goes far beyond simple access control. It hardens your application against tampering and effectively binds your database credentials to your specific binary.&lt;/p&gt;

&lt;p&gt;If you haven't implemented this yet, put it on your roadmap for the next sprint. It's a low-effort, high-impact security upgrade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Have you tried setting up cert.exe in your pipelines yet? Let me know your experiences in the comments!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>uniface</category>
      <category>security</category>
      <category>devops</category>
      <category>legacycode</category>
    </item>
    <item>
      <title>Fixing Legacy Dates in Uniface 10: The $NLS\_DISABLE\_NON\_GREGORIAN\_CALENDAR Switch</title>
      <dc:creator>Peter + AI</dc:creator>
      <pubDate>Sun, 30 Nov 2025 07:38:57 +0000</pubDate>
      <link>https://forem.com/petercode/fixing-legacy-dates-in-uniface-10-the-nlsdisablenongregoriancalendar-switch-9m7</link>
      <guid>https://forem.com/petercode/fixing-legacy-dates-in-uniface-10-the-nlsdisablenongregoriancalendar-switch-9m7</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was generated with the assistance of AI.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Migrating legacy applications is rarely a smooth ride. If you are a developer maintaining a long-standing Uniface application, you might have encountered a peculiar issue when upgrading to &lt;strong&gt;Uniface 10.4.03&lt;/strong&gt; or higher: suddenly, your date logic breaks on specific client machines.&lt;/p&gt;

&lt;p&gt;This usually happens when your application runs in an environment with a non-Gregorian locale (like de&amp;gt;ar-SA for Saudi Arabia or de&amp;gt;th-TH for Thailand). Uniface 10 introduced enhanced NLS (National Language Support) capabilities, which are great for modernization but can be catastrophic for legacy business logic that assumes every year has 365 days and starts with "20".&lt;/p&gt;

&lt;p&gt;Here is the quick fix and the technical "why" behind the $NLS_DISABLE_NON_GREGORIAN_CALENDAR switch.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: When 2025 Becomes 1447
&lt;/h2&gt;

&lt;p&gt;Prior to Uniface 10.4.03, Uniface functions like $date, $datim, and $clock were largely indifferent to the specific calendar type of the operating system's locale. They typically returned the standard Gregorian date regardless of whether the user's PC was set to use the Hijri (Islamic) or Thai Buddhist calendar.&lt;/p&gt;

&lt;p&gt;With the update, Uniface improved its internationalization (ticket &lt;strong&gt;UNI-31202&lt;/strong&gt;). Now, if a user's PC is set to an Arabic locale using the Umm al-Qura calendar, $date might return a year like &lt;strong&gt;1447&lt;/strong&gt; instead of &lt;strong&gt;2025&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is this bad?
&lt;/h3&gt;

&lt;p&gt;Imagine a validation script in your legacy code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variables
  date v_compDate
endvariables

; Convert the string to a Uniface date and store it in a variable
v_compDate = $date("01-01-2000")

; Check whether the conversion was successful (optional, but recommended)
if ($procerror &amp;lt; 0)
  message "Error: Invalid comparison date format."
else
  if ($date &amp;gt; v_compDate)
      call LP_PROCESS_ORDER
  else
      message "Error: System date is invalid."
  endif
endif
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If $date returns 30/06/1447 (Hijri date), this check fails because 1447 is numerically smaller than 2000. Your valid business logic suddenly treats the current date as being in the distant past.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: The Kill Switch
&lt;/h2&gt;

&lt;p&gt;Rocket Software introduced a configuration switch to force the old behavior without requiring you to rewrite your entire application or force customers to change their OS settings.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to implement it
&lt;/h3&gt;

&lt;p&gt;You need to add the following line to your assignment file (.asn), typically in the [SETTINGS] section:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[SETTINGS\]
$NLS\_DISABLE\_NON\_GREGORIAN\_CALENDAR = 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What it does
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Value 1&lt;/strong&gt;: Forces Uniface to ignore the non-Gregorian calendar settings of the locale. $date will return the Gregorian date (e.g., 2025) even if the OS is using the Islamic or Thai calendar.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Value 0 (or undefined)&lt;/strong&gt;: Uniface respects the OS locale's calendar system (default behavior in 10.4.03+).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Should you use it?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Yes&lt;/strong&gt;, if you need a quick stability fix for an existing application that was never designed to handle multiple calendar systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No&lt;/strong&gt;, if you are building a modern, truly global application. The "correct" way forward is to write code that is calendar-aware or to explicitly format dates for internal logic while displaying them in the user's preferred format. Rocket Software marks this switch as "Strongly Discouraged" for new development because it essentially disables a feature meant to help you reach a global audience.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have you faced similar issues migrating legacy ERP systems to modern environments? Let me know in the comments!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>uniface</category>
      <category>legacy</category>
      <category>calendar</category>
    </item>
    <item>
      <title>Leveraging Service Stored Procedures (SSPs) in Uniface 10.4</title>
      <dc:creator>Peter + AI</dc:creator>
      <pubDate>Sun, 23 Nov 2025 13:27:59 +0000</pubDate>
      <link>https://forem.com/petercode/leveraging-service-stored-procedures-ssps-in-uniface-104-3emd</link>
      <guid>https://forem.com/petercode/leveraging-service-stored-procedures-ssps-in-uniface-104-3emd</guid>
      <description>&lt;p&gt;In the world of enterprise application development with &lt;strong&gt;Uniface&lt;/strong&gt;, performance is king. One often underutilized but powerful feature in Uniface 10.4 is the concept of &lt;strong&gt;Service Stored Procedures (SSPs)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you are working with heavy data processing or complex SQL logic, moving that logic closer to the data (the DBMS) is usually the best optimization strategy. Here is a deep dive into what SSPs are, why you should use them, and the constraints you need to watch out for.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Service Stored Procedures?
&lt;/h2&gt;

&lt;p&gt;In Uniface, a Service Stored Procedure isn't just a raw SQL script. It acts as a bridge. Technically, it uses the Uniface &lt;code&gt;activate&lt;/code&gt; statement to address a &lt;strong&gt;Stored Procedure Component&lt;/strong&gt; that you define within the &lt;strong&gt;Signature Editor&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Ideally, you use these when you want to execute DBMS-specific stored procedures but maintain a generic ProcScript activation method. This keeps your Uniface code relatively portable even if the underlying database logic is highly specific.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use Them? (The "Why")
&lt;/h2&gt;

&lt;p&gt;The primary driver is &lt;strong&gt;performance&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Imagine a scenario where you need to calculate a complex risk assessment value for a client based on thousands of transaction records.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Without SSP:&lt;/strong&gt; You fetch all thousands of records to the client (or Uniface Server), loop through them in ProcScript, calculate the value, and display it. This creates massive network traffic.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;With SSP:&lt;/strong&gt; You call the stored procedure. The DBMS performs the calculation on the server. Only the &lt;strong&gt;single final result&lt;/strong&gt; is sent back to Uniface.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Typical Use Cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Complex Calculations:&lt;/strong&gt; Doing heavy math where the data lives.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Conditional Logic:&lt;/strong&gt; Selecting data from Table A or Table B depending on a value in Table C (a decision best made on the server side).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Business Rules:&lt;/strong&gt; Checking inventory levels and triggering re-order flags in one atomic operation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If your application is simply waiting for user input, SSPs won't help much. They shine when the bottleneck is data processing, not user interaction.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Implement
&lt;/h2&gt;

&lt;p&gt;While the developer (you) is responsible for writing the actual SQL Stored Procedure in the DBMS (be it SQL Server, Oracle, or Informix), Uniface handles the connection.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Define the Component:&lt;/strong&gt; Create a Stored Procedure Component in the Uniface &lt;strong&gt;Signature Editor&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Set to Stateless:&lt;/strong&gt; Since these are global operations, you must define the operations as &lt;strong&gt;stateless&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Activate:&lt;/strong&gt; Use ProcScript to call it.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; Pseudo-code example of activation
variables
    string vResult
endvariables

; parameters: In_Value, Out_Result
activate "MY_STORED_PROC".CALCULATE_STOCK(12345, vResult)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uniface ensures the DBMS connection is established before the execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Important Restrictions (Read This Before Implementing!)
&lt;/h2&gt;

&lt;p&gt;While powerful, SSPs in Uniface 10.4 come with a strict set of limitations. Knowing these saves you from debugging nightmares later:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;No Hitlists:&lt;/strong&gt; You cannot use standard Uniface hitlist functionality (e.g., &lt;code&gt;$hits&lt;/code&gt; is not supported). Data is returned in one step.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;No BLOBs/Images:&lt;/strong&gt; Large object data types (Image, Raw) are not supported. &lt;strong&gt;Exception:&lt;/strong&gt; Raw data parameters work on Sybase only.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;No Multibyte Support:&lt;/strong&gt; There is no support for multibyte language character sets within these procedures.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;No Overflow Tables:&lt;/strong&gt; Tables with overflow fields are off-limits.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;No Uniface Wildcards:&lt;/strong&gt; You cannot use Uniface-specific substitution characters or wildcards; you must rely on standard SQL syntax for the specific DBMS.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Service Stored Procedures are an excellent tool in the Uniface developer's belt for optimizing high-load queries. By offloading logic to the DBMS via the Signature Editor, you reduce network overhead. However, they require careful planning regarding data types and state management.&lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

&lt;p&gt;This article was created with the help of AI.&lt;/p&gt;

</description>
      <category>uniface</category>
      <category>sql</category>
      <category>legacy</category>
      <category>performance</category>
    </item>
    <item>
      <title>Running Operating System Commands in Uniface 10.4</title>
      <dc:creator>Peter + AI</dc:creator>
      <pubDate>Sun, 23 Nov 2025 13:20:23 +0000</pubDate>
      <link>https://forem.com/petercode/running-operating-system-commands-in-uniface-104-m21</link>
      <guid>https://forem.com/petercode/running-operating-system-commands-in-uniface-104-m21</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Uniface 10.4 allows you to execute operating system commands directly from ProcScript using the built‑in &lt;code&gt;COMMAND&lt;/code&gt; and &lt;code&gt;COMMANDOUT&lt;/code&gt; operations exposed by an OS service signature.​&lt;/p&gt;

&lt;p&gt;This is useful for tasks like calling shell scripts, batch files, or external tools, while still keeping the main business logic in your Uniface application.​&lt;/p&gt;

&lt;h2&gt;
  
  
  What OS commands in Uniface are
&lt;/h2&gt;

&lt;p&gt;Uniface provides a special service type often called something like &lt;code&gt;OS&lt;/code&gt; that exposes two default operations: &lt;code&gt;COMMAND&lt;/code&gt; and &lt;code&gt;COMMANDOUT&lt;/code&gt;.​&lt;/p&gt;

&lt;p&gt;These operations are invoked using the &lt;code&gt;activate&lt;/code&gt; ProcScript statement and pass a command string to the underlying operating system shell.​&lt;/p&gt;

&lt;p&gt;Under the hood, Uniface forwards the command to the OS and reports success or failure back to your ProcScript via the usual &lt;code&gt;$status&lt;/code&gt; and &lt;code&gt;$procerror&lt;/code&gt; variables.​&lt;/p&gt;

&lt;p&gt;If the OS command itself is invalid, Uniface raises an activation error and sets &lt;code&gt;$status&lt;/code&gt; and &lt;code&gt;$procerror&lt;/code&gt; to &lt;code&gt;-150&lt;/code&gt;.​&lt;/p&gt;

&lt;h2&gt;
  
  
  Maximum command length limits
&lt;/h2&gt;

&lt;p&gt;When passing commands, you must respect the maximum length supported by the target operating system.​&lt;/p&gt;

&lt;p&gt;Typical limits in the Uniface 10.4 documentation are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Windows: up to 8K&lt;/li&gt;
&lt;li&gt;  Unix/Linux: up to 4K&lt;/li&gt;
&lt;li&gt;  IBM iSeries: up to 512 bytes per command string&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you build a very long command line that exceeds these OS limits, the command execution will fail before it reaches your actual tool or script.​&lt;/p&gt;

&lt;p&gt;In practice this means you should keep commands short, avoid inlining huge argument lists, and consider using wrapper scripts when you need complex behavior.​&lt;/p&gt;

&lt;h2&gt;
  
  
  Synchronous execution with COMMAND
&lt;/h2&gt;

&lt;p&gt;By default, calling &lt;code&gt;COMMAND&lt;/code&gt; is synchronous, which means Uniface waits until the operating system finishes the command before your ProcScript continues.​&lt;/p&gt;

&lt;p&gt;This is appropriate for short‑running tasks where your business logic depends on the result, for example building a file and then immediately importing it into the application.​&lt;/p&gt;

&lt;p&gt;A simple pattern looks like this in ProcScript:​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variables
   string vCmd
endvariables

vCmd = "dir /B" ; or "ls" on Unix-like systems
activate "OS".COMMAND(vCmd)

if ($status &amp;lt; 0)
   ; handle error, e.g. log $status and $procerror
endif
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code activates the &lt;code&gt;COMMAND&lt;/code&gt; operation on the &lt;code&gt;OS&lt;/code&gt; service with a single string parameter that contains the OS command to execute.​&lt;/p&gt;

&lt;p&gt;Error handling should always inspect &lt;code&gt;$status&lt;/code&gt; and &lt;code&gt;$procerror&lt;/code&gt; to detect both activation issues and OS‑level problems.​&lt;/p&gt;

&lt;h2&gt;
  
  
  Capturing output with COMMANDOUT
&lt;/h2&gt;

&lt;p&gt;While &lt;code&gt;COMMAND&lt;/code&gt; is fine when you only care that the command ran, &lt;code&gt;COMMANDOUT&lt;/code&gt; is intended for scenarios where you need to capture and process the text output from the OS command.​&lt;/p&gt;

&lt;p&gt;Typical examples are parsing directory listings, reading the output of a custom tool, or integrating with scripts that return machine‑readable text.​&lt;/p&gt;

&lt;p&gt;A common pattern uses one parameter for the command and another for the returned output string, similar to the following conceptual example:​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variables
   string vCmd
   string vOut
endvariables

vCmd = "mytool --list"
activate "OS".COMMANDOUT(vCmd, vOut)

if ($status &amp;gt;= 0)
   ; process vOut, e.g. parse lines or tokens
else
   ; handle error condition
endif
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact signature of &lt;code&gt;COMMANDOUT&lt;/code&gt; depends on how the OS service signature is defined in your model, but the core idea is that the operation returns the OS output into a ProcScript variable.​&lt;/p&gt;

&lt;p&gt;From there you can split the string, validate content, or log it as part of your application diagnostics.​&lt;/p&gt;

&lt;h2&gt;
  
  
  Asynchronous execution with /async
&lt;/h2&gt;

&lt;p&gt;Sometimes you want to fire off a command and not wait for completion, for example starting a long‑running batch process or a background script.​&lt;/p&gt;

&lt;p&gt;Uniface supports this by allowing the &lt;code&gt;/async&lt;/code&gt; switch on the &lt;code&gt;activate&lt;/code&gt; statement, which makes the OS command execution asynchronous.​&lt;/p&gt;

&lt;p&gt;A typical example looks like this:​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;activate/async "OS".COMMAND("at -fm myscript")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the &lt;code&gt;activate/async&lt;/code&gt; qualifier tells Uniface to start the command and immediately continue ProcScript execution without waiting for the OS command to finish.​&lt;/p&gt;

&lt;p&gt;This approach is useful when the command does not have to return a result to the current user interaction and will instead log or report success asynchronously.​&lt;/p&gt;

&lt;h2&gt;
  
  
  Non‑interactive nature of OS services
&lt;/h2&gt;

&lt;p&gt;Uniface OS services are not interactive, which means they cannot reliably host applications that expect to read from or write directly to a terminal UI or prompt the user.​&lt;/p&gt;

&lt;p&gt;Because of that, the documentation explicitly recommends using the &lt;code&gt;spawn&lt;/code&gt; ProcScript statement when you need to run truly interactive applications.​&lt;/p&gt;

&lt;p&gt;Commands executed via &lt;code&gt;COMMAND&lt;/code&gt; or &lt;code&gt;COMMANDOUT&lt;/code&gt; should therefore be written to run unattended, using arguments and configuration files instead of interactive prompts.​&lt;/p&gt;

&lt;p&gt;If your current workflow starts interactive tools, consider wrapping them in non‑interactive scripts that read inputs from files or environment variables.​&lt;/p&gt;

&lt;h2&gt;
  
  
  Error handling and diagnostics
&lt;/h2&gt;

&lt;p&gt;Whenever you call &lt;code&gt;COMMAND&lt;/code&gt; or &lt;code&gt;COMMANDOUT&lt;/code&gt;, it is important to check both &lt;code&gt;$status&lt;/code&gt; and &lt;code&gt;$procerror&lt;/code&gt; after the activation.​&lt;/p&gt;

&lt;p&gt;If the OS command is invalid or Uniface cannot activate the operation, &lt;code&gt;$status&lt;/code&gt; and &lt;code&gt;$procerror&lt;/code&gt; are set to &lt;code&gt;-150&lt;/code&gt;, which tells you there was an activation‑level problem rather than a business error in your script.​&lt;/p&gt;

&lt;p&gt;For production systems, you should log at least the command string, &lt;code&gt;$status&lt;/code&gt;, &lt;code&gt;$procerror&lt;/code&gt;, and any returned text, so you can troubleshoot failures on the server.​&lt;/p&gt;

&lt;p&gt;In multi‑platform environments this logging is especially useful, because command length limits and shell behavior can differ significantly between Windows, Unix/Linux, and iSeries.​&lt;/p&gt;

&lt;h2&gt;
  
  
  Best practices and recommendations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  Design your OS commands to be short, deterministic, and non‑interactive, delegating complex logic to external scripts that you version‑control alongside your Uniface application.​&lt;/li&gt;
&lt;li&gt;  Prefer &lt;code&gt;COMMANDOUT&lt;/code&gt; when you need structured output and integrate the parsing logic into your ProcScript, keeping a clear contract between the shell script and the Uniface component.​&lt;/li&gt;
&lt;li&gt;  Use synchronous calls for user‑critical operations and asynchronous activation for background jobs that do not affect the current transaction or UI flow.​&lt;/li&gt;
&lt;li&gt;  Always validate &lt;code&gt;$status&lt;/code&gt; and &lt;code&gt;$procerror&lt;/code&gt; and handle the &lt;code&gt;-150&lt;/code&gt; case explicitly so that you can distinguish between OS‑level issues and functional errors in your own ProcScript&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article was created with the help of AI.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Solving C++ Linking Issues in Uniface on Unix using u3gl</title>
      <dc:creator>Peter + AI</dc:creator>
      <pubDate>Sun, 23 Nov 2025 13:14:50 +0000</pubDate>
      <link>https://forem.com/petercode/solving-c-linking-issues-in-uniface-on-unix-using-u3gl-5e73</link>
      <guid>https://forem.com/petercode/solving-c-linking-issues-in-uniface-on-unix-using-u3gl-5e73</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you are working with Uniface on Unix or Linux platforms, you might have encountered a specific challenge when creating call-in executables. Linking a call-in executable can become a headache if you do not have a C++ compiler, or worse, if you do not have the &lt;strong&gt;exact&lt;/strong&gt; version of the C++ compiler used to build the Uniface runtime.​&lt;/p&gt;

&lt;p&gt;Uniface contains components written in C++. Consequently, some platforms require that you link your executables using the same C++ compiler version to handle runtime initialization correctly. Trying to do this with a standard C compiler often results in unresolved external errors, such as &lt;code&gt;Unresolved symbol: __shlinit&lt;/code&gt;.​&lt;/p&gt;

&lt;p&gt;For scenarios where acquiring the specific C++ compiler is difficult or impossible, Uniface provides a utility called &lt;code&gt;u3gl&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is u3gl?
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;u3gl&lt;/code&gt; program is a pre-linked executable provided by Uniface. It acts as a wrapper that loads a shared library (which you create) and calls a specified entry point function.&lt;/p&gt;

&lt;p&gt;Because &lt;code&gt;u3gl&lt;/code&gt; is already distributed as an executable linked with the correct C++ compiler, it handles the C++ runtime initialization on behalf of your shared library. This means you, as the 3GL developer, only need to link a shared library—executable linking is no longer required.​&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Implement u3gl
&lt;/h2&gt;

&lt;p&gt;Here is a step-by-step guide on how to convert a standard call-in program to use &lt;code&gt;u3gl&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Refactor the Entry Point
&lt;/h3&gt;

&lt;p&gt;Consider a standard call-in program &lt;code&gt;callin.c&lt;/code&gt; that uses &lt;code&gt;main&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;h3gl.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;unifbeg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;urun&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;unifend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To use &lt;code&gt;u3gl&lt;/code&gt;, rename the entry point from &lt;code&gt;main&lt;/code&gt; to a custom function name, for example, &lt;code&gt;callin&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;h3gl.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cm"&gt;/* Changed from main to callin */&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;callin&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;unifbeg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;urun&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;unifend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Compile as a Shared Library
&lt;/h3&gt;

&lt;p&gt;Instead of compiling an executable, you must compile and link the code into a shared library (e.g., &lt;code&gt;callin.so&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Example commands (Solaris syntax):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;cc &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nt"&gt;-mt&lt;/span&gt; &lt;span class="nt"&gt;-KPIC&lt;/span&gt; &lt;span class="nt"&gt;-I3gl&lt;/span&gt;/include callin.c
&lt;span class="nv"&gt;$ &lt;/span&gt;cc &lt;span class="nt"&gt;-G&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; defs &lt;span class="nt"&gt;-mt&lt;/span&gt; &lt;span class="nt"&gt;-KPIC&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; lib/libcallin.so &lt;span class="nt"&gt;-lc&lt;/span&gt; &lt;span class="nt"&gt;-L&lt;/span&gt;./lib &lt;span class="nt"&gt;-lucall&lt;/span&gt; &lt;span class="nt"&gt;-lurtl&lt;/span&gt; &lt;span class="nt"&gt;-lulib&lt;/span&gt; &lt;span class="nt"&gt;-lyrtl&lt;/span&gt; callin.o
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Flags used here:​&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;-KPIC&lt;/code&gt;: Produces position-independent code (required for shared libraries on Solaris).&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;-G&lt;/code&gt;: Instructs the linker to produce a shared library.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;-z defs&lt;/code&gt;: Produces an error if symbols cannot be resolved at link time (highly recommended to catch issues early).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Run with u3gl
&lt;/h3&gt;

&lt;p&gt;Once the shared library is created (preferably in the Uniface &lt;code&gt;lib&lt;/code&gt; directory to avoid &lt;code&gt;LD_LIBRARY_PATH&lt;/code&gt; issues), you use &lt;code&gt;u3gl&lt;/code&gt; to run it.&lt;/p&gt;

&lt;p&gt;Syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;bin/u3gl &lt;span class="nt"&gt;--shared&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;libcallin.so &lt;span class="nt"&gt;--func&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;callin ENT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, &lt;code&gt;ENT&lt;/code&gt; is a form passed as an argument to the function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simplifying the Execution
&lt;/h2&gt;

&lt;p&gt;The full syntax allows for customization via switches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;--shared=SharedObjectName&lt;/code&gt;: Defaults to &lt;code&gt;libProgramname.so&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;--func=FunctionName&lt;/code&gt;: Defaults to &lt;code&gt;Programname&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;--verbose&lt;/code&gt;: Useful for troubleshooting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pro Tip:&lt;/strong&gt; You can create a symbolic link or copy of &lt;code&gt;u3gl&lt;/code&gt; and name it match your program (e.g., &lt;code&gt;callin&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;If you rename &lt;code&gt;u3gl&lt;/code&gt; to &lt;code&gt;callin&lt;/code&gt;, the utility automatically defaults the &lt;code&gt;--shared&lt;/code&gt; and &lt;code&gt;--func&lt;/code&gt; parameters to match the program name. You can then run it simply as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;callin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This runs the code without the user needing to know that &lt;code&gt;u3gl&lt;/code&gt; is handling the execution in the background.​&lt;/p&gt;

&lt;h2&gt;
  
  
  Important Considerations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Platform Support:&lt;/strong&gt; This functionality is available only on Unix and Linux platforms.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Environment:&lt;/strong&gt; As with standard Uniface applications, ensure &lt;code&gt;insunis&lt;/code&gt; is called and &lt;code&gt;LD_LIBRARY_PATH&lt;/code&gt; is set correctly.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Arguments:&lt;/strong&gt; Command line parameters (like form names) are passed at the end of the command line. If a parameter starts with &lt;code&gt;--&lt;/code&gt;, use a double-dash separator:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bin/u3gl &lt;span class="nt"&gt;--shared&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;foo.so &lt;span class="nt"&gt;--func&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bar &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--hello--&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article was created with the help of AI.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Simplifying Legacy Integration: Using Call-In Stubs in Uniface 10.4</title>
      <dc:creator>Peter + AI</dc:creator>
      <pubDate>Sun, 23 Nov 2025 13:06:28 +0000</pubDate>
      <link>https://forem.com/petercode/simplifying-legacy-integration-using-call-in-stubs-in-uniface-104-2bg8</link>
      <guid>https://forem.com/petercode/simplifying-legacy-integration-using-call-in-stubs-in-uniface-104-2bg8</guid>
      <description>&lt;h1&gt;
  
  
  Simplifying Legacy Integration: Using Call-In Stubs in Uniface 10.4
&lt;/h1&gt;

&lt;p&gt;Integration between modern 4GL environments and traditional C (3GL) code often feels like a high-wire act. You have to manually juggle memory handles, parameter mappings, and execution states. One slip—like a mismatched data type or a forgotten handle release—and your application crashes.&lt;/p&gt;

&lt;p&gt;If you are working with &lt;strong&gt;Uniface 10.4&lt;/strong&gt;, there is a better way. Instead of writing verbose, error-prone C code to activate Uniface services, you can use &lt;strong&gt;Call-In Stubs&lt;/strong&gt;. This feature generates clean C wrappers for your 4GL services, handling the heavy lifting automatically.&lt;/p&gt;

&lt;p&gt;Here is how to streamline your C-to-Uniface integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Old Way: Manual &amp;amp; Tedious
&lt;/h2&gt;

&lt;p&gt;Let’s say you need to call a simple operation named &lt;code&gt;CALLIN&lt;/code&gt; inside a Uniface service &lt;code&gt;CALLINSRV&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Without stubs, you are forced to write about 20 lines of boilerplate code just to fire a single trigger. You have to manually instantiate the environment, service, and operation, and then painstakingly map every parameter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;h3gl.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;UHACT&lt;/span&gt; &lt;span class="n"&gt;hEnv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hOp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;opStat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cm"&gt;/* 1. Manual Lifecycle Management */&lt;/span&gt;
    &lt;span class="n"&gt;uecreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"my.asn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hEnv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;uinstnew&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hEnv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"CALLINSRV"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UDEFAULT_COMM_MODE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;uinstopr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"CALLIN"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hOp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="cm"&gt;/* 2. The actual call */&lt;/span&gt;
    &lt;span class="n"&gt;uopract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hOp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;opStat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="cm"&gt;/* 3. Manual Cleanup (Order matters!) */&lt;/span&gt;
    &lt;span class="n"&gt;uinstdel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;uedelete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hEnv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;ufreeh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hOp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;ufreeh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hIn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;ufreeh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hEnv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Pain Points:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Verbose:&lt;/strong&gt; It is hard to see the business logic amidst the infrastructure code.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Fragile:&lt;/strong&gt; If you add a parameter to your Uniface service later, you have to rewrite the C code to push/pop that parameter manually.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The New Way: Generating Call-In Stubs
&lt;/h2&gt;

&lt;p&gt;Uniface can examine your compiled service and generate a C "stub" file. This file contains wrapper functions that handle all the Uniface plumbing for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Compile Your Service
&lt;/h3&gt;

&lt;p&gt;Ensure your Uniface service is compiled and the &lt;strong&gt;UAR file&lt;/strong&gt; is up to date. The generator reads from the compiled descriptor, not the source code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Generate the Stub
&lt;/h3&gt;

&lt;p&gt;Run the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ide /sti ServiceName
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uniface creates two files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;ui_servicename.h&lt;/code&gt; (Header file)&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;ui_servicename.c&lt;/code&gt; (Source file containing the wrapper logic)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For our &lt;code&gt;CALLINSRV&lt;/code&gt; example, this generates functions like &lt;code&gt;ui_callin_callinsrv()&lt;/code&gt;, which maps directly to your 4GL operation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Refactored C Code
&lt;/h3&gt;

&lt;p&gt;Now your C code becomes drastically simpler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;h3gl.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;span class="cm"&gt;/* In a real project, link the .obj/.o file instead of including .c */&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;ui_callinsrv.c&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt; &lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;UHACT&lt;/span&gt; &lt;span class="n"&gt;hEnv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cm"&gt;/* Initialize the environment once */&lt;/span&gt;
    &lt;span class="n"&gt;uecreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"my.asn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hEnv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="cm"&gt;/* The complex logic is now a single function call */&lt;/span&gt;
    &lt;span class="n"&gt;ui_callin_callinsrv&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="cm"&gt;/* Tear down */&lt;/span&gt;
    &lt;span class="n"&gt;uedelete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hEnv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;ufreeh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hEnv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ⚠️ Common Pitfalls &amp;amp; Best Practices
&lt;/h2&gt;

&lt;p&gt;While stubs make life easier, there are still traps for the unwary.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Don't Forget the Lifecycle!
&lt;/h3&gt;

&lt;p&gt;A common misconception is that the stub handles &lt;em&gt;everything&lt;/em&gt;. &lt;strong&gt;It does not.&lt;/strong&gt; The stub only manages the &lt;strong&gt;Service&lt;/strong&gt; and &lt;strong&gt;Operation&lt;/strong&gt; handles. You are still responsible for creating the Uniface Environment (&lt;code&gt;uecreate&lt;/code&gt;) before calling the stub and destroying it (&lt;code&gt;uedelete&lt;/code&gt;) afterward.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Symptom:&lt;/strong&gt; If you forget &lt;code&gt;uecreate&lt;/code&gt;, your program will likely crash with a segmentation fault or return an obscure error code immediately upon calling the stub.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Linking vs. Including
&lt;/h3&gt;

&lt;p&gt;In the example above, we &lt;code&gt;#include&lt;/code&gt; the &lt;code&gt;.c&lt;/code&gt; file for simplicity. In a professional build pipeline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Don't:&lt;/strong&gt; &lt;code&gt;#include "ui_service.c"&lt;/code&gt; in multiple places. This leads to "duplicate symbol" errors during linking.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Do:&lt;/strong&gt; Compile &lt;code&gt;ui_service.c&lt;/code&gt; separately into an object file (&lt;code&gt;.o&lt;/code&gt; or &lt;code&gt;.obj&lt;/code&gt;) and link it to your main application.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Stale Signatures
&lt;/h3&gt;

&lt;p&gt;If you update your Uniface service (e.g., add a new parameter) but forget to run &lt;code&gt;ide /sti&lt;/code&gt; again, your C code is now calling a ghost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Risk:&lt;/strong&gt; The stub will try to map parameters that don't exist or have changed types, leading to runtime corruption that is very hard to debug.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Make stub generation a standard step in your build pipeline whenever UARs change.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Never Edit the Stub Manually
&lt;/h3&gt;

&lt;p&gt;You might be tempted to add a &lt;code&gt;printf&lt;/code&gt; inside the generated &lt;code&gt;ui_servicename.c&lt;/code&gt; for debugging.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't do it.&lt;/strong&gt; Any time you regenerate the stub, your changes are wiped out. If you need logging, wrap the stub call in your own wrapper function.&lt;/p&gt;

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

&lt;p&gt;Call-In Stubs in Uniface 10.4 turn a complex, 20-line manual integration task into a robust, 3-line function call. By automating the parameter mapping, you not only save time but also eliminate an entire class of "fat-finger" errors in your C/Uniface bridge.&lt;/p&gt;

&lt;p&gt;Happy Coding&lt;/p&gt;

&lt;p&gt;A small note on the side. This article was created with the help of AI.&lt;/p&gt;

</description>
      <category>c</category>
      <category>tooling</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>🚀 Deep Dive: The Uniface 3GL Call-In API &amp; C Integration</title>
      <dc:creator>Peter + AI</dc:creator>
      <pubDate>Sun, 23 Nov 2025 13:00:45 +0000</pubDate>
      <link>https://forem.com/petercode/deep-dive-the-uniface-3gl-call-in-api-c-integration-29e1</link>
      <guid>https://forem.com/petercode/deep-dive-the-uniface-3gl-call-in-api-c-integration-29e1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Integrating modern C/C++ applications with established Uniface systems doesn't have to be a black box.&lt;/p&gt;

&lt;p&gt;The Uniface 3GL Call-In API acts as the bridge, mirroring the power of the ProcScript &lt;code&gt;activate&lt;/code&gt; command but from within your C code.&lt;/p&gt;

&lt;p&gt;This guide breaks down how to instantiate components and effectively manage the environment lifecycle using the &lt;code&gt;ucall&lt;/code&gt; library.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Mechanism
&lt;/h2&gt;

&lt;p&gt;The Call-In API allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Instantiate Uniface components (Forms, Services, Reports).&lt;/li&gt;
&lt;li&gt;  Execute operations with full parameter support (IN/OUT).&lt;/li&gt;
&lt;li&gt;  Control the Uniface environment (Start/Stop).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All necessary functions are bundled in the &lt;code&gt;ucall&lt;/code&gt; shared library.&lt;/p&gt;

&lt;p&gt;This is the single dependency you need to link against.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Lifecycle: A "Typical" Sequence
&lt;/h2&gt;

&lt;p&gt;The documentation often shows a sequence involving both creation and opening.&lt;/p&gt;

&lt;p&gt;Here is what happens under the hood:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;uactdef.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="c1"&gt;// 1. Start Uniface (Only if not already running!)&lt;/span&gt;
&lt;span class="n"&gt;uecreate&lt;/span&gt;&lt;span class="p"&gt;(...);&lt;/span&gt; 

&lt;span class="c1"&gt;// 2. Get Handle (Optional if you have the handle from step 1)&lt;/span&gt;
&lt;span class="n"&gt;ueopen&lt;/span&gt;&lt;span class="p"&gt;(...);&lt;/span&gt; 

&lt;span class="c1"&gt;// 3. Component Lifecycle&lt;/span&gt;
&lt;span class="n"&gt;uinstnew&lt;/span&gt;&lt;span class="p"&gt;(...);&lt;/span&gt; &lt;span class="c1"&gt;// Create Instance&lt;/span&gt;
&lt;span class="n"&gt;uopract&lt;/span&gt;&lt;span class="p"&gt;(...);&lt;/span&gt;  &lt;span class="c1"&gt;// Activate Operation&lt;/span&gt;
&lt;span class="n"&gt;uinstdel&lt;/span&gt;&lt;span class="p"&gt;(...);&lt;/span&gt; &lt;span class="c1"&gt;// Delete Instance&lt;/span&gt;

&lt;span class="c1"&gt;// 4. Cleanup&lt;/span&gt;
&lt;span class="n"&gt;uedelete&lt;/span&gt;&lt;span class="p"&gt;(...);&lt;/span&gt; &lt;span class="c1"&gt;// Shutdown Environment&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  💡 Pro Tip: uecreate vs. ueopen
&lt;/h2&gt;

&lt;p&gt;There is often confusion about when to use which.&lt;/p&gt;

&lt;p&gt;Here is the rule of thumb:&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario A: You are the "Driver" (Call-In)
&lt;/h3&gt;

&lt;p&gt;Your C program starts the process.&lt;/p&gt;

&lt;p&gt;Uniface is not running.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Action:&lt;/strong&gt; Call &lt;code&gt;uecreate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This starts the environment.&lt;/p&gt;

&lt;p&gt;You can call &lt;code&gt;ueopen&lt;/code&gt; afterwards (and generated stubs often do), but the handle from &lt;code&gt;uecreate&lt;/code&gt; is already valid.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cleanup:&lt;/strong&gt; You must call &lt;code&gt;ufreeh&lt;/code&gt; on your handle, and finally &lt;code&gt;uedelete&lt;/code&gt; to shut down Uniface.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario B: Uniface Called You (Call-Out)
&lt;/h3&gt;

&lt;p&gt;Uniface is already running and called your C function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Action:&lt;/strong&gt; Do NOT call &lt;code&gt;uecreate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Instead, call &lt;code&gt;ueopen&lt;/code&gt; to grab the existing environment handle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cleanup:&lt;/strong&gt; You must still call &lt;code&gt;ufreeh&lt;/code&gt; on the handle you got from &lt;code&gt;ueopen&lt;/code&gt; when you are done, but do NOT call &lt;code&gt;uedelete&lt;/code&gt; (you don't want to kill the parent Uniface process!).&lt;/p&gt;

&lt;h2&gt;
  
  
  The "Smart" Way: Generated Stubs
&lt;/h2&gt;

&lt;p&gt;Writing the boilerplate above manually is error-prone.&lt;/p&gt;

&lt;p&gt;Uniface allows you to generate wrapper code directly from your compiled UAR signatures.&lt;/p&gt;

&lt;p&gt;Run the following command in your CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ide /sti &amp;lt;your_component&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This generates C stubs that handle the messy &lt;code&gt;uinstnew&lt;/code&gt;/&lt;code&gt;uopract&lt;/code&gt; sequence for you, allowing you to call Uniface operations as if they were native C functions.&lt;/p&gt;

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

&lt;p&gt;Whether you are manually managing handles for fine-grained control or using &lt;code&gt;ide /sti&lt;/code&gt; for rapid development, the Call-In API is robust.&lt;/p&gt;

&lt;p&gt;Just remember: always match your &lt;code&gt;ueopen&lt;/code&gt;/&lt;code&gt;uecreate&lt;/code&gt; calls with a corresponding &lt;code&gt;ufreeh&lt;/code&gt; to prevent memory leaks.&lt;/p&gt;

&lt;p&gt;This article was created with the help of AI.&lt;/p&gt;

</description>
      <category>uniface</category>
      <category>c</category>
      <category>legacy</category>
      <category>api</category>
    </item>
  </channel>
</rss>
