Leverage Containers to test and debug Native applications on Nano Server


Today we’d like to share improvements in the test and debug workflow while developing native applications for Nano Server. The new workflow leverages Nano Server Containers and enhancements in the Visual Studio 2017 Remote Debugger to run in a Container. By putting these two technologies together we can setup a fast and powerful dev, test and debug environment for Nano Server developers on their local machine that avoids the overhead of configuring Nano Server virtual machines and manually copying over test binaries. Let’s dig into the details.

Prerequisites

  1. Windows 10 Anniversary Edition (Professional or Enterprise)

  2. Visual Studio 2017 with the following Workloads installed:

    • Universal Windows Platform Development
    • Desktop Development with C++

      A free Community Edition is available from visualstudio.com. Visual Studio 2017 RC can be used to test before the final version of VS2017 is released.

  3. Docker for Windows (v1.13.1 or later recommended)

    • After installation, ensure Docker is configured to use Windows Containers as described in this blog post

      Free download available from Docker site

One-time setup

Once all the prerequisites are in place, it is time to perform the first time setup of the Container-based debug environment. To aid the process we have published a helper batchfile and a Dockerfile on our Github tools page.

Here are the steps to get all setup:

  1. Install the Nano Server Project Template for Native applications from the Visual Studio Gallery as described in this post , and create a new Nano Server Project. You can also use an existing Nano Server project if you have one created.

  2. In the Project settings, configure an Output directory for your project where the build artifacts should be placed.

    project_properties

  3. Build the Project to ensure the test binaries are successfully built.

  4. Download the zip file that contains the helper batchfile and Dockerfile from this location, and extract its contents

  5. Execute NanoDockerBuild.bat in the Visual Studio 2017 Developer Command Prompt (as it defines some convenient environment variables), specifying the path to the Output directory as its only parameter. The batchfile performs the following actions:

    • Copies over the OneCore version Remote Debugger binaries and Native application runtime dependencies to a local staging folder from various well known locations in the Visual Studio 2017 install directory

    • Uses the Dockerfile to build a Nano Server Container which includes the Base Container image layered with staged binaries, and specifies the entrypoint of the Container as the Visual Studio Remote Debugger (msvsmon.exe)

    • Runs the Container, mapping the test binaries location from the Container Host into the Container and outputs the ID of the Container that was created (which is also the Container’s hostname). Example execution below:

      C:\ContainerDebug>NanoDockerBuild.cmd c:\nanodebug
      
      Staging Remote Binaries.
      Building container...
      Launching Nano Container...
      
        Nano Server Container started with id: 4c19ad2927da
      
      C:\ContainerDebug>
      

      Once the Base Nano Container image is downloaded for the first time (typically ~10min), on subsequent invocations, this whole sequence should take well under a minute.

  6. Configure the Remote Debugger settings as follows:

    • Debugger to launch: Remote Windows Debugger
    • Remote Command: $(TargetFileName)
    • Working Directory: $(OutDir)
    • Remote Server Name: [enter-container-id-from-batchfile-output]
    • Connection: Remote with no authentication

      remote-debugger-settings

 

That’s it, you are ready to test and debug your native applications in a Nano Server environment!

Test and debug workflow

It is now super easy to run and debug your Nano Server application. Set breakpoints as needed and hit F5 to launch your application in the Nano Container. When the breakpoint hits, execution will stop and break into the Visual Studio debugger where you can examine execution context. Testing additional changes is very convenient, simply make the changes you want, add any new breakpoints and hit F5 to run and debug them. No more manual copy of the test binaries to the Target system is required. The entire workflow is captured in a gif below:

workflow

To resume your debug session after a system reboot, just run the NanoDockerBuild.cmd again, and update your Remote Debugger settings with the new Container ID and you will be back testing and debugging in no time!

Feedback appreciated

Hope you find this useful. As always, please be generous with your feedback, and feel free to send pull requests to our Github repo to make the scripts better. Also, let us know if you want to see any specific topic you’d like us to post about or publish sample code for.

Happy Coding!


Comments (6)

  1. John Davis says:

    How do we know what API's are available in nano? For example, can I use User Mode Scheduling?

    1. Hi,

      There are a few different ways:
      You can use the API list here: https://msdn.microsoft.com/en-us/library/mt588480(v=vs.85).aspx, its long so takes a bit to load.
      It sounds like you have existing code so you can use the NanoServerAPIScan tool from here: https://blogs.technet.microsoft.com/nanoserver/2016/04/27/nanoserverapiscan-exe-updated-for-tp5/
      If you use Visual Studio you can install the Nano Server template and it will limit you to the APIs available in Nano Server.

      Hope that helps,

      Andrew

  2. Anton says:

    Is there an equivalent docker container for 32bit applications?

    1. No, Nano Server is 64-bit only and doesn't support WoW64 (running 32-bit applications on 64-bit Windows).

  3. JeffM says:

    This is a big improvement in the workflow, but I would like to see all of it handled by Visual Studio.

    Also, I had to change line 9 of NanoDockerBuild.cmd to set UCRT_DLL_PATH="%WindowsSdkVerBinPath%\x64\ucrt". Originally it was set UCRT_DLL_PATH="%WindowsSdkBinPath%\x64\ucrt" but that was not a valid path.

  4. Jan Ringoš says:

    Hey guys, can we expect a post on changes in Nano coming up with ~1709? It would be nice to get a little more details than just "bye bye bare-metal Nano" as is everywhere else. Will some of it's features move to Server Core?

Skip to main content