C# analysis fails without .pdb files - c#

I'm trying out the new C# plugin v3.0 with SonarQube 4.2.
According to plugin documentation, I need .pdb files to run analysis which includes FxCop rules, and indeed I get a failure message when executing sonar-runner if said .pdb files are not present in the output folder; FxCop exits with code 1536.
The thing is, the analysis seems to require .pdb files for ALL the binnaries, and the output folder contains several dependencies in addition to my own compiled code. These are NuGet packages and I cannot find symbol files for all of them.
So, is there any way I can have the analysis to skip the files without debugging symbols?
The regular SonarQube file exclusion lists seem to apply to source code files only (e.g. *.designer.cs) and not for binnaries.

This is a bug on the SonarQube C# plugin side. I have created the following ticket to fix it: https://jira.codehaus.org/browse/SONARFXCOP-29
Note that this is not related to the presence of *.pdb files, but only on the presence of the referenced assemblies.

Related

Running Fortify on .dll files as well as .cs

.NET version of existing question Can I run fortify on .jar files instead of .java?
My team is using Fortify 5.15.0.0060. We are scanning our .NET project in Visual Studio, and project settings shows the following command line arguments:
-vsversion 10.0 "-b" "project" "-machine-output" "-scan" "-f" "C:\Users\user\AppData\Local\Fortify\VS2010-3.80\project\Scan.fpr" "-format" "fpr"
This highlights issues in our .cs source code files, but does not appear to look at the DLLs that form part of our solution (and which are copied to our output directory along with our binaries). For many of these libraries we do not have access to .pdb files, but were hoping that Fortify would be able to do a limited amount of scanning anyway.
Is it possible to add a command line argument to include DLL files, with/without PDB files?
When it comes to .Net, Fortify can only scan assemblies that have a .pdb because it uses ildasm.exe to decompile the assembly and then it uses the .pdb to match to the source files. Unfortunately there is no way for you to scan these extra assemblies.
If you have the .pdb files, you can have Fortify scan them, however you may not see the full source in your results. To include these assemblies, you need to specify them in your Translation options. If you are doing this all from the command line, then this is how you would do it:
sourceanalyzer -b project -vsversion 10.0 projectPath\Additional.Assembly.1.dll projectPath\Additional.Assembly.2.dll projectPath\Additional.Assembly.3.dll
sourceanalyzer -b project -scan -f MyResults.fpr
If you have not yet updated your Fortify version, I would highly recommend that you do so.

Sandcastle Help File Builder Can't Find documentation source

I'm building the doc of a VS 2010 C# project with the Sandcastle Help File Builder. I've added the .xml documentation generated by the compiler and the Visual Studio solution .sln file of the project to the Documentation Sources. I have also added the project's executable .exe to References. However, It is not building. I get these warnings and errors:
SHFB: Warning BE0006: Unable to locate any documentation sources for 'C:\Users\user\Music\Documents\Visual Studio 2010\Projects\SFML_Platformer\SFML_Platformer.sln' (Configuration: Debug Platform: AnyCPU)
SHFB: Error BE0042: You must specify at least one documentation source in the form of an assembly or a Visual Studio solution/project file
What's the problem?
You should only add the XML documentation files as Document Source. The DLLs are added automatically after you add the XML files.
Here the answer from Eric a.k.a EWoodruff the developer of Sandcastle Help File Builder.
BE0006 means it couldn't find the documentation source based on the
project. BE0042 is a secondary result of that meaning it found
nothing at all to document. What type of projects are in the
solution? If it's a website project, bear in mind that they do not
typically produce any assemblies that are listed as output in the
project nor any XML comments files. In that case, you'd need to add
the web code providers to your project to get the XML comments and
manually add the website's .\bin folder as a documentation source in
the SHFB project. There's a topic on documenting websites in the
Getting Started section if that is the case.
All other project types should work. If all else fails, try adding
the assembly and XML comments files directly. I suppose it's possible
the Express editions use diffent project type IDs. If you can send me
the solution file and project file, I can take a look at them and see
why it isn't finding the targets. My e-mail address is in the About
box in the standalone GUI and in the footer of the pages in the help
file.
One other thing, make sure the Configuration and Platform settings
selected in the SHFB toolbar match the Configuration and Platform
settings used to build your project (i.e. Debug/AnyCPU,
Release/AnyCPU, Debug/x86, etc). If not, that will cause it to not
find the proper output targets.
Eric
source
I had this issue occur when I switched the project's build in VS.NET on my main application from Debug to Release. I assume it could not longer find the .dll I had specified to create the documentation. I could have fixed the mapping, but going back to Debug worked just fine for me to remove this error.
Don't forget to rebuild your solution after cleaning before running Build in Sandcastle.

