# How to Use Ghidra's Task Monitor and Progress Tracking in Scripts

> Learn to use Ghidra's task monitor and progress tracking in scripts. Implement initialize incrementProgress and checkCancelled for better script control and user feedback.

- Repository: [National Security Agency/ghidra](https://github.com/NationalSecurityAgency/ghidra)
- Tags: how-to-guide
- Published: 2026-03-04

---

**Ghidra scripts report execution progress and handle cancellation by calling methods on the built-in `TaskMonitor` instance, such as `initialize()`, `incrementProgress()`, and `checkCancelled()`.**

The NationalSecurityAgency/ghidra repository provides a polymorphic `TaskMonitor` architecture that enables consistent progress tracking across GUI, headless, and console execution modes. By leveraging the `monitor` field provided by the `GhidraScript` base class, analysts can write responsive scripts that display progress bars in the GUI and run silently in batch operations without code changes.

## Understanding the TaskMonitor Architecture

The framework centers on the `ghidra.util.task.TaskMonitor` interface, defined in [`Ghidra/Framework/Utility/src/main/java/ghidra/util/task/TaskMonitor.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Ghidra/Framework/Utility/src/main/java/ghidra/util/task/TaskMonitor.java). This contract specifies methods for **progress initialization**, **incremental updates**, **status messaging**, and **cancellation detection**.

Ghidra implements this interface through several layers:

- **TaskMonitor.DUMMY**: A no-op implementation (backed by `StubTaskMonitor`) injected during headless execution when no UI is available.

- **ConsoleTaskMonitor**: Outputs progress to standard output, utilized in testing and command-line utilities ([`Ghidra/Framework/Generic/src/main/java/ghidra/util/task/ConsoleTaskMonitor.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Ghidra/Framework/Generic/src/main/java/ghidra/util/task/ConsoleTaskMonitor.java)).

