【问题标题】:MSBuildWorkspace OpenSolutionAsync() exits processMSBuildWorkspace OpenSolutionAsync() 退出进程
【发布时间】:2020-03-25 00:06:27
【问题描述】:

在控制台应用程序中,我一直试图让 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行退出进程

【问题讨论】:

  • 抛出了什么异常以及它的堆栈跟踪是什么?

标签: c# msbuild roslyn projects-and-solutions


【解决方案1】:

发现问题。 我正在使用 nuget 包CommandLineParser。它与使用 CommandLineParser 触发操作时使用异步有关。当我删除 async 并改为调用 OpenSolutionAsync().Result 时,它可以工作。

CommandLineParser 似乎不支持异步实现。然后 OpenSolutionAsync 在 CommandLineParser 的 WithParsed 方法中使用 await 调用时会退出进程。

这花了我几个星期才弄清楚.. 无论如何,感谢您的回答,@Jonathon Marolf 和 @Paul Cohen。

【讨论】:

    【解决方案2】:

    您需要使用 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);
    

    【讨论】:

    • 感谢您的评论,但我已经这样做了。见MSBuildService.cs。完全相同的代码在sample project from roslyn-sdk 中完美运行(打开解决方案)。但它在控制台应用程序中不起作用...
    • 啊,对不起。拉下你的 github repo 这个问题是你正在使用的System.Composition 的版本与你正在使用的MSBuildWorkspace 的版本不兼容。见this拉取请求
    • 您好 Jonathon,抱歉我在解决问题后忘记回复您的评论。谢谢你的时间。问题是异步操作的错误使用。但是我将 codeanalysis 和 msbuildworkspace nuget 包升级到了最新版本。现在即使在 .NET Core 中也能正常工作。谢谢!
    【解决方案3】:

    一些事情,对不起,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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-09
      相关资源
      最近更新 更多