如何从 roslyn 代码分析器输出文件?
How to output a file from a roslyn code analyzer?
我正在使用 roslyn API 编写 DiagnosticAnalyzer 和 CodeFix。
收集完所有字符串和字符串插值后,我想将它们全部写入一个文件,但我不确定如何以最佳方式执行此操作。
当然我总是可以简单地做一个 File.WriteAllText(...)
但我想向用户公开更多控制权。
我也不确定如何最好地触发此文件的生成,所以我的问题是:
我不想对文件名进行硬编码,将此设置公开给代码分析器用户的最佳方法是什么?配置文件?如果是这样,我将如何访问它?即:我怎么知道目录?
如果文件中缺少一个字符串,我想建议像 "Project contains changed or new strings, regenerate string file" 这样的代码修复。这是最好的方法吗?或者是否可以在 visual studio?
中添加按钮或其他内容
我正在从命令行调用 devenv.com
可执行文件来触发构建,有没有办法在构建时强制我的代码修复到 运行,或者 before/after?或者我是否必须 "manually" 使用 roslyn 加载解决方案并执行我的代码修复?
对于配置文件,您可以使用 AdditionalFiles
msbuild 属性,它通过上下文传递给分析器。参见 here。
我刚刚完成了一个项目。您需要做/知道一些事情。
- 您可能需要将可移植 class 库切换为 class 库。否则你将无法调用
File.WriteAllText()
您可以了解如何将便携式 class 库转换为常规 here
- 当尝试将所有更改应用到 document/project/solution 时,这可能无法正常工作。从 document/project/solution 调用时,更改会预先计算并在预览中应用 window。如果您取消,将触发撤消操作以撤消所有更改,如果您在此期间写入文件,并且不注册撤消操作,您将不会撤消对文件的更改。
我已经用 roslyn 打开了一个错误,但你可以通过覆盖预览来处理实例,你可以看到如何这样做
您可能需要知道的最后一件事是如何从分析器访问解决方案,目前我已经编写了一个 hack 来做到这一点
正如 Tamas 所说,您可以使用其他文件,您可以了解如何使用 here
您可以使用附加文件,但我知道在我使用资源文件的版本上,默认情况下未标记为附加文件,它们是 embeddedResources。
因此,为了让我的用户不必手动将资源标记为 additonalFiles,我编写了一个函数来使用 xDoc 从 csproj 文件中取出与资源文件关联的 Designer.cs 文件,如果您选择,可以将其用作示例解析 csproj 文件:
protected List<string> GetEmbeddedResourceResxDocumentPaths(Project project)
{
XDocument xmldoc = XDocument.Load(project.FilePath);
XNamespace msbuild = "http://schemas.microsoft.com/developer/msbuild/2003";
var resxFiles = new List<string>();
foreach (var resource in xmldoc.Descendants(msbuild + "EmbeddedResource"))
{
string includePath = resource.Attribute("Include").Value;
var includeExtension = Path.GetExtension(includePath);
if (0 == string.Compare(includeExtension, RESX_FILE_EXTENSION, StringComparison.OrdinalIgnoreCase))
{
var outputTag = resource.Elements(msbuild + LAST_GENERATED_TAG).FirstOrDefault();
if (null != outputTag)
{
resxFiles.Add(outputTag.Value);
}
}
}
return resxFiles;
}
我正在使用 roslyn API 编写 DiagnosticAnalyzer 和 CodeFix。
收集完所有字符串和字符串插值后,我想将它们全部写入一个文件,但我不确定如何以最佳方式执行此操作。
当然我总是可以简单地做一个 File.WriteAllText(...)
但我想向用户公开更多控制权。
我也不确定如何最好地触发此文件的生成,所以我的问题是:
我不想对文件名进行硬编码,将此设置公开给代码分析器用户的最佳方法是什么?配置文件?如果是这样,我将如何访问它?即:我怎么知道目录?
如果文件中缺少一个字符串,我想建议像 "Project contains changed or new strings, regenerate string file" 这样的代码修复。这是最好的方法吗?或者是否可以在 visual studio?
中添加按钮或其他内容
我正在从命令行调用
devenv.com
可执行文件来触发构建,有没有办法在构建时强制我的代码修复到 运行,或者 before/after?或者我是否必须 "manually" 使用 roslyn 加载解决方案并执行我的代码修复?
对于配置文件,您可以使用 AdditionalFiles
msbuild 属性,它通过上下文传递给分析器。参见 here。
我刚刚完成了一个项目。您需要做/知道一些事情。
- 您可能需要将可移植 class 库切换为 class 库。否则你将无法调用
File.WriteAllText()
您可以了解如何将便携式 class 库转换为常规 here
- 当尝试将所有更改应用到 document/project/solution 时,这可能无法正常工作。从 document/project/solution 调用时,更改会预先计算并在预览中应用 window。如果您取消,将触发撤消操作以撤消所有更改,如果您在此期间写入文件,并且不注册撤消操作,您将不会撤消对文件的更改。
我已经用 roslyn 打开了一个错误,但你可以通过覆盖预览来处理实例,你可以看到如何这样做
您可能需要知道的最后一件事是如何从分析器访问解决方案,目前我已经编写了一个 hack 来做到这一点
正如 Tamas 所说,您可以使用其他文件,您可以了解如何使用 here
您可以使用附加文件,但我知道在我使用资源文件的版本上,默认情况下未标记为附加文件,它们是 embeddedResources。
因此,为了让我的用户不必手动将资源标记为 additonalFiles,我编写了一个函数来使用 xDoc 从 csproj 文件中取出与资源文件关联的 Designer.cs 文件,如果您选择,可以将其用作示例解析 csproj 文件:
protected List<string> GetEmbeddedResourceResxDocumentPaths(Project project)
{
XDocument xmldoc = XDocument.Load(project.FilePath);
XNamespace msbuild = "http://schemas.microsoft.com/developer/msbuild/2003";
var resxFiles = new List<string>();
foreach (var resource in xmldoc.Descendants(msbuild + "EmbeddedResource"))
{
string includePath = resource.Attribute("Include").Value;
var includeExtension = Path.GetExtension(includePath);
if (0 == string.Compare(includeExtension, RESX_FILE_EXTENSION, StringComparison.OrdinalIgnoreCase))
{
var outputTag = resource.Elements(msbuild + LAST_GENERATED_TAG).FirstOrDefault();
if (null != outputTag)
{
resxFiles.Add(outputTag.Value);
}
}
}
return resxFiles;
}