Netremote
This project provides the ability to remotely control network components such as Wi-Fi access points typically used to test network functionality on Windows.
Install / Use
/learn @microsoft/NetremoteREADME
Network Remote Control
This project provides the ability to remotely control network components such as Wi-Fi access points typically used to test network functionality on Windows.
Project Structure
This project is organized to allow primary development on both Linux and Windows. Hence, CMake is used as the build system generator. Consequently, there is an OS-independent source tree under src, and OS-dependent source trees linux and windows.
Coding Guidelines
Where possible, C++ Standard Library primitives should be used for interoperability between common and OS-dependent code. The use of OS-specific primitives and libraries is reserved for scenarios where they are strictly needed (eg. calling an OS/System API), or where the highest possible performance is required and only the OS implementation can provide this.
The coding style is dictated by both .clang-format and .clang-tidy files at the root of the project. Please configure your editor to format and lint sources accordingly. Above all, the coding style should be kept as consistent as possible. The exact style used is not overly important.
To help keep the code consistent, please follow these general guidelines:
- DO use spaces instead of tabs.
- DON'T prefix variable names to describe their type, scope, or visibility.
- DO use
std::filesystemfor storage and UNIX path separators (/) where possible. - DO use
std::formatfor string formatting. - DO use complete words for variable and function names.
- DO use the following table for variable naming:
| Block | Style | Example |
| ----- | ----- | -------- |
| Types | PascalCase | struct AccessPoint {}; |
| Functions | PascalCase | AccessPoint GetAccessPointById(std::string_view id) |
| Variables | camelCase | AccessPoint accessPoint{}; |
| Parameters | camelCase | void registerEventCallback(AccessPointEventCallback& eventCallback) |
| Namespaces | lowercase | namespace microsoft::net::remote |
| Public Members | PascalCase | struct AccessPoint { std::string Id; } |
| Private Members | camelCase with m_ prefix | class AccessPoint { uint64_t m_sessionId; } |
Commit Signing
While not required, it is strongly recommended to configure git with a GNU Privacy Guard (GPG) signing key. This allows GitHub to verify commits were pushed by a specific user and will show a green Verified status beside each verified commit. Follow these steps to configure a signing key for commit verification:
- Install the gpg tools for the target operating system (see the OS-specific
READMEfiles for details: Windows, Linux). - Generate a gpg key
- Add the gpg key to your github account
- Configure git to use the gpg key. This link will also tell you how to use gpg signing with an ssh key. Additionally, if you wish tell git to use a type any type of signing by default, be it gpg, ssh or X.509, you need to run the following command
git config --global commit.gpgsign true
Development Environment Setup
Pre-requisities:
- C++ 23 Compiler
- CMake version >= 3.25
Compiler
Both a compiler and standard C++ library supporting C++23 are required. The C++ reference pages for C++23 core language features and C++23 library features provide complete details about current compiler and library support.
Windows
Visual Studio 2022 generally satisfies the requirements, however, the full integrated development environment (IDE) is not needed. A much leaner alternative for those using other editors such as Visual Studio Code can instead install Visual Studio Build Tools. The build tools come with a C++ compatible compiler and standard library. Detailed development environment setup instructions can be found in the Windows README.
Linux
g++ or LLVM/Clang are suitable, however, some care must be taken to obtain a compatible standard library. A known, working environment is ubuntu 24.04 (noble) with clang 18.1.3 and LLVM 18.1.3. Both are both provided by the official ubuntu package repository so can be installed using apt. Detailed development environment setup instructions can be found in the Linux README.
CMake
CMake may be installed in any form, as long as the version meets the minimum. One popular way of installing it on Windows is to use Chocolately with choco install -y cmake. On Linux, all standard package managers provide a cmake package (eg. apt-get install -y cmake, yum install -y cmake, etc.).
To bootstrap the build environment, instruct CMake to generate the build files. It is strongly recommended to do this in a directory that is separate from the source; this allows one to easily destroy and recreate the build environment without affecting the checked-out source and changes in progress. Typically, a new directory called build at the top-level project tree is used for this purpose:
git clone git@github.com:microsoft/netremote.git
cd netremote
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -Bbuild
cmake --build build
CMake with Visual Studio Code
Alternatively, Microsoft provides a CMake Tools Visual Studio Code extension that automates this process. After installing the extension and cloning the repository in VSCode, hit <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd> or <kbd>F1</kbd>, then find the command CMake: Delete Cache and Reconfigure. This will generate the build configuration in a build folder at the top-level of the source tree. Once done, you can build the ALL target (default) with the CMake: Build command again (<kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd> or <kbd>F1</kbd>, type cmake, find the command).
In general, you set a build target and variant, then use the CMake: Build command to build incrementally. All build targets can be found in the CMake: Project Outline activity bar, but a list of them will also be shown when invoking actions that involve targets.
You may need to enable unsupported presets versions. To do this, press File > Preferences then search for 'presets' and enable the option CMake: Allow Unsupported Presets Versions.
Docker-based Environment
A Docker image is available that provides a known working Linux development environment with all of the tools necessary pre-installed:
- abeltrano/netremote-dev: A container image for development of the project, including hostapd and building modules for the WSL2 kernel.
To use the Docker container image, install Docker on your development machine, then start an interactive instance, which will bring you to a bash shell:
docker run -it abeltrano/netremote-dev

This provides the full development environment but does not sync source code. So instead of using the docker image directly, it is recommended to use a development container described in the Dev Container section below.
Dev Container
The docker images are also configured for use with dev containers. Many IDEs have built-in support for development containers, including but not limited to VSCode. This method is the easiest and fastest way to get a working development environment, especially if you're already using VSCode.
VSCode
Use of dev containers in VSCode is the recommended and officially supported development environment. To use this, install Docker on your development machine and install the Dev Containers VSCode extension. The Dev Containers extension has two (2) primary ways to use it:
-
[Recommended] Cloning directly into a named volume in the container.
Clone the repository with the dev containers command to use a named volume: press <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>P</kbd> or <kbd>F1</kbd> and select the Dev Containers: Clone Repository in Named Container Volume dev container extension command. A named volume is a persistent filesystem that is mounted in the container and used to store the repository source code. This allows the source code to survive across container stops, removals, and deletions. As part of the command, you will be prompted to select the named volume to use. On first run, no volumes will have been created so select Create a new volume and give it any name you want (eg
source). In subsequent command invocations to clone the repository, the source volume will exist and you can select it from the list.