>
>
Visual Studio 2022 — stylish and fresh.…

Nikolay Mironov
Articles: 13

Visual Studio 2022 — stylish and fresh. How PVS-Studio supported VS2022

Seems like Microsoft has just announced Visual Studio 2022. And it already came out! For us at PVS-Studio, this meant only one thing — we must support this IDE in the next PVS-Studio release. Almost everything went smoothly. However, there were some hitches that we're going to discuss today.

First impressions of the new IDE

Honestly, I really liked Visual Studio 2022. I am enjoying the new fonts — now they are kind of less sharp. Also, the colors became less acidic. Now it's not so painful to set breakpoints when debugging.

Take a look at the examples below. Here's a code fragment in Visual Studio 2019:

The same code fragment in Visual Studio 2022:

Important. Both images have a 1:1 scale.

Also, the developers tweaked the dark theme — purple looks very much in tune (VS2019 — on the left, VS2022 — on the right):

All in all, the new VS looks neat and fresh. Although I know that old schoolers did not like the new design. :)

One more feature that I really liked in Visual Studio 2022 is the upgraded IntelliCode. It never got in the way of my coding. Sometimes, it added exactly what I wanted to write:

However, there was one thing that I didn't like. Sometimes, to accept an inline suggestion, I had to use the right arrow key, not the tab key. For some reason, in certain cases, pressing tab does not accept an inline suggestion, but displays the usual tab character instead. This problem might not be common — a teammate of mine does not have it. If you know how to fix it, please write in the comments. I'd like to note that the first preview version had more of such issues. The developers of VS2022 just need more time to fix everything.

I enjoyed working with the new VS version. That's why I decided to fast-track its support in PVS-Studio and took up that task as soon as I could. I didn't even want to open VS2019 again. Not because it's bad (actually, it's pretty cool). But it seemed a bit outdated to me. As the saying goes — everything is relative.

Plugin support

Here everything went smoothly. The changes almost did not affect us. So, I just created a new solution for the plugin, updated the NuGet packages to the required versions, and did some housekeeping in XML (for example, editing .csproj files).

However, I had to fix the code a bit. There were about 5 errors that prevented the plugin solution from building successfully. These errors appeared because Microsoft slightly changed the API. But everything turned out to be not so bad. For example, here's one thing that didn't work:

int Hwnd = DTE.MainWindow.HWnd;
return new NativeWindowWrapper(new IntPtr(Hwnd));

And this is how I fixed the code:

IntPtr Hwnd = DTE.MainWindow.HWnd;
return new NativeWindowWrapper(Hwnd);

The rest I took out of the box. After I built everything, I ran the plugin to check that it worked. All icons were clickable, I successfully ran the analysis and got the results. So, one can say, updating the plugin was a breeze. My next step was to update toolsets. And then came one curious case. I can't help but tell you about it.

The most interesting case

This unexpected and curious case involved solution-level file templates. These are those things that appear when we want to add a file to the solution:

In that scenario we can see the following window that contains the templates:

As you see, PVS-Studio has two templates. I'll skip the details and say that the Filters File helps to configure the analyzer, the Suppress File — to suppress warnings. Same as in the old plugins, I could easily add the templates. There was only one problem. With the new plugin, there were no images:

What? How? Why? I couldn't answer these questions. So, I had to dive deeper and understand how they are created.

These templates have their own format. For those in the images above, the code looks as follows:

Filters.pvsconfig_template| |PVS-Studio Filters File|1|
PVS-Studio C#/C++ filters file can be used to filter,
 disable and modify C#/C++ analyzer messages on project and 
solution.|{installDir}\PVSLoader.exe|#32512| |Filters.pvsconfig

SuppressionFile.suppress_template| |PVS-Studio Suppress File|2|
An empty PVS-Studio suppression file. You can suppress analyzer messages 
in your code from 'PVS-Studio >Suppress Messages...' menu item. 
Only one suppression file per solution is allowed. 
Other files will be ignored.|{installDir}\PVSLoader.exe|#32512
| |SuppressionFile.suppress

Each position between | is responsible for certain contents. If there is a spacebar, there will be no contents. The template contents are set separately.

Let's look at the description format:

  • the name of the folder, template, or the .vsz file, such as HeaderFile.h or MyWizard.vsz;
  • the GUID of the VSPackage;
  • the name of the template;
  • the relative priority of this template file;
  • the description;
  • the path to the .exe file used to load an icon;
  • the icon ID;
  • the field used to disable or enable the "Name" and "Location" fields on the "Add New Item" dialog box;
  • the name of the file created from the template.

You can read more about this format here.

Since we don't have images, the suspicion falls on points 6 and 7. At first, I googled how to find the image ID in the executable file — but this was disappointing. :( I needed to download some special program. And all the links to such programs looked, let's say, not very official. I didn't want to take that road, so I decided to turn to IL DASM and look at the IL code. That didn't help either :). There was no mention of number 32512. "What if this number is written in another numeral system?" — I thought. So, I tried to convert it and search, but failed again. Hmm...

