I'm trying to write a code generation tool. For this tool it's important that the generated code is available prior to building (i.e., for IntelliSense). I know Visual Studio will at least partially evaluate the project build plan automatically to generate IntelliSense, but I can't find much information on the details.
As a simpler example, let's say I want to take all items with build action None
and compile them. I have a project like this:
<Project [...]>
[...]
<Compile Include="Foo.cs" />
<None Include="Bar.cs" />
</Project>
One way to get Bar.cs
to compile is to add the following to the project:
<PropertyGroup>
<CoreCompileDependsOn>
$(CoreCompileDependsOn);IndirectCompile
</CoreCompileDependsOn>
</PropertyGroup>
<Target Name="IndirectCompile">
<CreateItem Include="@(None)">
<Output ItemName="Compile" TaskParameter="Include" />
</CreateItem>
</Target>
If I do it this way, Visual Studio acts basically the same as if Bar.cs
had the Compile
action to begin with. IntelliSense is fully available; if I make a change in Bar.cs
it's reflected immediately (well, as immediate as the background operation normally is) in IntelliSense when I'm editing Foo.cs
, and so on.
However, say instead of directly compiling the None
entry, I want to copy it to the obj
directory and then compile it from there. I can do this by changing the IndirectCompile
target to this:
<Target Name="IndirectCompile"
Inputs="@(None)"
Outputs="@(None->'$(IntermediateOutputPath)%(FileName).g.cs')"
>
<Copy SourceFiles="@(None)"
DestinationFiles="@(None->'$(IntermediateOutputPath)%(FileName).g.cs')"
>
<Output TaskParameter="DestinationFiles" ItemName="Compile" />
</Copy>
</Target>
Doing this causes IntelliSense to stop updating. The task works on build, dependency analysis and incremental building work, Visual Studio just stops automatically running it when an input file is saved.
So, that leads to the title question: How does Visual Studio choose to run targets or not for IntelliSense? The only official documentation I've found has been this, specifically the "Design-Time IntelliSense" section. I'm pretty sure my code meets all those criteria. What am I missing?
In Visual Studio 2022, open Tools -> Options -> [type in "database" in the search box] -> Text Editor -> C/C++ -> Advanced -> Recreate Database = TRUE, and then reopen the solution. Save this answer.
IntelliSense is a code-completion aid that includes a number of features: List Members, Parameter Info, Quick Info, and Complete Word. These features help you to learn more about the code you're using, keep track of the parameters you're typing, and add calls to properties and methods with only a few keystrokes.
Please try: Go to Visual Studio Installer, click Modify , uncheck IntelliCode in Individual components, then click Modify button to save the change, wait for the installation to complete, and then reinstall IntelliCode . In Visual Studio, go to Tools->Options->IntelliCode to check if the setting is Default.
After a few days of experimenting and poking around in the debugger I think I have found the answer, and unfortunately that answer is that this is not possible (at least not in a clearly supported way -- I'm sure there are ways to trick the system).
When a project is loaded, and when the project itself changes (files added/removed, build actions changed, etc), the IntelliSense build is executed (csproj.dll!CLangCompiler::RunIntellisenseBuild
). This build will run tasks up to and including the Csc
task. Csc
will not execute normally, but instead just feed its inputs back into its host (Visual Studio).
From this point on, Visual Studio keeps track of the files that were given as Sources
to the Csc
task. It will monitor those files for changes, and when they change, update IntelliSense. So in my example, if I manually edit Bar.g.cs
those changes will be picked up. But the build tasks themselves will not be run again until the project changes or a build is explicitly requested.
So, that's disappointing, but not surprising, I guess. It also explains something else I had always wondered about -- XAML files with a code-behind tend to have a Custom Tool action of MSBuild:Compile
, presumably for exactly this reason.
I'm going to mark this as the answer, but I'd love to be told I'm wrong and that I missed something.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With