[在控制台应用程序中,我一直试图使OpenSolutionAsync运行几周而没有成功。
最后,我记得要查看包含样本的roslyn-sdk repository。我在本地运行了名为SolutionExplorer的示例,它可以完美运行。我可以选择一个解决方案文件,它可以打开该解决方案。
鉴于此示例有效,所以我决定使控制台应用程序与此类似。因此,我将MSBuildService和WorkspaceService复制到控制台应用程序(只是更改了日志记录行为)。将我的控制台应用程序更改为以.NET Framework v4.6.1为目标。引用了完全相同的nuget包。我确保删除bin文件夹,还将样本中的bin文件夹与为我的项目生成的bin文件夹进行了比较。他们是一样的。但是,当我进入OpenSolutionAsync()行时,我的控制台应用程序仅退出该过程。
我在做什么错?
更多信息:我复制了项目here,以使其易于使用。请提供两个参数来运行项目,例如:
callerid.scanner.exe -p "<path to some solution>" -d "<documentNameToFindInSolution>"
它退出WorkspaceService的第97行的处理
几件事,对不起VB,但您应该明白这一点。重要的是获取正确的MSBuild实例并捕获错误。
Property MSBuildInstance As VisualStudioInstance
' Get all instances of MSBuild
Private ReadOnly visualStudioInstances() As VisualStudioInstance = MSBuildLocator.QueryVisualStudioInstances().ToArray()
' Pick the instance of MSBuild you want
MSBuildInstance = visualStudioInstances(???)
MSBuildLocator.RegisterInstance(MSBuildInstance)
Using Workspace As MSBuildWorkspace = MSBuildWorkspace.Create()
AddHandler Workspace.WorkspaceFailed, AddressOf MSBuildWorkspaceFailed
Dim currentProject As Project = Workspace.OpenProjectAsync(FileName).Result
' Do something with the project
End Using
' Print message for WorkspaceFailed event to help diagnosing project load failures.
Private Sub MSBuildWorkspaceFailed(_1 As Object, e1 As WorkspaceDiagnosticEventArgs)
If MsgBox(e1.Diagnostic.Message, MsgBoxStyle.AbortRetryIgnore, "MSBuild Failed") = MsgBoxResult.Abort Then
End
End If
End Sub
您需要使用MSBuildLocator
类注册msbuild位置。这将允许MSBuildWorkspace
打开解决方案和项目。长话短说:它需要知道msbuild在哪里,因为它使用它来加载项目。
我会将以下代码放在您的服务的构造函数中
// Attempt to set the version of MSBuild.
var visualStudioInstances = MSBuildLocator.QueryVisualStudioInstances().ToArray();
var instance = visualStudioInstances.Length == 1
// If there is only one instance of MSBuild on this machine, set that as the one to use.
? visualStudioInstances[0]
// Handle selecting the version of MSBuild you want to use.
: SelectVisualStudioInstance(visualStudioInstances);
_logger.WriteLine($"Using MSBuild at '{instance.MSBuildPath}' to load projects.");
// NOTE: Be sure to register an instance with the MSBuildLocator
// before calling MSBuildWorkspace.Create()
// otherwise, MSBuildWorkspace won't MEF compose.
MSBuildLocator.RegisterInstance(instance);
发现了问题。我正在使用nuget程序包CommandLineParser。它与在使用CommandLineParser触发操作时使用异步有关。当我删除异步并调用OpenSolutionAsync()。Result时,它可以工作。
似乎CommandLineParser不支持异步实现。然后,在CommandLineParser的WithParsed方法中使用await进行调用时,OpenSolutionAsync会退出该过程。
这花了我数周的时间才能弄明白..无论如何,感谢您的回答,@ Jonathon Marolf和@Paul Cohen。