- **TaskMonitorComponent**: A Swing component rendering visual progress bars and cancel buttons in the GUI ([`Ghidra/Framework/Docking/src/main/java/ghidra/util/task/TaskMonitorComponent.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Ghidra/Framework/Docking/src/main/java/ghidra/util/task/TaskMonitorComponent.java)).

Script integration occurs through `ghidra.app.script.GhidraScript` ([`Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScript.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScript.java)). The base class declares a protected `monitor` field that the framework populates automatically via `ScriptControls`. For headless runs, `GhidraScriptRunner` ([`Ghidra/Features/Base/src/main/java/ghidra/app/util/headless/GhidraScriptRunner.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Ghidra/Features/Base/src/main/java/ghidra/app/util/headless/GhidraScriptRunner.java)) constructs `ScriptControls` with `TaskMonitor.DUMMY`, ensuring scripts can call monitor methods without null checks.

## Core Workflow for Progress Tracking

All Ghidra scripts follow a consistent pattern to implement user feedback and cancellation support.

### Initialize the Monitor

Call `monitor.initialize(totalWork)` once at the beginning, passing the total number of work units. Pass `-1` for indeterminate progress when the total scope is unknown.

### Check for User Cancellation

Inside every significant loop, invoke `monitor.checkCancelled()`. According to the source code in [`TaskMonitor.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/TaskMonitor.java), this method throws `CancelledException` immediately when the user presses the cancel button in the GUI, allowing scripts to terminate cleanly and release resources.

### Update Progress and Messages

Advance the progress bar using `monitor.incrementProgress(amount)` or set an absolute value with `monitor.setProgress(value)`. Update the status line via `monitor.setMessage("status text")` to inform users of current operations.

## Code Examples

### Jython (Python) Script

Jython scripts access the pre-bound `monitor` variable, following the pattern demonstrated in [`Ghidra/Features/Jython/ghidra_scripts/ghidra_basics.py`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Ghidra/Features/Jython/ghidra_scripts/ghidra_basics.py).

```python
import time

# 1. Initialize for 10 steps

monitor.initialize(10)

for i in range(10):
    # 2. Respond to cancellation

    monitor.checkCancelled()
    
    # Simulate work

    time.sleep(0.5)
    
    # 3. Update progress

    monitor.incrementProgress(1)
    
    # 4. Update status message

    monitor.setMessage("Processing item %d of 10" % (i + 1))

```

### Java Ghidra Script

Java scripts extend `GhidraScript` and access the inherited `monitor` field populated by the framework during `execute()`.

```java
public class MyAnalysisScript extends GhidraScript {
    
    @Override
    protected void run() throws Exception {
        // Initialize for 5 operations
        monitor.initialize(5);
        
        for (int i = 0; i < 5; i++) {
            // Throw CancelledException if user pressed Cancel
            monitor.checkCancelled();
            
            // Perform work
            doWork(i);
            
            // Update progress and message
            monitor.incrementProgress(1);
            monitor.setMessage("Finished step " + (i + 1) + " of 5");
        }
    }
    
    private void doWork(int step) {
        // Implementation-specific analysis
    }
}

```

### Headless Execution

When launched from the command line, `GhidraScriptRunner` instantiates `TaskMonitor.DUMMY`:

```java
ScriptControls controls = new ScriptControls(System.out, System.err, TaskMonitor.DUMMY);
script.execute(state, controls);

```

The same script code works without modification; progress calls become no-ops, and `checkCancelled()` never throws, enabling batch processing without UI dependencies.

### Console-Based Monitoring

For tests or command-line tools requiring visibility, explicitly instantiate `ConsoleTaskMonitor`:

```java
TaskMonitor monitor = new ConsoleTaskMonitor();
monitor.initialize(100);
for (int i = 0; i < 100; i++) {
    monitor.checkCancelled();  // Prints cancellation status on Ctrl-C
    // ... work ...
    monitor.incrementProgress(1);
    monitor.setMessage(" processed " + i);
}

```

## Summary

- **TaskMonitor interface**: Core contract defined in [`TaskMonitor.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/TaskMonitor.java) providing `initialize()`, `incrementProgress()`, `setMessage()`, and `checkCancelled()` methods.

- **Automatic injection**: `GhidraScript` base class provides the `monitor` field; `GhidraScriptRunner` handles headless setup with `TaskMonitor.DUMMY`.

- **Cancellation handling**: `checkCancelled()` throws `CancelledException` when users press the cancel button, enabling graceful termination.

- **Cross-mode compatibility**: Identical script code operates in GUI mode (visual progress bar via `TaskMonitorComponent`) and headless mode (silent operation via `TaskMonitor.DUMMY`).

- **Console alternative**: `ConsoleTaskMonitor` enables text-based progress reporting in terminal environments.

## Frequently Asked Questions

### What happens if I don't use the TaskMonitor in my Ghidra script?

The script executes normally but provides no progress feedback or cancellation capability. In GUI mode, the progress bar remains empty; in headless mode, the monitor operates as a no-op. Long-running operations cannot be interrupted by users, forcing manual process termination.

### How do I make a Ghidra script cancellable by users?

Insert `monitor.checkCancelled()` inside every major loop or long-running operation. As implemented in the source code, this method detects the cancel button state and throws `CancelledException` immediately, terminating the script execution cleanly and allowing resource cleanup.

### Can I use the same progress tracking code for GUI and headless execution?

Yes. The polymorphic design ensures `TaskMonitor.DUMMY` (injected by [`GhidraScriptRunner.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/GhidraScriptRunner.java) for headless runs) implements the full `TaskMonitor` interface. Progress calls execute as silent no-ops, while `checkCancelled()` returns normally without throwing, allowing identical scripts to run in both environments without conditional logic.

### Where is the TaskMonitor interface defined in the Ghidra source code?

The core interface resides at [`Ghidra/Framework/Utility/src/main/java/ghidra/util/task/TaskMonitor.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Ghidra/Framework/Utility/src/main/java/ghidra/util/task/TaskMonitor.java). The Swing GUI implementation is located at [`Ghidra/Framework/Docking/src/main/java/ghidra/util/task/TaskMonitorComponent.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Ghidra/Framework/Docking/src/main/java/ghidra/util/task/TaskMonitorComponent.java), while console output handling is implemented in [`Ghidra/Framework/Generic/src/main/java/ghidra/util/task/ConsoleTaskMonitor.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Ghidra/Framework/Generic/src/main/java/ghidra/util/task/ConsoleTaskMonitor.java).