And that's when it hit me! I needed to try another .exe. Well, why not? I just used another file, and, finally, it worked! The problem was in the number of bits. All versions of Visual Studio up to 2022 are 32-bit. Obviously, they need the 32-bit .exe file. However, VS2022 has become 64-bit. Such a funny problem.

New toolset support

In our blog, we have articles about Visual Studio 2017 and 2019. Do take a look if you haven't already — this will help you understand the concepts I discuss in this article.

Well, the plugin support went smoothly, but the toolset support turned out to be quite an adventure. Let me explain what happened. We have the MSBuild.exe.config file where we specify various properties necessary to build a project model. Before we introduced the VS2022 support, it looked as follows:

<?xml version="1.0" encoding="utf-8"?>
 ....
 <msbuildToolsets default="Current">
  <toolset toolsVersion="Current">
   ....
   <property name="VsInstallRoot" value="$(PVSBuildTools_InstallDir_VS2019)" />
   <property name="MSBuildToolsRoot" value="$(VsInstallRoot)\MSBuild" />
   <property name="VCTargetsPath"
value="$([MSBuild]::ValueOrDefault('$(VCTargetsPath)'
,'$(MSBuildExtensionsPath32)\Microsoft\VC\v160\'))" />
   ....
  </toolset>

  <toolset toolsVersion="15.0">
   ....
   <property name="VsInstallRoot" value="$(PVSBuildTools_InstallDir_VS2017)" />
   <property name="MSBuildToolsRoot" value="$(VsInstallRoot)\MSBuild" />
   <property name="VCTargetsPath"
value="$([MSBuild]::ValueOrDefault('$(VCTargetsPath)'
,'$(VsInstallRoot)\Common7\IDE\VC\VCTargets\'))" />
   ....
  </toolset>
 </msbuildToolsets>  
</configuration>

It's only a fragment, but it's enough to understand the idea. So, we have 2 toolsets here: 'Current' for VS2019 and 15.0 for VS2017. For VS2022, Microsoft used the same name as for VS2019:

So, Tools Version for VS2019 and for VS2022 are identical. And here's the problem. We can't give two different toolsets the same name because of the way the configuration file works. That's why we decided to dynamically change the contents instead of changing the name. We keep 'Current' and continue to use environment variables to initialize toolsets. The values for these variables are specified based on the installed versions of Visual Studio or the VS version currently in use.

As a result, we have one 'Current' toolset that can work with VS2019, VS2022, and future IDE versions. Here's a diagram representing this process:

It's worth emphasizing again that we also need to keep in mind the case when the VisualStudioVersion environment variable has the 16.0 or 17.0 value. In this case, we set and use the value of the specified VS for 'Current'.

Thus, we managed to solve the current problem with different toolsets having identical names. Moreover, we made the mechanism universal and easily extensible (we hope so) for new VS versions.

.NET 6 support, Roslyn and MSBuild libraries update

Microsoft released VS2022 and .NET 6 at the same time. That's why we needed to support them both in the same PVS-Studio release. So, we were simultaneously introducing Visual Studio 2022 and .NET 6 projects analysis, .NET 6 SDK, updating MSBuild and Roslyn libraries.

I need to point out here that since we're using our BuildTools, we faced a lot of peculiarities when supporting the new .NET version. This always happens when we support a new .NET version. By the way, if you are curious about what difficulties we encountered when supporting .NET 5, see the following article.

Synchronizing our BuildTools and .NET BuildTools

If you want to know why we needed this and how we implemented it, read our articles about VS2017 and VS2019 support. Custom BuildTools may seem troublesome. However, in the real world, this approach provides greater security/flexibility.

Besides, this is a good opportunity to work with .targets / .props files, and understand PVS-Studio and the .NET ecosystem better.

Debugging Roslyn and MSBuild

Sometimes when working with Roslyn / MSBuild, developers encounter hidden problems and have to delve into the source code (for example, if a project is missing some references). PVS-Studio even has a special configuration to debug Roslyn and MSBuild, compiled from source code. :)

These (and many other) projects by Microsoft are open source — this plays into our hands. If developers need to find out something, they can debug the code and see how everything works.

It may be difficult at first. However, the more you work with these projects, the better you know their ins and outs. Opening code fragments seen several years ago, you feel like coming home.

As I said earlier — such tasks help you better understand how the compiler / assembly system works.

Switching to .NET 6 and supporting C# 10

Now, the C# PVS-Studio analyzer for Linux and macOS works under .NET 6. Besides, when we updated Roslyn, we got the C# 10 support out of the box. Yeah, we still have to update the diagnostics, dataflow, etc. But it's always great to fully understand the new syntax and semantics. After updating the MSBuild libraries, you get the new features out of the box.

So, in case you've missed this, now you can analyze your .NET6 projects. ;)

Conclusion

As I said earlier, the new Visual Studio is brilliant. Microsoft obviously did their best. The plugin update went smoothly — that's pleasing. However, while updating the toolset, we opened those closets that could have remained shut for many years.

A month has passed since we successfully supported Visual Studio 2022. We didn't break backward compatibility and received positive feedback. Special thanks to those who were interested in the plugin for this IDE and tried the beta version.

If you've wanted to try PVS-Studio with Visual Studio 2022 for a while, now is the time!