-
Notifications
You must be signed in to change notification settings - Fork 51
Cpp Custom Visualizer Sample
This repo contains a sample C/C++ Custom Visualizer. The sample
changes how FILETIME variables are formatted so that instead
of showing up as a pair of unsigned 32-bit values they instead show up as a date and time.
Screenshot:
The Visual Studio C/C++ Expression Evaluator allows customization of the display of variables in the debugger based on the type of that variable (example: change the way CExampleClass variables are displayed) using .natvis files. Natvis files add rules to format a type either declaratively or by running custom code in the debugger. This custom code is called a Custom Visualizer. Most of the time it is easier and much less error prone to use the declarative approach. But Custom Visualizers are useful when formatting a type is too complicated to be done declaratively.
Natvis documentation can be found on docs.microsoft.com.
To run the sample in Visual Studio, open CppCustomVisualizer.sln from the CppCustomVisualizer directory. Then do the following:
- In Solution Explorer, right click on the 'vsix' project and use 'Set As StartUp Project'.
- Using the solution/platform configurations drop down menu from the toolbar, make sure that the solution configuration is 'Debug' and the platform is 'x86' (IMPORTANT will not work if the platform is 'x64', which is the default).
- If you using Visual Studio 2019 and you want to debug the extension, install the Microsoft Child Process Debugging Power Tool.
- Hit F5 to launch an experimental instance of Visual Studio under the debugger. NOTE: This project pulls in some NuGet packages so Visual Studio will need to be able to download packages during build. If downloading packages fails, make sure 'Allow NuGet to download missing packages during build.' from Tools -> Options -> NuGet Package Manager, is checked.
- In the Experimental Instance:
- The experimental instance should load the 'TargetApp' project
- Hit F5 to build and run 'TargetApp' under the debugger
- The debugger should stop at the
__debugbreak();line - Evaluate
creationTimein the watch window. If everything worked correctly, you should seecreationTimevisualized as a date time rather than two raw 32-bit unsigned integers.
If hitting F5 on the vsix project doesn't cause an experimental instance of VS to start, see troubleshooting instructions below.
The CppCustomVisualizer directory contains three subdirectories with source code -- dll, vsix and TargetApp. Let's look at 'dll' first since this has the most important files.
The 'dll' directory contains the Concord extension
| File | Description |
|---|---|
| _EntryPoint.cpp/.h | The one and only public (exported) class in the sample. In Concord, classes implement interfaces, and Concord calls into these classes through the implemented interfaces. Custom visualizers implement the IDkmCustomVisualizer interface. So _EntryPoint.cpp contains the implementation of this interface, which is the only interesting source code in this sample. |
| CppCustomVisualizer.natvis | The C++ Expression Evaluator (EE) uses .natvis files to control how types are formatted. For types formatted with a Custom Visualizer, the only important thing is declare the 'VisualizerId' to indicate which visualizer to use. |
| CppCustomVisualizer.vsdconfigxml | CppCustomVisualizer.vsdconfigxml is an XML file which describes the sample component – what classes does it have, which interfaces does each class implement, when should these interfaces be called. The sample’s build process runs a custom tool over this file (vsdconfigtool.exe) which validates this file and turns it into a binary file (CppCustomVisualizer.vsdconfig) which is deployed alongside CppCustomVisualizer.dll. For a custom visualizer, the important thing is to indicate that IDkmCustomVisualizer is implemented with a particular VisualizerId. |
| packages.config, packages.version.props | This project obtains Concord headers, libs and build tools from nuget.org. These two files indicate the version to obtain. |
The 'vsix' directory contains a project file used to package the sample into a .vsix file so that it can be installed into Visual Studio. The Installing Extensions page has more information about how Visual Studio extensions are installed.
| File | Description |
|---|---|
| source.extension.vsixmanifest | Declares metadata about the extension, such as its name, company, and version. |
| VSIXSourceItems.props | This declares the set of files to be included in the .vsix file for this extension. One important thing to note is that in order to support Visual Studio 2019, this extension needs to provide both an x86-compiled dll and an x64-compiled dll because, as of VS 2019, custom visualizers are usually, but not always loaded in an x64 process. Because of this we declare the dll as a vsix item explicitly rather than using project-to-project references. |
| Build-x64.targets | As mentioned in the previous item, this extension needs to compile the dll project for both x86 and x64 as part of building the extension. This file contains custom MSBuild targets to do just that. NOTE: make sure that your vsix project is configured to NOT build for x64 through Solution Build Manager or else this will cause an infinite set of builds. |
The 'TargetApp' directory contains just an example project that uses FILETIME that we will debug to show the sample in action.
When you 'F5' from your primary Visual Studio instance on the vsix project, it should start up a second 'experimental' instance of Visual Studio, and this experimental instance should load the 'TargetApp' project. If this isn't happening for you, a few troubleshooting steps:
- Make sure that your startup project is the vsix project, and the solution/platform is Debug/x86.
- Right click on the vsix project in solution explorer and bring up project properties. Then switch to the 'Debugging' tab, and make sure that the settings are correct:
- 'Debugger to launch' is
Local Windows Debugger - 'Command' is
$(DevEnvDir)devenv.exe - 'Command Arguments' is
/rootsuffix Exp $(SolutionDir)\TargetApp\TargetApp.sln - 'Working Directory' is
$(ProjectDir)
- 'Debugger to launch' is
If your debugging project settings are different then somehow the project system must have decided to ignore the defaults set in 'vsix.vcxproj'. You could try to force the project system to go back to the defaults by closing your solution, deleting ConcordExtensibilitySamples\CppCustomVisualizer\vsix\vsix.vcxproj.user and then reopening the solution. You could also just correct these settings by hand by pasting in these values into project properties.
Concord Documentation:
- Overview
- Visual Studio 2022 support
- Concord Architecture
- Getting troubleshooting logs
- Tips for debugging extensions
- Component Discovery and Configuration
- Component Levels
- Navigating the Concord API
- Obtaining the Concord API headers, libraries, etc
- Concord Threading Model
- Data Container API
- Creating and Closing Objects
- Expression Evaluators (EEs)
- .NET language EEs
- Native language EEs
- Installing Extensions
- Cross Platform and VS Code scenarios:
- Implementing components in native code:
- Worker Process Remoting
Samples: