I've got a solution containing two MVC 5 web applications with associated class libraries and the code analysis settings are causing the build to hang. If I try to interact with the UI during this time I get the "VS is busy" bubble. Leaving the build to complete overnight doesn't work either.
To troubleshoot this I turned off code analysis on all projects and the project builds just fine [0]. So I enabled the "Microsoft All Rules" on one of the MVC projects and the build process doesn't complete.
"Microsoft Managed Minimum Rules" builds but what I'd now like is that there's some kind of structured way of going through the rulesets, where the next one I try is a superset of the last successful one. Does such a hierarchy exist, and if so, is there a canonical reference for it?
Once I get to that level then I can start to isolate individual rules, perhaps by increasing the verbosity of the build output...
[0]
This statement should not be interpreted as "Building without code analysis is perfectly okay"
A general hierarchy is exposed via the Include elements in the .ruleset files located under the Visual Studio install directory (e.g.: C:\Program Files (x86)\Microsoft Visual Studio 14.0\Team Tools\Static Analysis Tools\Rule Sets for a typical VS 2015 installation). Broadly, it looks something like this (with "All Rules" not actually depending on any of the others):
All Rules
Extended Correctness Rules
Basic Correctness Rules
Minimum Recommended Rules
Extended Design Guideline Rules
Basic Design Guideline Rules
Minimum Recommended Rules (same as above)
Globalization Rules
Security Rules
It's also worth noting that this isn't a clean hierarchy without overlaps. For example, rules included in the "Globalization" and "Security" rulesets are also included in some of the others (including the "Minimum" set).
To inherit from a ruleset file, you can include it with:
<Include Path="MyOther.ruleset" Action="Default" />
Then you can override the action for specific rules.
Related
We have a scenario like this:
We have ~100 solutions containing 10 projects each.
Each solution copies its artefacts (i.e. its 10 dlls) to a shared single folder like C:\code/assemblies.
If I develop something for feature X, I'll open up SolutionX.
The source for all solutions/projects is local in a single Monorepo C:\code.
During debugging, when the method/class/whatever is implemented in project Y, it opens the corresponding file (which is nice). So there must be information available how to get to the source.
But when developing, I cannot navigate to the implementation e.g. by using F12 ("go to definition") but just get the signatures gathered from meta data. I'd like to have the same experience like during debugging.
So right now I open up a Visual Studio Code, open the folder containing the sources and do a "search in files".
Any better ideas?
N.b. Resharper is not an allowed option. Also doesn't play nice with Postsharp.
N.b. I don't know if it is important but all except one solution start an external program (the shell), since all except one solution contain only dlls.
I have done similar in Old project.
You can use Symbol with Visual Studio 2019. Simple steps can be:
A. Generate Symbols for projects :
In Solution Explorer, select the project.
Select the Properties icon (or press Alt+Enter).
In the side pane, choose Build.
In the Configuration list, choose Debug or Release.
Select the Advanced button.
In the Debugging information list, choose Full, Pdb-only, or Portable.
Refer for more information:
Set debug and release configurations in Visual Studio
Publish symbols for debugging
B. Use Symbol in Visual Studio:
In Visual Studio, open Tools > Options > Debugging > Symbols (or Debug > Options > Symbols).
Under Symbol file (.pdb) locations,
To use the Microsoft Symbol Servers or NuGet.org Symbol Server, select the checkbox.
To add a new symbol server location,
Select the + symbol in the toolbar.
Type the URL (http), network share, or local path of the symbol server or symbol location in the text field. Statement completion helps you find the correct format.
Tools - Options - Debugging - Symbols page
For more Details refer:
Configure symbol locations and loading options
I think you should analyze project dependencies (for example with https://www.ndepend.com/docs/visual-studio-dependency-graph ) and cluster your projects in less Solutions
Edit : I am editing this answer based on your comment. I think you are looking for two use cases
Peek into the source code of referenced binaries
Navigate to the source and then edit them in place
To achieve option (1)
In Visual Studio 2019, use the built in decompiler to help you with navigating to code outside of the solution. This is an experimental feature as of May 2020. By default this is disabled and you should enable it. Once enabled the F12 navigation will decompile and allow you to peek into the source code.
On the other side, the more you relax the compilation the better the decompilation. Meaning, you can turn off optimisations (if any). This doesn't have to do anything with symbol generation options.
If you are using visual studio 2017 (or) less, the same can be achieved by Telerik Just Decompile plugin (free). Check the feature View decompiled code in tabs
To Achieve option (2) :
You should reference source files rather than binaries, because you won't get the natural in-place edit with referencing binaries. There are always going to be caveats irrespective of the solution you choose. Referencing source can be done using the "Add as link" feature in Visual studio, where the source code belong to one solution and can be referenced as link (something like windows shortcuts) in all the other solutions. (https://andrewlock.net/including-linked-files-from-outside-the-project-directory-in-asp-net-core/). If you are referencing source, you need to remove the binary references.
And you also have to decide from an architectural standpoint on how this changes the way people develop and commit code. The point of referencing binaries is to make sure they are not edited for convenience, but that depends on the nature of the development team purely.
Conclusion
From a best practices standpoint, you either have to reference binaries and don't allow them to be edited (or) you allow source references and edit in place. But that depends purely on what you want to achieve.
I'm tring to run analysis on SonarQube, using an FxCop custom Rule.
In SonarQube 4.5.7 I add the rule to the set of rules, I activate it and then run the analysis.
To run the analysis I use the sequence of following commands:
1) MSBuild.SonarQube.Runner.exe begin /k:my.project.C-Sharp-ConsoleApp /n:C-Sharp-ConsoleApp /v:1.1
2) "C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild" /T:Rebuild
3) MSBuild.SonarQube.Runner.exe end
I see that the rule is executed, because when I run the second command I read the following part of log:
...
(RunCodeAnalysis target) ->
MSBUILD : warning CR1000: MyRules : Field 'CSharpSortNames.m_variabile' is not in Hungarian notation. Field name should be prefixed with 's'. [C:\Users\Alessandro\Documents\Visual Studio 2015\Projects\C-Sharp-ConsoleApp\C-Sharp-ConsoleApp\C-Sharp-ConsoleApp.csproj]
My custom rule checkID is CR1000, and after the third command, I see that an error of this rule is founded, but the web app doesn't let me see where. For all other errors the web app let me see the precise line where is the error by a link to the .cs file. For my rule it doesn't.
Anyone can help me about this?
Further problem is in SonarQube 5.4 the same rule is activated but web app does not show the error.
The root cause here is that FxCop uses information from the PDB file for providing location information. However, the PDB only contains information that would be useful for debugging scenarios, which means that FxCop rule violations that are associated with non-executable code (e.g.: field declarations or interface definitions) will not have location information available. (FWIW, there is an open SonarQube issue for addressing this, but it would be non-trivial to accomplish unless SonarQube were to directly examine the source files to attempt to locate the field declaration. I rather suspect they might not bother given that it simpler to address via a Roslyn analyzer.)
Further problem is in SonarQube 5.4 the same rule is activated but web
app does not show the error.
That's because older versions of the C# plugin for SonarQube completely ignored FxCop violations without location information. This was addressed in version 5.2 of the plugin, which only became in early May 2016 (and is presumably what you used when you installed SonarQube 5.5). It is compatible with version 5.4 of SonarQube, so you should be able to use it with your older installs if you like.
I'm afraid I may be asking a really dumb question, but I can't seem to find anything that makes this clear. I usually work on smaller applications but am now working on a larger one with several assemblies in a baseline framework and several assemblies for a product line domain (with more to come). I would like to manage the build by configuring MSBuild. I've done a lot of online research (specifically with several MSDN articles I found) and now feel knowledgeable enough to be dangerous.
I understand that in csharp the *.csproj file can be unloaded and modified with properties, items, and targets to control the build process. I also understand that I can import my own targets file to help separate and organize. In this link though (https://msdn.microsoft.com/en-us/magazine/dd483291.aspx) a multilevel project build is organized with node-level dirs.proj files. This is confusing to me and has raised several questions I can't seem to find an answer to:
What is the difference in a *.proj and *.csproj file?
Can a *.proj be setup in VS to load on Build with F6 or does using this require use of the command prompt only? (i.e. "msbuild dirs.proj /t:Build").
Does dirs.proj load automatically? If so, my study-by is not working correctly, yet it does with command prompt.
Or am I overlooking something all the way around with "dirs.proj" Maybe it's just a substitue name for one of the project *.csproj files? If that was the case though there wouldn't have been a need for the root node's dirs.proj which from what I can tell doesn't have an actual project associated to it.
Anyways, I've seen dirs.proj mentioned in several forums regarding issues, but no where can I find how it's loaded or used in VS (outside of manual command prompt building which seems unreasonable if this is used to organize the build but the build won't really take a huge amount of time). I'm hoping someone can help me achieve that a-ha moment with this.
Thanks in advance.
Dirs.proj is an MSBuild convention typically used when dealing with very large source trees (> than 20 projects). I've worked with Microsoft engineers at a previous company and the dirs.proj convention appears to be one that Microsoft developed and uses internally to manage very large source trees.
A very good implementation reference for this is the Python Tools for Visual Studio project on CodePlex GitHub.
The link you shared by Sayed Ibrahim Sashimi is a very good explanation of the reasoning behind the msbuild paradigm, but it doesn't do a very good job of showing a practical example of how it works. The Python Tools project is an outstanding reference for this.
The idea behind using this paradigm is simple. I'd wager a guess that most .NET software engineers work on somewhat limited-scale projects that don't deal with more than 5-10 projects at a time, and they manage these projects in Visual Studio via Solution (.sln) files. They may even instruct their build system to run builds on the .sln. This works fine until you start thinking about scaling your product into or combining it with something larger, such as a platform with many, many projects. Solution files are not MSBuild files and as such they are not extensible like MSBuild is and they suffer massive performance penalties when dealing with large numbers of projects.
From an MSBuild perspective, dirs.proj stands in for Visual Studio .sln files. The difference, however, is that dirs.proj don't just include .csproj (and the like) as .sln do, rather, they can include source subtrees (e.g. other nested dirs.proj). So, building the root dirs.proj can result in the entire source tree being built, or building a nested dirs.proj will result in that subtree being built.
Therefore, the paradigm encourages you to look at your source as a series of interdependent nodes organized into features or product areas. That way, engineers can work on different source subtrees in very large projects without having to deal with the entire source tree, as you would have to with a VS solution.
Using this paradigm also carries certain benefits that don't come with .sln files. For example, if one project references a project from another, separate subtree, msbuild will build that reference first, automatically. Additionally, your source nodes can carry their own build settings, allowing them to be built dynamically using different build settings based on build scenario. For example, under one scenario a SharePoint source subtree needs WSP packaging, a C# subtree needs to be built without .pdb, a DB subtree needs to generate dacpacs, and the entire source tree needs to sign their assemblies using myCorp.snk and set build output to the $(buildRoot)\Output directory.
dirs.proj aren't opened via visual studio - they're built on the command line using msbuild. The only pain point is that the files have to be hand-curated.
So, long answer short take a look at the Python Tools project and see how they're using dirs.proj. Note how the entire source tree has common settings managed by Common.Build.settings, and how msbuild properties in this .settings file are used in the various .csproj files.
Is there a way to easily stop StyleCop warnings from being displayed within specific projects in a solution. Or, more pointedly, a way to select which projects StyleCop analysis should be performed on by Visual Studio?
We have a solution with 9 projects in it. There are only 2 projects that I actually want to see StyleCop warnings for, so I've created StyleCop.Settings files within those project root directories. This means that, for the rest of the projects, the default rule set is applied and I get a screen full of warnings every time I open a class.
The only way I can think to remove these warnings is to add another StyleCop.Settings file a folder level above with all the rules switched off and set merge options on the specific Settings files I am interested in to not merge with this parent file. This just feels wrong though. Is there a cleaner option or is this my only one?
UPDATE: I'm specifically looking for a way to stop the warnings from appearing within Visual Studio. I've added a Settings.StyleCop file to the solution folder and disabled all the rules. I run StyleCop analysis across one of my test projects and there are no errors reported. However, opening a test class reveals a raft of StyleCop warnings, which I want to suppress. Could this be the StyleCop for ReSharper plugin? I have a code cleanup profile created and have disabled certain rules within there but that doesn't appear to make any difference within my test classes.
Please have a look at File Lists configuration - they allow to disable rules by default per project:
Enabled Or Disabled By Default
In addition, a new setting allows you to determine whether rules
should be enabled or disabled by default. This can be set either at
the project level or at the SourceFileList level. For example, here’s
how you would set up a project with all rules disabled by default, and
only two rules explicitly enabled:
<StyleCopSettings Version="4.3">
<GlobalSettings>
<BooleanProperty Name="RulesEnabledByDefault">False</BooleanProperty>
</GlobalSettings>
We have a moderately sized solution, with about 20 projects. In one of them I have my business entities. On compiling any project, visual studio waits and hangs about one and a half minutes on this BusinessEntities project.
I tried our solution in SharpDevelop and it compiles our complete solution, in 18 seconds. Similar timing with MSBuild.
My guess is that VS is trying to find out if the project needs a compile, but this process is about 15 times slower than actually performing the compile!!
I can't switch to the great sharpdevelop, it lacks some small, but essential requirements for our debugging scenarios.
Can I prevent VS from checking this project, And have it compile the projects without such a check, just like sharpdevelop?
I already know about unchecking projects in configuration management to prevent building some projects, but my developers will forget they need to compile this project after updating to latest sources and they face problems that seem strange to them.
Edit: Interesting results of an investigation: The delay happens to one of the projects only. In configuration manager I unchecked all projects, then compiled each of them individually. All projects compile in a few seconds!! The point is this: if that special project is built directly, compiles in a few seconds, if it is being built (or skipped, because it is up-to-date) as a result of building another project that depends on it, VS hangs for about a minute and half, and then decides to compile it (or skip it). My conclusion: Visual studio is checking to know if any files are changed, but for some reasons, for this special project it is extremely inefficient!!
I'd go to Tools -> Options -> Projects and Solutions -> Build and Run and then change the "MSBuild project build [output|build log] verbosity" to Diagnostic. At that level it will include timings which should help you track down the issue.
We had the same problem with an ASP.NET MVC web project running in Visual Studio 2013. We build the project and nothing happens for about a minute or so and then the output window shows that we are compiling.
Here's what fixed it... open the .csproj file in a text editor and set MvcBuildViews to false:
<MvcBuildViews>false</MvcBuildViews>
I had to use sysinternals process monitor to figure this out but it's clearly the cause for my situation. The site compiles in less than 5 seconds now and previously took over a minute. During that minute the Asp.net compilation process was putting files and directories into the Temporary Asp.net Files folder.
Warning: If you set this, you'll no longer precompile your views so you will lose the ability to see syntax errors in your views at build time.
There is the possibility that you are suffering from VS inspecting other freshly built assemblies for the benefit of the currently compiling project.
When an assembly is built, VS will inspect the references of the target assembly, which if they are feshly built or new versions, may include actually loading them in a .Net domain, which bears all the burdens of loading an assembly as though you were going to run it. The build can get progressively slower as it rebuilds more and more projects. When one assembly becomes newer the others do a lot more work. This is one possible explanation for why building by itself, versus already built, versus building clean, all have seemingly relevantly differing results. Its really tht the others changed and not about the one being compiled.
VS will 'mark down' the last 'internal' build number of the referenced assembly and look to see if the referenced assembly actually changed as it rolls through its build process. If its not differnt, a ton of work gets skipped. And yes, there are internal assembly build numbers that you dont control. This is probalby not in any way due to the actual c# compiler or its work or anything post-compile, but pre-compile steps necessary for the most general cases.
There are several reference oriented settings you can play with, and depending on your dev, test, or deployments needs, the functional differences may be irrelevant, however may profoundly impact how VS behaves and how long it takes during build.
Go to the references of one of the projects in Solution Explorer:
1) click on a reference
2) open the properties pane if its not (not the Property Pages or the Property Manager)
3) look at 'Copy Local', 'Embed Interop Types', 'Reference Output Assembly'; those may be very applicable and probably something good to know about regardless. I strongly suggest looking up what they do on MSDN. 'Reference Output Assembly' may or may not show in the list.
4) unload the project, and edit the .proj file in VS as text. look for the assembly reference in the XML and look for 'Private'. This means whether the assembly referenced is to be treated as though its going to be a private assembly from the referencing assemblies perspective, vs a shared one. Which is sort of a wordy way of saying, will that assembly be deployed as a unit with the other assemblies together. This is very important toward unburdening things. Background: http://msdn.microsoft.com/en-us/magazine/cc164080.aspx
So the basic idea here is that you want to configure all of these to be the least expensive, both during build and after deployment. If you are building them together, then for example you probably really don't need 'Copy Local'. Id hate to say more about how you should configure them without knowing more about your needs, but its a very fine thing to go read a few good paragraphs about each. This gets very tricky however, because you also influence whether VS will use the the stale old one when resolving before the referenced one is rebuilt. As a further example explaiing that its good to go read about these, Copy Local can use the local copy, even though its stale, so having this set can be double bad. Just remember the goal at the moment is to lower the burden of VS loading newly built assemblies jsut to compile the others.
Lastly, for now, I can easily say that hanging for only 1.5 mins is getting off very lucky. There are people with much much worse build times due to things like this ;)
Some troubleshooting idea's that have not been mentioned:
Clean solution?
Delete Obj and Bin folders plus the .suo file? FYI, neither Clean nor Rebuild will delete non-build files, eg files copied during a pre-build command.
Turn off VS scanning outside files. Options > tools > environment > document > detect when file is changed outside the environment?
Rollback SVN history to confirm when it started to occur? What changed? If the project file on day 1 takes the same time, recreate the project, add all the files and build.
Otherwise could you please run Process Monitor and let us know what Visual Studio is doing in the prep-build stage?
Sounds silly, but remove all breakpoints first. It sped up my pre-build checks massively - still don't know why though.
Based on the (limited) information provided one possibility is that there could be a pre-build action specified in the project file that is slow to compile.
Try disabling platform verification task as described here.
If your individual projects are compiling correctly then all you can do is change order of compilation by setting dependent projects explicitly in configuration.
Try to visualize your project dependency hierarchy and set dependent projects. For example, if your business entities project is referenced in each project, then in configuration of each project, this project must be selected as dependent.
When an explicit build order is not set, visual studio is analyzing projects to create an order of building project. Setting explicit dependent projects wiki make visual studio skip this step and use the order provided by you.
With such an extreme delay on a single project and no other avenue seeming to provide a reason I would attempt to build that specific project while running procmon from sysinternals and filter out all the success messages. You could probably also narrow it down to just the file system actions as well. From your description I might guess that the files are being locked by an external source like the event collection or workflow management process services.
Other things to consider would be whether or not this is a totally clean build machine or if it has been used to perhaps test the builds as well? If so, is there a chance that someone mapped an IIS application path to the project directly or registered it as a service location?
If you run procmon and see no obvious locks or conflicts I would create a totally new solution and project and copy the files over to see if that project also has the same delay. If it does have the same delay I would create a sample project of the same type but generic data (essentially empty) and see if that too is slow. If the new project with the same files builds fine you can then diff the directories to see what the variance is that causes the problem (perhaps a config or project setting).
For me, thoroughly disabling code analyzers helped per instructions here:
https://learn.microsoft.com/en-us/visualstudio/code-quality/disable-code-analysis?view=vs-2019#net-framework-projects.
I thought my code analyzers were already off, but adding the extra xml helped.
Thanks Kaleb's for the suggestion to set "MSBuild project build [output|build log] verbosity" to Diagnostic. The first message took more than 10 seconds to display:
Property reassignment: $(Features)=";flow-analysis;flow-analysis" (previous value: ";flow-analysis") at C:\myProjectDirectory\packages\Microsoft.NetFramework.Analyzers.2.9.3\build\Microsoft.NetFramework.Analyzers.props (32,5)
Which led me to the code analyzers.
Just in case someone else trips into this issue:
In my case the delay was being caused by an invalid path entry in "additional include directories" that referred to a non accessible UNC location.
Once this was corrected, the delay disappeared.