How does MSBuild decide whether it needs to rebuild a C# library or not?

How does MSBuild decide whether it needs to rebuild a library (that is, invoke csc), or not, when it is run against a C# project file?
I imagine (but want to confirm):
If there's no output directory, rebuild (duh :) )
If a C# file has changed, rebuild
If an included file marked copy-always has changed, rebuild
Or is it smart enough to not rebuild, but just copy the file to the existing output?
If an included file marked copy-if-newer has changed, rebuild
Same question as above
If you look in Microsoft.CSharp.targets (the MSBuild file for compiling C# projects) the CoreCompile target has a set of Inputs and Outputs defined. These are used to do the dependency checking to see if CoreCompile needs to run. The list of inputs include the C# files, resource files, application icon, strong name key file, and other custom inputs you can define.
If you have a solution and run MSBuild on it with diagnostic logging enabled (/v:diag command line parameter), you might see this message if the outputs are up to date:
Skipping target "CoreCompile" because
all output files are up-to-date with
respect to the input files.
The targets file is located in the .NET Framework directory (C:\windows\Microsoft.NET\Framework\v3.5 or v4.0.30319).
MSBuild has built-in functionality to do it.
Target has two properties, Inputs and Outputs.
Whenever Input changes or Output is older or missing the Target is executed.
The things is, any heuristic that might sound plausible is probably not going to cut it. And when you're asking your compiler (build system) to produce an output you better damn guarantee that the output is what you expect it is.
As far as I know, MSBuild doesn't do this. It always rebuilds (from scratch) the entire solution/project. However, when MSBuild is being invoked from within Visual Studio temporary compilation units are maintained in the \obj folder of your project. Emptying that folder is the same as rebuilding.
That said if the compiler or build system was to reuse outputs it would use checksums of the actual file contents to determine whether a compiled output can be retrieved from some other place. This is basically the only reliable way you could determine whether a file actually needs to be recompiled from scratch. FYI, this is done by the Visual C# compiler not MSBuild.
The file system "last modified date" attribute wouldn't be consistent cross systems and therefore not ultimately used to determined whether to build with cached output or build from scratch.

What is function of each file in a simple C# project?

I want to ask about the files that are found in the folder of a simple C# Project .
like
(.pdb file , .vshost file , .manifest file ) in bin folder
( .csproj.fileListAbsolute.txt file , .pdb file ) in debug folder
(AssemblyInfo.cs ) in Properties folder
what is the function of each file of them ?
and which of them is in MSIL , if there is no file of them in this language how can I get file in MSIL ?
another question : what is the specific part that converts C# code into MSIL ?? , Is it the C# Compiler ? Is there any specific name to it ?
Technically, the pdb, vshost, and manifest file are not part of a C# project, the are part of the output generated when you build the project.
The PDB file contains symbol information used by the debugger to associate code within the assembly with your sources files. This allows the debugger to identify which line of source code corresponds a set of instruction in the MSIL of an assembly.
The vshost.exe file is a hosting process that visual studio generates that helps accelerate the debugging of an application. It caches app domain for your process to reduce the startup time for the debugger.
The manifest file contains information about the assemblies in a project and some common metadata about them. Its contents varies by project type.
The csproj file is xml-based representation of the code and resources for a project. It's the file that Visual Studio uses to figure out what code and resuorces to compile into an assembly. This file also contains project settings and options that control how the compiler (and other tools) process the assets of a project.
None of these files contains MSIL. The MSIL is part of the .exe and .dll files generated when you build a project. These files are encoded using the Microsoft PE (portable executable) format, and contain resources, data, and MSIL code.
The exe and dll, and pdb files are generated by the C# compiler - csc.exe. The other files (IIRC) are generated by other tools invoked by the msbuild process that controls the entire build cycle.
The executable (exe) or assembly (dll) will contain code in MSIL. The MSIL can be viewed using a tool like ILDASM or .NET Reflector. The C# compiler is csc.exe.
Here's a quick list:
PDB - These are debugging symbols used by Visual Studio and other debuggers.
VSHOST - This is a special executable that's hosted by Visual Studio (hence the name) I think this is used to provide intellisense and debugging help (e.g. breakpoints).
MANIFEST - Depends on the kind of project you're working on. Usually this file lets you specify special OS-level needs for your application (e.g. UAC admin rights... security model etc. etc.)
CSPROJ - Think of this as a Makefile/Buildfrile for your application. (CSPROJ means a CSharp Project) - This file list all the files necessary to build your application and also any extra processing steps (like a Makefile target) that might be necessary.
AssemblyInfo.cs - This is just a normal C# code file, but usually reserved for adding assembly-level attributes. (a .NET assembly metadata, as opposed to a normal EXE file metadata which is used by the operating system)
MSIL is Microsoft Intermediate Language which is an intermediate representation of the code resulting from compiling C# source code (or other .NET languages) using the C# compiler (csc.exe).
The .NET Runtime then interprets or JIT-compile the IL into actual machine code when you run the application.

ILMerge Best Practices

Do you use ILMerge? Do you use ILMerge to merge multiple assemblies to ease deployment of dll's? Have you found problems with deployment/versioning in production after ILMerging assemblies together?
I'm looking for some advice in regards to using ILMerge to reduce deployment friction, if that is even possible.
I use ILMerge for almost all of my different applications. I have it integrated right into the release build process so what I end up with is one exe per application with no extra dll's.
You can't ILMerge any C++ assemblies that have native code.
You also can't ILMerge any assemblies that contain XAML for WPF (at least I haven't had any success with that). It complains at runtime that the resources cannot be located.
I did write a wrapper executable for ILMerge where I pass in the startup exe name for the project I want to merge, and an output exe name, and then it reflects the dependent assemblies and calls ILMerge with the appropriate command line parameters. It is much easier now when I add new assemblies to the project, I don't have to remember to update the build script.
Introduction
This post shows how to replace all .exe + .dll files with a single combined .exe. It also keeps the debugging .pdb file intact.
For Console Apps
Here is the basic Post Build String for Visual Studio 2010 SP1, using .NET 4.0. I am building a console .exe with all of the sub-.dll files included in it.
"$(SolutionDir)ILMerge\ILMerge.exe" /out:"$(TargetDir)$(TargetName).all.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll" /target:exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards
Basic hints
The output is a file "AssemblyName.all.exe" which combines all sub-dlls into one .exe.
Notice the ILMerge\ directory. You need to either copy the ILMerge utility into your solution directory (so you can distribute the source without having to worry about documenting the install of ILMerge), or change the this path to point to where ILMerge.exe resides.
Advanced hints
If you have problems with it not working, turn on Output, and select Show output from: Build. Check the exact command that Visual Studio actually generated, and check for errors.
Sample Build Script
This script replaces all .exe + .dll files with a single combined .exe. It also keeps the debugging .pdb file intact.
To use, paste this into your Post Build step, under the Build Events tab in a C# project, and make sure you adjust the path in the first line to point to ILMerge.exe:
rem Create a single .exe that combines the root .exe and all subassemblies.
"$(SolutionDir)ILMerge\ILMerge.exe" /out:"$(TargetDir)$(TargetName).all.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll" /target:exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards
rem Remove all subassemblies.
del *.dll
rem Remove all .pdb files (except the new, combined pdb we just created).
ren "$(TargetDir)$(TargetName).all.pdb" "$(TargetName).all.pdb.temp"
del *.pdb
ren "$(TargetDir)$(TargetName).all.pdb.temp" "$(TargetName).all.pdb"
rem Delete the original, non-combined .exe.
del "$(TargetDir)$(TargetName).exe"
rem Rename the combined .exe and .pdb to the original project name we started with.
ren "$(TargetDir)$(TargetName).all.pdb" "$(TargetName).pdb"
ren "$(TargetDir)$(TargetName).all.exe" "$(TargetName).exe"
exit 0
We use ILMerge on the Microsoft application blocks - instead of 12 seperate DLL files, we have a single file that we can upload to our client areas, plus the file system structure is alot neater.
After merging the files, I had to edit the visual studio project list, remove the 12 seperate assmeblies and add the single file as a reference, otherwise it would complain that it couldnt find the specific assembly. Im not too sure how this would work on post deployment though, could be worth giving it a try.
I know this is an old question, but we not only use ILMerge to reduce the number of dependencies but also to internalise the "internal" dependencies (eg automapper, restsharp, etc) that are used by the utility. This means they are completely abstracted away, and the project using the merged utility doesn't need to know about them. This again reduces the required references in the project, and allows it to use / update its own version of the same external library if required.
We use ILMerge on quite a few projects. The Web Service Software Factory, for example produces something like 8 assemblies as its output. We merge all of those DLLs into a single DLL so that the service host will only have to reference one DLL.
It makes life somewhat easier, but it's not a big deal either.
We had the same problem with combining WPF dependencies .... ILMerge doesn't appear to deal with these. Costura.Fody worked perfectly for us however and took about 5 minutes to get going... a very good experience.
Just install with Nuget (selecting the correct default project in the Package Manager Console). It introduces itself into the target project and the default settings worked immediately for us.
It merges the all DLLs marked "Copy Local" = true and produces a merged .EXE (alongside the standard output), which is nicely compressed in size (much less than the total output size).
The license is MIT as so you can modify/distribute as required.
https://github.com/Fody/Costura/
Note that for windows GUI programs (eg WinForms) you'll want to use the /target:winexe switch. The /target:exe switch creates a merged console application.
I'm just starting out using ILMerge as part of my CI build to combine a lot of finely grained WCF contracts into a single library. It works very well, however the new merged lib can't easily co-exist with its component libraries, or other libs that depend on those component libraries.
If, in a new project, you reference both your ILMerged lib and also a legacy library that depends on one of the inputs you gave to ILMerge, you'll find that you can't pass any type from the ILMerged lib to any method in the legacy library without doing some sort of type mapping (e.g. automapper or manual mapping). This is because once everything's compiled, the types are effectively qualified with an assembly name.
The names will also collide but you can fix that using extern alias.
My advice would be to avoid including in your merged assembly any publicly available lib that your merged assembly exposes (e.g. via a return type, method/constructor parameter, field, property, generic...) unless you know for sure that the user of your merged assembly does not and will never depend on the free-standing version of the same library.
We ran into problems when merging DLLs that have resources in the same namespace. In the merging process one of the resource namespaces was renamed and thus the resources couldn't be located. Maybe we're just doing something wrong there, still investigating the issue.
We just started using ILMerge in our solutions that are redistributed and used in our other projects and so far so good. Everything seems to work okay. We even obfuscated the packaged assembly directly.
We are considering doing the same with the MS Enterprise Library assemblies.
The only real issue I see with it is versioning of individual assemblies from the package.
I recently had issue where I had ilmerged assembly in the assembly i had some classes these were being called via reflection in Umbraco opensource CMS.
The information to make the call via reflection was taken from db table that had assembly name and namespace of class that implemented and interface. The issue was that the reflection call would fail when dll was il merged however if dll was separate it all worked fine. I think issue may be similar to the one longeasy is having?
It seems to me like the #1 ILMerge Best Practice is Don't Use ILMerge. Instead, use SmartAssembly. One reason for this is that the #2 ILMerge Best Practice is to always run PEVerify after you do an ILMerge, because ILMerge does not guarantee it will correctly merge assemblies into a valid executable.
Other ILMerge disadvantages:
when merging, it strips XML Comments (if I cared about this, I would use an obfuscation tool)
it doesn't correctly handle creating a corresponding .pdb file
Another tool worth paying attention to is Mono.Cecil and the Mono.Linker [2] tool.
[2]: http:// www.mono-project.com/Linker

Categories