如何将 Roslyn 用于网站项目?



在我的Visual Studio包中,我得到了Josh Varty描述的VisualStudioWorkspace。 https://joshvarty.com/2014/09/12/learn-roslyn-now-part-6-working-with-workspaces/

使用 EnvDTE.Project对象,我通过比较属性 CodeAnalysis.Project.FilePath 和 EnvDTE.Project.FileName 在 VisualStudioWorkspace.Projects 中查找匹配的 Roslyn 项目。

如果我找到匹配项,那么我知道该项目支持 Roslyn,并且可以在 CodeAnalysis.Project.Documents 集合中找到文档。到目前为止,这对于 C# 和 VB 项目来说效果很好。

如果我找不到匹配项,那么它可能是一个不支持 Roslyn 的C++项目。

但是,我现在发现网站项目的行为完全不同。

我在Visual Studio 2019中创建了一个新的网站项目。尽管该解决方案仅包含一个项目,但 VisualStudioWorkspace 包含两个 CodeAnalysis.Project 对象,如下所示:

?VSWorkspace.CurrentSolution.Projects(0)
1_Default.aspx
AdditionalDocumentIds: Count = 0
AdditionalDocuments: {System.Linq.Enumerable.WhereSelectEnumerableIterator(Of Microsoft.CodeAnalysis.DocumentId, Microsoft.CodeAnalysis.TextDocument)}
AllProjectReferences: Length = 1
AnalyzerConfigDocuments: {System.Linq.Enumerable.WhereSelectEnumerableIterator(Of System.Collections.Generic.KeyValuePair(Of Microsoft.CodeAnalysis.DocumentId, Microsoft.CodeAnalysis.AnalyzerConfigDocumentState), Microsoft.CodeAnalysis.AnalyzerConfigDocument)}
AnalyzerOptions: {Microsoft.CodeAnalysis.Diagnostics.AnalyzerOptions}
AnalyzerReferences: Length = 0
AssemblyName: "1_Default"
CompilationOptions: {Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions}
DefaultNamespace: ""
DocumentIds: Count = 2
Documents: {System.Linq.Enumerable.WhereSelectEnumerableIterator(Of Microsoft.CodeAnalysis.DocumentId, Microsoft.CodeAnalysis.Document)}
FilePath: Nothing
HasDocuments: True
Id: (ProjectId, #ca6b1f58-967a-4c31-a874-71d7720dd972 - 1_Default.aspx)
IsSubmission: False
Language: "C#"
LanguageServices: {Microsoft.CodeAnalysis.Host.Mef.MefLanguageServices}
MetadataReferences: Length = 56
Name: "1_Default.aspx"
OutputFilePath: Nothing
OutputRefFilePath: Nothing
ParseOptions: {Microsoft.CodeAnalysis.CSharp.CSharpParseOptions}
ProjectReferences: {System.Linq.Enumerable.WhereEnumerableIterator(Of Microsoft.CodeAnalysis.ProjectReference)}
Solution: {Microsoft.CodeAnalysis.Solution}
SupportsCompilation: True
Version: {2019-10-13T06:46:42.2691386Z-10141-0}
?VSWorkspace.CurrentSolution.Projects(1)
2_App_Code
AdditionalDocumentIds: Count = 0
AdditionalDocuments: {System.Linq.Enumerable.WhereSelectEnumerableIterator(Of Microsoft.CodeAnalysis.DocumentId, Microsoft.CodeAnalysis.TextDocument)}
AllProjectReferences: Length = 0
AnalyzerConfigDocuments: {System.Linq.Enumerable.WhereSelectEnumerableIterator(Of System.Collections.Generic.KeyValuePair(Of Microsoft.CodeAnalysis.DocumentId, Microsoft.CodeAnalysis.AnalyzerConfigDocumentState), Microsoft.CodeAnalysis.AnalyzerConfigDocument)}
AnalyzerOptions: {Microsoft.CodeAnalysis.Diagnostics.AnalyzerOptions}
AnalyzerReferences: Length = 0
AssemblyName: "App_Code.yy7qumxk"
CompilationOptions: {Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions}
DefaultNamespace: ""
DocumentIds: Count = 5
Documents: {System.Linq.Enumerable.WhereSelectEnumerableIterator(Of Microsoft.CodeAnalysis.DocumentId, Microsoft.CodeAnalysis.Document)}
FilePath: Nothing
HasDocuments: True
Id: (ProjectId, #12ab68ac-7b29-4252-87c2-67dc2f3d0696 - 2_App_Code)
IsSubmission: False
Language: "C#"
LanguageServices: {Microsoft.CodeAnalysis.Host.Mef.MefLanguageServices}
MetadataReferences: Length = 53
Name: "2_App_Code"
OutputFilePath: Nothing
OutputRefFilePath: Nothing
ParseOptions: {Microsoft.CodeAnalysis.CSharp.CSharpParseOptions}
ProjectReferences: {System.Linq.Enumerable.WhereEnumerableIterator(Of Microsoft.CodeAnalysis.ProjectReference)}
Solution: {Microsoft.CodeAnalysis.Solution}
SupportsCompilation: True
Version: {2019-10-13T06:46:41.6118955Z-10139-2}

首先,两个项目中的 FilePath 属性都是空的,所以我无法通过其文件名来识别项目。

这两个项目共包含七个文件,分别是:

"C:DotNetTestPrograms2019CSWebSite1Default.aspx.cs"
"C:DotNetTestPrograms2019CSWebSite1Default.aspx"
"C:DotNetTestPrograms2019CSWebSite1App_CodeBundleConfig.cs"
"C:DotNetTestPrograms2019CSWebSite1App_CodeIdentityModels.cs"
"C:DotNetTestPrograms2019CSWebSite1App_CodeRouteConfig.cs"
"C:DotNetTestPrograms2019CSWebSite1App_CodeStartup.Auth.cs"
"C:DotNetTestPrograms2019CSWebSite1App_CodeStartup.cs"

这不是项目中文档的完整列表。该项目包含七个附加代码隐藏文件:

AccountLogin.apsx.cs
AccountManage.apsx.cs
AccountOpenAuthProviders.ascx.cs
AccountRegister.apsx.cs
AccountRegisterExternalLogin.apsx.cs
Site.master.cs
ViewSwitcher.ascx.cs

我的问题是,我可以在网站项目中与 Roslyn 合作吗?

显然,EnvDTE和CodeAnalysis项目之间没有一对一的关系。我想我可以解决这个问题。

但是丢失的文件呢?不是没有另外七个代码隐藏文件的 Roslyn 文档吗?

我终于再次研究了这个问题,并找到了以下解决方案。

仅当文档在 Visual Studio 中打开时,此方法才有效。因此,我从

projectItem.Open ( EnvDTE.Constants.vsViewKindTextView ) ;

(我的函数中已经有项目项,所以这很容易。

然后,使用文件的完整路径(FullPath(和VisualStudioWorkspace(VSWorkspace(,我可以通过以下方式获得Roslyn文档

var docid = VSWorkspace.CurrentSolution.GetDocumentIdsWithFilePath(FullPath).FirstOrDefault() ;
if ( docid != null )
{
var RoslynDoc = VSWorkspace.CurrentSolution.GetDocument ( docid ) ;
}

如果文档尚未打开,则最好在完成后再次关闭它。您可以确定文档以前是否使用

var wasOpen = projectItem.IsOpen ( EnvDTE.Constants.vsViewKindTextView ) ;

顺便说一下,像这样打开文档不会使窗口在Visual Studio中可见(在我的应用程序中很好(。如果你想让它可见,你可以像这样打开它:

var wnd = projectItem.Open ( EnvDTE.Constants.vsViewKindTextView ) ;
wnd.Visible = true ;

最新更新