
To do this, we bound the search paths (the property MSBuildExtensionsPath) of our toolset to a special environment variable, which PVS-Studio_Cmd.exe process specifies according to the type of the checked project. We found the solution due to the ability to easily modify "our own" toolset. In our "installation" of MSBuild it was not present. When installing the corresponding component in Visual Studio, these extensions are defined in a separate directory next to MSBuild. For example, these types of projects include WebApplication, Portable.

It turned out that the toolset itself is not enough for the projects that are using MSBuild extensions - these are additional build steps. That was not the end of our troubles with MSBuild. Roslyn has all the necessary information to get the semantic model now - all the references to other projects and libraries are expanded (as analyzed source code could contain types declared in these dependencies) all the prebuild steps are performed, all the dependencies are restored/copied and so on. As we remember, we have a "fake" build, and so when everything is ready, the compiler call will not happen. The csc task will prepare everything for the call of the compiler itself (usually it is a separate command line utility csc.exe). In accordance with this file, the appropriate library, containing the implementation of the csc task, will be found and loaded. A tasks file is an xml file, containing paths to the libraries, implementing standard build tasks. MSBuild will need to find a library where this step is implemented directly, and the tasks file from the selected toolset will be used for that. Let's move to the segment of the Build Tools diagram.
