如何向 Roslyn 分析器 NuGet 包添加额外的 dll?

How to add additional dll to Roslyn analyzer NuGet package?

简而言之:我在我的代码分析器中引用了额外的 dll。单元测试都很好,而我按 F5 调试分析器。但是当这个分析器作为 NuGet 包安装到实际项目中时,它找不到额外的 dll & 崩溃。

#选读-问题详细版:

我已经编写了我的代码分析器(比如 MyAnalyzer)。它发现某些类型禁止在客户端代码中使用。它的 codeFix 将这些类型替换为我的自定义 dll 中允许的替换类型(比如 myCustom.dll)。我已将此 dll 作为依赖项添加到 MyAnalyzer.CodeFixes 项目和 MyAnalyzer.Test 分析器解决方案的单元测试项目。

当通过 F5 启动时它工作正常(在特殊打开的 VisualStudio 实例中)并成功通过所有单元测试。

但是当我:

诊断正常,但是当我尝试使用 codefix 时,它应该用 myCustom.dll 中的某个类型替换某些类型,我的分析器 找不到 myCustom.dll 并抛出一个异常

System.IO.FileNotFoundException : Could not load file or assembly 'myCustom, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

我可能以错误的方式添加了对我的 dll 的引用(不使用分析器)?或者可能(这只是我的假设)NuGet 包的任何依赖项也应该是 NuGet 包?

#Additional info(可能很重要):

构建输出看起来不错:构建输出的文件夹包含我引用的 dll。

我将其原样复制到 NuGet 本地提要文件夹。

但是安装包后出现的已安装包的缓存文件夹不包含myCustom.dll。它仅包含(除了一些小文件):

C:\Users\user1\.nuget\packages\myanalyzer[=19=].0.1\MyAnalyzer.0.0.1.nupkg

& 2 个 dll:

C:\Users\user1\.nuget\packages\myanalyzer[=20=].0.1\analyzers\dotnet\cs\MyAnalyzer.dll C:\Users\user1\.nuget\packages\myanalyzer[=21=].0.1\analyzers\dotnet\cs\MyAnalyzer.CodeFixes.dll

当我尝试手动将我的 dll 放在那里 - 打包 cahe 文件夹时,分析器仍然抛出异常。

And when I try to manually put my dll there - to package cahe folder, analyzer still throws exception.

这不是正确的方法。该问题描述了您在全局缓存下有一些错误的旧版本的 nuget。由于您没有将新版本更改为另一个,旧的错误 nuget 包与新版本相同,nuget 包管理器总是首先安装全局缓存下的版本,如果它没有找到相同版本的 nuget由 nuget 包管理器 UI 打包,然后它会从 nuget 包中下载特定的、不同的版本并将其送入全局缓存 C:\Users\xxx\.nuget\packages\,然后将其安装到您的项目。

您应该尝试以下步骤进行仔细检查:

1) 在本地提要下检查新打包的 nuget 包 myanalyzer。您可以使用 7zip 工具解压 myanalyzer.0.0.1.nupkg.

检查myCustom.dll是否在文件夹myanalyzer.0.0.1\analyzers\dotnet\cs\下。

还有,我发现错误是

Could not load file or assembly 'MyCustomDll, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies.

我很好奇为什么dll不对。错误是您使用了 MyCustomDll.dll 而不是 MyCustom.dll。您应该检查 Analyzers 文件并确保使用正确命名的文件。

然后,重新打包新的nuget工程,确保新发布的nuget包是正确的。

2)删除C:\Users\xxx\.nuget\packages\myanalyzer下的缓存文件夹。

如果你使用packages.config nuget管理格式,你也应该删除解决方案文件夹<solution_folder>\packages\myanalyzer.0.0.1下的文件夹。

3) 之后,在 包管理器下重新安装正确的版本 UI.

更新

抱歉,我忽略了您的分析器 nuget 项目的打包步骤。

实际上,如果你当前的nuget项目引用了dll,打包按钮没有义务将这些dll自动打包到nupkg文件中。

你得手动打包,不管你怎么做,你都得修改csproj文件。

解决方案

使用你的目标或另一个是在 myanalyzer.package.csproj 文件下添加这些:

<ItemGroup>
        <None Include ="$(TargetDir)mycustom.dll" pack="true" PackagePath="analyzers/dotnet/cs"></None>
</ItemGroup>

然后,重新打包项目,清理 nuget 缓存,然后安装新的。

I wonder, why all dlls are present twice at installed NuGet package: as separate files at packages\myanalyzer[=33=].0.1\analyzers\dotnet\cs & as part of archive in .nupkg file. Or all content of installed package folder, except .nupkg file, is just unpacked .nupkg?

nupkg 文件是你的 nuget 包的原始版本。它由您的 pack nuget 项目生成。包含 nupkg 的文件夹是本地 nuget 提要。

该文件夹类似于 nuget.org 来源。这个包含它的文件夹是nuget包源(nuget从这个路径下载nuget文件然后下载nupkg并在C:\Users\xxx\.nuget\packages下解压)

除了C:\Users\xxx\.nuget\packages就是global nuget cache folder.

所以它恢复了从本地提要下载的nuget包,如果你之前安装了相同版本的myanalyzer nuget包,它将始终安装相同的旧版本喜欢缓存文件夹中的 1.0.0,无论您是否打包了相同 1.0.0 版本的新版本。因为版本相同,所以VS IDE会判断cache文件夹下已经有相同的nuget包,总是安装旧的,不安装新的。

所以 所以我建议您删除该文件夹下的所有缓存文件。避免 VS 一直安装旧的缓存包。或者你应该为更新的 nuget 包设置一个新版本,比如 2.0.0.

就是这两个Folder的解释和区别

一个是原始的本地nuget包提要。另一个是本地nuget package feed下载包的存放路径和解包路径,会记录之前下载的包。这个你要注意了。