Perform Roslyn conditional compilation with custom symbol (eg: "DEBUG") defined - c#

I'm compiling a project using Roslyn with code resembling:
var workspace = MSBuildWorkspace.Create();
var project = await workspace.OpenProjectAsync("SomeProject.csproj");
var compilation = await project.GetCompilationAsync();
I need to set a compilation symbol (such as DEBUG or TRACE, but in my case something altogether custom). How can I do this with the API?
I saw that project has a CompilationOptions property, but I didn't see anything relevant there.
EDIT Thanks to #JoshVarty who pointed towards adding code like this prior to compilation:
project = project
.WithParseOptions(((CSharpParseOptions)project.ParseOptions)
.WithPreprocessorSymbols("SOME_SYMBOL"));

I think you're looking for Project.WithParseOptions() and WithPreprocessorSymbols()

Related

Roslyn Document of a Project return null

string sln = path;
MSBuildWorkspace workspace = MSBuildWorkspace.Create();
Solution solution = workspace.OpenSolutionAsync(sln).Result;
foreach (Project pro in solution.Projects)
{
foreach (Document documents in pro.Documents)
{
SyntaxNode rootNode = documents.GetSyntaxRootAsync().Result;
SemanticModel semanticModel = documents.GetSemanticModelAsync().Result;
IEnumerable<ClassDeclarationSyntax> myClasses = rootNode.DescendantNodes().OfType<ClassDeclarationSyntax>();
string pfad = documents.FilePath; .....
What I want to do is load a solution and its projects and the documents inside those projects then I want to get the path of those files. First 2 work but there are no documents being loaded. When executing this code, the second foreach is just being skipped completely. Debugging shows that documents is null.
I've seen other projects use this type of code but it doesn't work and I have no reason why. The dots mean there is more code but that part does actually work so I just cut it out. If someone has a clue, can you please add on to my code? Much appreciated!
The possible reasons for pro.Documents returning null could be because of:
.NET standard project is not supported by MSBuild Workspace. For more information, click here.
Missing Nuget Packages
           a. Microsoft.Build
           b. Microsoft.Build.Utilities.Core
If none of the above solutions worked, then you can try debugging yourself by using MSBuildWorkspace.WorkspaceFailed event handler. Make sure that you subscribe to this event before calling OpenSolutionAsync method. Credits: Jason Malinowski

Figure out why Microsoft.Build.Evaluation.Project.Build() returns false

I'm trying to build C# projects using .csproj files.
For this I'm using the following code:
Microsoft.Build.Evaluation.Project project = new Microsoft.Build.EvaluationProject(projectFile);
bool success = project.Build();
But not all projects are build and for some I get false as the result of project.Build().
Any ideas how to understand what is going wrong?
Or maybe anyone can suggest an alternative way to compile projects using .csproj files?
You need to add an ILogger to the Build method as a parameter. I suggest implementing one as the MSDN article suggests. Just copy paste their code, add any missing references and you'll be fine.
Then you can call Build as follows:
Microsoft.Build.Evaluation.Project project = new Microsoft.Build.Evaluation.Project(projectFile);
BasicFileLogger logger = new BasicFileLogger();
logger.Parameters = logFilePath;
logger.Verbosity = LoggerVerbosity.Normal; //Increase it if you don't get enough data
bool success = project.Build(logger);
The example logger will write all data that you would see during a normal build to the file at logFilePath. Based on that you should be able to discern the issue.

Is there anyway to use the NDepend API to get a list of assemblies and their associated projects?

I am currently trying to get a list of 3rdParties shipped with each product and have come across the NDepend API. Based on the research I have done, it seems like you feed in a solution file and out comes a list of DLLs and EXE's associated with that solution. So far I have tried:
static void Main(string[] args)
{
var ndependServicesProvider = new NDependServicesProvider();
var projectManager = ndependServicesProvider.ProjectManager;
var visualStudioManager = ndependServicesProvider.VisualStudioManager;
var projPath = "C:\\code\\depot\\Captiva\\IA\\EIM\\_Trunk\\Src\\BuildInputAccel.Installers.sln";
var sln = projPath.ToAbsoluteFilePath();
var vsSlnOrProjFilePaths = new List<IAbsoluteFilePath> { sln };
var assembliesFilePath = (from vsSlnOrProjFilePath in vsSlnOrProjFilePaths
from assembliesFilePathTmp in visualStudioManager.GetAssembliesFromVisualStudioSolutionOrProject(vsSlnOrProjFilePath)
select assembliesFilePathTmp).Distinct().ToArray();
IProject project = projectManager.CreateTemporaryProject(assembliesFilePath, TemporaryProjectMode.Temporary);
project.CodeToAnalyze.SetApplicationAssemblies(assembliesFilePath);
projectManager.SaveProject(project);
IAnalysisResult analysisResult = project.RunAnalysis();
Console.Write(analysisResult.CodeBase);
}
And have gotten a An unhandled exception of type 'System.IO.FileNotFoundException' occurred in mscorlib.dll
Does anyone know what I am doing wrong here. I simply want to output a list of dll's and exes associated with each project within a solution. PS: I am very new to C# so sorry if this seems trivial!
At the end of the NDepend API getting started page you'll find instruction about what to do.
Actually can use the integrated Code Querying LINQ (CQLinq) facility to query live 3rd party assemblies referenced and their usage.
1) from the NDepend start page > Analyze VS solution
2) choose your solution
3) run analysis
Then you can just edit this code query:
from a in ThirdParty.Assemblies
select new { a, a.AssembliesUsingMe }
et voilà
If some third-party assemblies are missing it is because they haven't been resolved at analysis time. Look at analysis error list and update the list of folder where NDepend will look for assemblies in NDepend Project Properties > Code to Analyze > Directories

Does Roslyn actually allow you to manipulate TreatWarningsAsErrors for a CSharp project?

I'm trying to retrieve the setting TreatWarningsAsErrors, but I'm unable to find it for a project of my loaded solution.
What I'm trying to accomplish, is to get the setting from the project files, and set it to true, if it's not already that. Next, I want to let Roslyn do a compilation with the new setting, so I can check if this will break the project.
I've looked at various places, among others, the Project.CompilationOptions. Most options to a project build are there, except this one.
The CompilationOptions contains all the build settings, such as warning level, etc. But TreatWarningsAsErrors is not there. Am I looking at the wrong place?
The way I'm opening the solution is similar to the FormatSolution sample:
var solutionFile = #"C:\ties\src\playground\EnforceTreatAllWarningsAsErrors\EnforceTreatAllWarningsAsErrors.sln";
var workspace = MSBuildWorkspace.Create();
var solution = workspace.OpenSolutionAsync(solutionFile).Result;
var project = solution.Projects.Single();
// warning level is there
var warningLevel = project.CompilationOptions.WarningLevel;
// treat warnings as errors is not there... The following doesn't compile :(
bool treatWarningsAsErrors = project.CompilationOptions.TreatWarningsAsErrors;
You're looking for
compilationOptions.WithGeneralDiagnosticOption(ReportDiagnostic.Error)
Source

Updating Visual Studio .csproj new Method

In my application i am using the following code to update my .csproj.
var project = new Project();
project.Load(path);
var itemGroup = project.AddNewItemGroup();
var buildItem = itemGroup.AddNewItem("ProjectReference",#"..\Basics\Test.csproj");
buildItem.SetMetadata("Project","sf34-34hg-jgjk3-3434-99345345hh345");
buildItem.SetMetadata("Name","Test");
project.Save(path,Encoding.UTF8);
The code is working fine. But during the time of compilation. It shows a warning like Microsoft.Build.BuildEngine.Project is Obsolete which is advising to use another assembly Microsoft.Build.Evaluation.Project.
I searched for changing the code with new assembly, but didn't get much information on the same. Anyone please help me to change this code to new method.

Categories

Resources