Custom Code Tool

Custom Code Tool

The Custom Code feature is a built-in C# programming environment for writing custom functions that operate on HL7 messages loaded in HL7Spy. Use it when you need to go beyond the standard tools — for example:

  • Generating CSV or text reports from message data

  • Filtering or splitting messages into new tabs based on complex criteria

  • Validating messages against business rules

  • Transforming or anonymizing patient data

  • Filing data into a database

  • Analyzing complex multi-message exchanges

Your code runs directly inside HL7Spy with full access to the parsed HL7 message model, so there is no need to export data or use external tools.

Requirements

  • Programming experience with .NET C#

  • A valid HL7Spy license

Resources

  1. HL7Spy comes with preloaded sample functions.

  2. You can find user-submitted, goal-oriented function samples here: http://hl7spy.ca/hl7-code/ .

  3. Documentation of the available classes in HL7Spy.Core can be found here:   (Right-Click after downloading and "Unblock" to view)

User Interface

The Custom Code tool can be selected by clicking on the “Custom Code” tab in the specialty tools section of the application.

image-20260411-205233.png

The Custom Code window is divided into four areas:

Area

Location

Purpose

Area

Location

Purpose

Plugin List

Left panel

Lists all your custom functions, grouped by category. Select a function to load it into the editor.

Code Editor

Center

A full-featured C# code editor with syntax highlighting, IntelliSense, error squiggles, outlining, and symbol navigation.

Plugin Explorer

Right panel

Shows the structure of the selected plugin: code files, assembly references, and embedded resources.

Output / Events

Bottom tabs

Output shows compiler diagnostics. Events shows runtime log entries produced by Log() and Assert calls.

Toolbar

Button

Shortcut

Description

Button

Shortcut

Description

Plugins

Ctrl+O

Toggle the Plugin List panel on or off.

Options

Submenu for editor settings: Show Line Numbers, Show Whitespace, Scroll to First Compiler Error, Import Legacy Plugins, Clear All Plugin Caches.

Install Plugin

Install a plugin from a .nupkg file or a NuGet feed.

Compile

Ctrl+Shift+C

Compile the current function without running it. Errors appear in the Output tab.

Run

F5

Compile and execute Run() for every message in the active tab. The button changes to Stop while running.

Run Once

F10

Compile and execute RunOnce() for the currently selected message only.

Attach Debugger

Toggle Visual Studio debugger attachment for stepping through your code.

Keyboard Shortcuts

Shortcut

Action

Shortcut

Action

F5

Run

F10

Run Once

Ctrl+Shift+C

Compile

Ctrl+S

Save current plugin

Ctrl+O

Toggle Plugin List

Ctrl+N

Navigate to next compiler error

Ctrl+P

Navigate to previous compiler error

F12

Go to Definition

F2

Rename item in Package Explorer

Delete

Remove selected item in Package Explorer or Plugin List

Working with Multiple Code Files

A plugin can contain multiple .cs files. This is useful for organizing larger functions into separate files.

  1. In the Package Explorer on the right, expand the Code node.

  2. Right-click and choose Add to create a new code file.

  3. Your main class is defined as partial class DynamicClass, so you can split it across files or add helper classes in separate files.

All code files within a plugin are compiled together as a single assembly.

Working with Multiple Code Files

A plugin can contain multiple .cs files. This is useful for organizing larger functions into separate files.

  1. In the Package Explorer on the right, expand the Code node.

  2. Right-click and choose Add to create a new code file.

  3. Your main class is defined as partial class DynamicClass, so you can split it across files or add helper classes in separate files.

All code files within a plugin are compiled together as a single assembly.

Execution Model

Custom functions follow a well-defined lifecycle. Understanding this lifecycle is key to writing effective code.

Lifecycle

  1. OnUserInterfaceSetup(UserInterfaceElements) — Called before anything else. Lets you customize toolbar buttons (rename, hide, enable/disable).

  2. OnStart() — Called once on the UI thread before the first message is processed. Use it to initialize objects, open files, prompt the user for input, or set up state.

  3. Message processing — depends on which button was pressed:

    • Run (F5): Run() is called once for each message in the active tab, from first to last.

    • Run Once (F10): RunOnce() is called a single time for the currently selected message.

  4. OnFinish() — Called once on the UI thread after all messages have been processed. Use it for cleanup, writing summary output, or closing files.

  5. OnError(Exception ex) — Called on the UI thread if an unhandled exception occurs during Run() or RunOnce().

After execution completes, any message collections you created via SaveMessage() are automatically opened as new tabs in HL7Spy.

