Skip to content

cpsdenis/native-messaging-sample

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

C++ Native Messaging Host Sample

A lightweight, cross-platform reference implementation of a browser Native Messaging Host written in C++. This repository provides a boilerplate for secure, bi-directional communication between a Chromium Web Extension and a local C++ executable via standard I/O (stdin/stdout).

This implementation has been compiled, deployed, and verified to work in user-space across the following environments:

Operating System Browser Coverage Toolchain / Compiler
Windows 10/11 (x86_64) Google Chrome, Chromium MSYS2 MinGW64 (mingw64 / cmake + Ninja)
Ubuntu Linux (x86_64) Google Chrome, Chromium Native GCC (g++ / cmake)
Asahi Linux (arm64) Vivaldi Native GCC (g++ / cmake)
macOS (M1 Pro) Google Chrome, Chromium Homebrew GCC (g++ / cmake)

Architecture Overview

The web extension communicates with the C++ host asynchronously. The browser spawns the native application as a separate process and manages its lifecycle via standard streams.

[ Web Extension ] 
       │  ▲
       │  │  chrome.runtime.connectNative()
       ▼  │
[ Browser Process ] 
       │  ▲
       │  │  Standard I/O Streams (stdin / stdout)
       ▼  │
[ C++ Native Host Executable ]

Project Structure

.
├── CMakeLists.txt
├── Dockerfile                      # Docker build example for Linux target
├── extension
│   ├── background.js
│   ├── icon.png
│   ├── manifest.json               # Extension Manifest (MV3)
│   ├── popup.css
│   ├── popup.html
│   └── popup.js
├── host
│   ├── io.github.cpsdenis.json     # Native Host Manifest template
│   └── src
│       ├── CMakeLists.txt
│       └── main.cpp                # C++ Native Host source code
├── LICENSE
├── Makefile
└── README.md

Protocol

Native Messaging communication relies on a structured protocol header:

  1. Every message must be prefixed with a 4-byte unsigned integer specifying the length of the following JSON string in native byte order.
  2. The total size of an individual incoming message from the browser cannot exceed 1 MB.
  3. Outgoing responses from the C++ host to the browser cannot exceed 4 MB.

Windows Stream Warning

On Windows, standard I/O defaults to Text Mode (O_TEXT), which alters \n to \r\n and truncates data at the 0x1A byte (EOF). The streams must explicitly be converted to binary mode:

#ifdef _WIN32
    _setmode(_fileno(stdin), _O_BINARY);
    _setmode(_fileno(stdout), _O_BINARY);
#endif

Prerequisites

Ensure your system has a C++17 compiler and CMake 3.12+ installed:

  • Windows (MSYS2): Open the MinGW64 terminal and install packages:
    pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake make
  • Linux (Ubuntu/Debian):
    sudo apt update && sudo apt install build-essential cmake
  • macOS (Homebrew): Install GCC and CMake via Homebrew:
    brew install gcc cmake

How to Run the Sample

Running this sample configuration requires two key phases:

1. Build and Register the Native Host

Compile the binary program and register its structural location manifest to the local system using user-space directories:

make install

2. Install the Browser Extension

  1. Open your browser and navigate directly to the extension management page: chrome://extensions.
  2. Toggle on Developer mode using the switch located in the upper-right corner.
  3. Click the Load unpacked button in the upper-left corner.
  4. Select the extension/ directory located inside this project repository workspace.
  5. Call popup-window and send message


Compilation, Installation & Registration

To make testing and deployment simple, a Makefile wrapper is provided.

⚠️ No Root Privileges Required

The build system and installation targets work entirely within the current user's profile (HKCU on Windows registry, ~/.local/share and user configurations on Unix). Never run these commands with sudo.

\$ make help

Target       Description
──────       ───────────
build        Build native host application
clean        Clean project output
debug        Print local makefile variables
help         Display this help screen
install      Build native host and install binary and manifests (User-space, no sudo)
purge        Uninstall and clean
rebuild      Clean and build the binary from scratch
reinstall    Uninstall and install
uninstall    Remove installed binary and native messaging manifests

Docker Build Example (Linux)

If you want to build the project inside a clean Linux container without installing tools locally, a Dockerfile example is included.

Execute the Docker build command from the root of your repository to trigger the compiler pipeline inside an isolated workspace:

docker build -t nmcpp .

About

A lightweight, cross-platform reference implementation of a browser Native Messaging Host written in C++.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors