Roslyn workspace.OpenSolutionAsync().Projects always empty? - roslyn

I'm trying to create a self-hosted WebAPI 2.0 project that allows you to open/explore/build .sln solutions through an API.
Here's the code within one of my controllers, that's supposed to return a list of projects given a path to the .sln:
public async Task<IHttpActionResult> GetProjects(string slnPath = "")
{
var workspace = MSBuildWorkspace.Create();
var solution = await workspace.OpenSolutionAsync(slnPath);
var projects = solution.Projects;
}
I would expect projects to hold the projects in the solution, but according to the debugger, solution.Projects and solution.ProjectIds always seem to be empty.
I've tried this with multiple .sln files, all of which I can open in Visual Studio and see that they have projects in them.
I've seen this question, but my project isn't a Visual Studio add in, it's a class library called from a command line application.

This is generally caused by one of a few things, in order of commonality:
You are missing copies of Microsoft.CodeAnalysis.CSharp.Workspaces.dll or Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll. Make sure when you are running your project that those DLLs are next to the main Microsoft.CodeAnalysis.Workspaces.dll.
You're loading solutions with project types we don't support. We should support any project type except the project-less Web Site projects. Class libraries should work just fine.
We have a bug that's causing us to mis-handle your particular project types. If that's the case, file a bug on GitHub.

If you are getting this issue in unit tests but not in your production code, ensure that you have referenced both Microsoft.CodeAnalysis.CSharp.dll and Microsoft.CodeAnalysis.CSharp.Workspaces in your test project.
JYL mentioned it in the comments of the selected answer but I didnt see it right away.

Related

Payload contains two or more files with the same destination path for Default.rd.xml file

I was trying to do unit testing for UWP App. When I added target application reference in Test project, the following error is giving while running the test method
Payload contains two or more files with the same destination path'Properties\Default.rd.xml'.Source files: D:\Test\MyAppTesting\Properties\Default.rd.xml D:\Test\MyApp\Properties\Default.rd.xml
No error code was given.
adding refernce
public class MyAppTesting
{
[Fact]
public async void PassingWinAppServiceTest()
{
AgendaService agendaService = new AgendaService();
var memberModel = await agendaService.GetMemberDetailsById("234");
Assert.False(String.IsNullOrEmpty(memberModel.MemberId.ToString()));
}
The only workaround I found is to remove the Default.rd.xml file from the test project.
Comments from the developer community for similar issue.
From the documentation of Runtime Directive Configuration file,
A runtime directives (.rd.xml) file is an XML configuration file that
specifies whether designated program elements are available for
reflection.
So, if reflection is not used in the test project then I believe, Default.rd.xml file can be safely removed from the test project.
After installing the NuGet, you need to add an existing project reference into the unit test project.
[right click test project -> Add -> Reference-> select an existing project}
Then check your test project dependencies, Your existing project should be there.

How unit test logic in xamarin forms with a separated console project with F#?

I have a complete new/empty project with xamarin.forms 2.3.4 with F#.
I have a shared project, with a extra module for the logic:
module Db
let openDb() =
printf "Hello"
Then I create a console project, reference the shared project & related libraries, and try to run it:
open Db
[<EntryPoint>]
let main argv =
Db.openDb()
0
Now I getting this error:
../Test/Tests.fs(6,6): Error FS0039: The namespace or module 'Db' is not defined. Maybe you want one of the following: XDB (FS0039) (Test)
I not getting any other error. I try both with xamarin & Visual Studio Mac; and also creating a UI test project (however, I only care for logic testing).
This is an empty form project without anything else.
P.D: I make it to work if a just delete the reference to the shared project and link manually the files. However, I wonder if is possible to cover this scenario...
Is there an EntryPoint file under the file that defines the module?
The location of the file can be changed with alt +up arrow and alt +down arrow(win + visual studio) or Db.fs(in Solution Explorer) is right click -> Move up
F# is readed file from up to down.(See "Projects and Solutions" on this site )
It Maybe that(win10 ,visual studio 2017)
Db.fs is difine module. There is an entry EntryPoint program.fs.
Also, if the namespace and the module name are the same, an error will occur. module name for this project is Bar.

Visual studio 2017 create Intellitest not working

Note: Answering my own problem for future developers.
I right click a Method > Create Intelli Tests.
I choose the MSTestv2, chose the Project.Test project, click OK and see the following output:
Processing Proj.API
Scanning assembly references in Proj.API Applying
template AssemblyInfo to Proj.API Applying template Tests to Proj.API
test stubbing ProductController -> ProductControllerIntelliTest
generating method bodies
flushing generated code
Unfortunately the Test.cs file is NOT created.
I've set all projects x86 and that doesn't make a difference.
Does anyone know why this doesn't work?
For some reason I had to specify a New Project for the Intelli Tests.
Creating new IntelliTests in the new project work, however they cant be added to the standard Test Project.
Hopefully someone else knows why.

Incremental build in TFS - How do I update AssemblyInfo.cs version only for projects that have changed?

We have a solution in TFS 2012 that contains several projects. I have set up a Continuous Integration build on our build server and have set Clean Workspace = None. I'm using the TFS Versioning template 2.0 to update the AssemblyFileVersion and AssemblyVersions.
When the build is run, each project has its AssemblyInfo.cs file updated with a new version number even though there have been no changes made to the code in some of the projects. Ideally we want the version to change only if there have been changes to the project.
I was considering building each project separately, but we would prefer to be able to simply build the solution. I have read that Clean Workspace = None should prevent the projects from being updated but it doesn't appear to be happening for me since the timestamp on all the dll's are showing as changed after the build.
I am new to setting up a build process, so I'm hoping there is something simple that I'm doing wrong. Any suggestions would be greatly appreciated.
Update:
After checking the suggested link, it appears that I'm doing two things during build that may be causing the issue: 1) web.config file transforms that take place in an "AfterBuild" step in one of my projects and 2) using the version number increment features in the "TFS Versioning" template without opening up the workflow to see how it is checking for changed files. I'll remove both of these and see what happens.
This is a good question and it is possible. I run powershell scripts that use the TFS API to determine what files have changed
You need to get the changesets and shelvesets also, but once you have these you can get the information you want like this:
function Get-ChangesetChanges()
{
[CmdletBinding()]
param ([Parameter(Mandatory=$true)][string]$Changeset,[Parameter(Mandatory=$true)][string]$TFSServer)
[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.TeamFoundation.VersionControl.Client')
[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.TeamFoundation.Client')
$tfs = [Microsoft.TeamFoundation.Client.TeamFoundationServerFactory]::GetServer($TFSServer)
$vcs = $tfs.GetService([Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer])
$vcsChanges = $vcs.GetChangeset($changeset).Changes;
$changes = #();
foreach ($change in $vcsChanges)
{
$changes += $change.Item.ServerItem;
}
$changes;
}

TFS Build and absolute path in app.config

first, I'd like to apologize for my english, it's not my 1st language !
I'm a total n00b in the wonderful world of TFS Build (2010), and I've got a problem.
I'll try to explain it to you using a simple example (but my actual situation is much more complicated).
I have a project with a console application "MyApp1", its location on my computer is "D:\MyProjets\MyApp1".
I have another project "Res" which contains only resources, including a file named emailTemplate.html.
My project "MyApp1" uses this file. Therefore, in the "App.config" file there's a key that stores the path of this resource : "D:\MyProjets\Res\emailTemplate.html"
Finally, I have a test for that application "MyApp1". This test checks if an e-mail has been sent. To send the e-mail "MyApp1" will need the file "emailTemplate.html", and will use the key in the configuration file to find it.
When I run the test on my computer : everything's ok.
But if I build the solution with TFS Build, when the tests are run I have a problem with this resource. During the build, the source files are copied in a directory (for example "D:\Build\1\My build projet\Sources\MyProjets\Res", and therefore "MyApp1" will look for "emailTemplate.html" in "D:\MyProjets\Res\emailTemplate.html" (configuration file) and of course won't be able to find it.
How should I do ?
I already know that my project shouldn't work with resources this way, but it's almost impossible for us to change that now, since it's the way we've been working in my company for a loooong time...
I thought about modifying the BuildProcessTemplate to force the Build server to run a getLatest on the Res projects exactly where I want. But I don't know if it's a good idea, or if it's even possible...
Thanks a lot for your help ! :)
Edit your build definition to include the "Res" project directory in the workspace as well. It should be automatically download/updated at each build (if you use any of the default process templates), and as long as you use relative paths in your tests you should be fine.