Run vs. RunOnce

 

Run (F5)

Run Once (F10)

 

Run (F5)

Run Once (F10)

Method called

Run()

RunOnce()

Messages processed

Every message in the active tab

Only the currently selected message

Typical use

Batch operations, filtering, reporting

Inspecting or modifying a single message

You can check RunTypeRequested at runtime to determine which mode was triggered.

Plugin Management

Each custom function is stored as a plugin package (internally a .nupkg file). The Plugin List on the left shows all your functions, grouped by category.

Creating a Plugin

  1. Click the Add (+) button in the Plugin List toolbar.

  2. Enter a Category (optional, for grouping) and a Name.

  3. A new plugin is created with a default code template. Press Ctrl+S to save.

Plugin Operations

Operation

Description

Operation

Description

Save (Ctrl+S)

Save the current plugin. Changes are written to the package file on disk.

Revert

Discard unsaved changes and reload from the last saved package file.

Clone

Create a copy of the selected plugin with a new name.

Rename

Change the name and/or category of the selected plugin.

Delete

Remove the selected plugin(s). Supports multi-select.

Install Plugin

Open the Install Plugin dialog to install from a NuGet feed or browse for .nupkg files. See below for details.

Installing Plugins

There are three ways to install a plugin package into HL7Spy:

  1. From the HL7Spy Plugin Feed (NuGet)

  2. From a .nupkg file on disk

  3. By dragging and dropping .nupkg files onto the Plugin List

All three methods are accessed through the Install Plugin button on the main Custom Code toolbar or the Plugin List toolbar.

Installing from the HL7Spy Plugin Feed

Click Install Plugin to open the Install Plugin dialog. The dialog connects to the HL7Spy Plugin Feed and displays all available plugins.

The dialog has the following layout:

Area

Description

Area

Description

Plugin Grid (left)

Lists available plugins with columns: checkbox (for selection), Plugin (package ID), Version, and Description. Use the filter row at the top of the grid to narrow results by typing in any column.

Details Panel (right)

Shows metadata for the selected plugin: name, version, description, summary, authors, tags, project URL, license URL, download count, and publish date.

Bottom Bar

Status text, Refresh, Browse..., Install, and Cancel buttons.

To install from the feed:

  1. Wait for the plugin list to load (happens automatically when the dialog opens).

  2. Use the filter row to find the plugin(s) you want.

  3. Check the checkbox next to one or more plugins.

  4. Click Install.

  5. Each selected plugin is downloaded and imported. If a plugin with the same name already exists, you will be prompted to choose how to handle the conflict (see Duplicate Package Handling below).

  6. The dialog closes and the newly installed plugin(s) appear in your Plugin List.

The Refresh button reloads the plugin list from the feed. To avoid excessive server requests, refresh is rate-limited to once every 15 minutes. If you click Refresh during the cooldown period, a message indicates how long until refresh is available again.

Installing from a File

If you have a .nupkg plugin file (for example, shared by a colleague or downloaded from another source), you can install it using the Browse... button in the Install Plugin dialog.

  1. Click Install Plugin to open the dialog.

  2. Click Browse... at the bottom of the dialog.

  3. In the file picker, select one or more .nupkg files. Multi-select is supported.

  4. Each file is imported. If a duplicate package name is detected, you are prompted to resolve it (see below).

  5. The dialog remains open after a file-based install, so you can continue to install additional plugins from the feed or from other files. The status bar shows how many plugins were installed.

Installing by Drag and Drop

You can also drag one or more .nupkg files directly from Windows Explorer onto the Plugin List panel in the Custom Code window. Each file is imported using the same process as the Browse method, including duplicate detection.

Duplicate Package Handling

When installing a plugin whose package name already exists in your Plugin List, HL7Spy prompts you with three options:

Choice

Effect

Choice

Effect

Yes (Overwrite)

Replace the existing plugin with the incoming package. The existing plugin’s code, references, and resources are replaced with the contents of the new package.

No (Create Unique)

Import the plugin as a new entry with a unique name (a numeric suffix is appended, e.g. MyPlugin.2). Both the old and new versions exist side by side.

Cancel (Skip)

Skip this plugin and continue with any remaining plugins in the batch.

When installing multiple plugins in a batch (either from the feed or by selecting multiple files), the duplicate prompt appears individually for each conflicting plugin. Non-conflicting plugins are imported without prompting.

Import Legacy Plugins

If you have custom functions from an earlier version of HL7Spy that used the XML storage format, you can import them via Options → Import Legacy Plugins. The legacy XML files are automatically converted to the current package format.