【发布时间】:2019-05-17 04:54:02
【问题描述】:
我有一个需要加载一些 yaml 资源才能工作的 c# 项目,我已将它们设置为 "build action":"content" 和 "copy to Output directory":"Copy if newer"
为了加载它们,我只使用了一个相对路径,并且在项目中一切正常。
我实现了加载库的 xunit 项目,并且一切正常。
现在我在 nuget 上发布了该库,并尝试在 Asp.Net Core 上进行引用,但是当我尝试加载我的文件时,应用程序会尝试在错误的文件夹中找到它们:
从根 asp.net 项目的相对路径中搜索文件,但文件位于 C:\Users\[name]\.nuget\packages\[pakage name]\[version]\content
所以我想知道如何在 C# 中获取程序集的“内容”文件夹?
更新:我试着解释得更好
我有一个 Visual Studio 解决方案,我们称之为 foo.sln 和一个 C# 项目,我们称之为 foo.csproj
该项目是一个 netstandard 2.0 库,旨在供其他应用程序使用:cli、asp.net、core、wpf 等...
该库是为多平台构建的,因此可以在 Windows、Mac 和 Linux 上运行
在 foo 项目的根目录下有一个文件夹,我们称之为YamlDefinitions
在该文件夹中,我们有很多 .yaml 文件需要由我的 foo 库加载和解析。
所以foo.csproj 有类似的东西:
<Content Include="YamlDefinitions\Definition1.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="YamlDefinitions\Definition2.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="YamlDefinitions\Definition3.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="YamlDefinitions\Definition4.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
这些文件是不可变的,所以我将它们作为内容而不是作为资源加载
现在在我的 foo 库的 c# 代码中,我有:
var filePaths = Directory.GetFiles("YamlDefinitions", "*.yaml", SearchOption.TopDirectoryOnly)
foreach (var filePath in filePaths)
{
using (var reader = new StreamReader(filePath))
{
// Load the stream
var yamlStream = new YamlStream();
yamlStream.Load(reader);
yaml = yamlStream.Documents.FirstOrDefault();
}
}
该代码搜索、加载和解析所有可以在指定文件夹中找到的 yaml 文件。
一切似乎都还好,所以现在为了测试我在foo.sln 中创建了一个xunit 项目,我们称之为footest.csproj
现在我在footest.csproj 中引用foo.csproj
<ProjectReference Include="..\Foo\foo.csproj" />
所有测试都通过了,所以我打包了库并发布了 nuget 包:foo.nuget
现在我想尝试使用我的 nuget 包,所以我用 Net Core 2.2 创建了一个新的控制台应用程序,我们称之为MyConsoleApp.csproj
我安装了我的 nuget 包 foo.nuget:
<PackageReference Include="Foo" Version="1.0.0"/>
包安装完毕,所有yaml文件都放在
C:\Users\UserName\\.nuget\packages\Foo\1.0.0\content\YamlDefinitions
在
C:\Users\UserName\\.nuget\packages\Foo\1.0.0\contentFiles\any\netstandard2.0\YamlDefinitions
这些文件在 MyConsoleApp.csproj 中也作为链接文件可见,但它们实际上并不存在于项目中。
现在我启动我的 MyConsoleApp.exe, 并收到错误,因为它无法找到这些 yaml 文件,因为应用程序试图将它们加载到与 MyConsoleApp.exe 相同的路径中
解决方法:从 Visual Studio 中,我选择链接在 MyConsoleApp.csproj 内的所有 yaml 文件,并将其设置为 CopyIfNewer
现在在 cproj Visual Studio 内部添加了这些代码行:
<Content Include="C:\Users\User\.nuget\packages\Foo\1.0.0\contentFiles\any\netstandard2.0\YamlDefinitions\Definition1.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
我再次运行MyConsoleApp.exe,一切正常。
这种解决方法很糟糕,因为最终用户应该能够使用 nuget 库而无需手动指定复制文件。 如果我发布包含新定义的库的新版本,最终用户不应该知道这些必须包含在项目中。
不管怎样,还有一个更大的问题:
我创建了一个新的 ASP.NET Core 2.2 MVC 应用程序,我们称之为MyWebApp.csproj
我安装了Foo.nuget 并尝试使用它。
我手动设置复制输出文件夹中的所有 Yaml 定义,当我构建它们时,它们会自动复制到 MyWebApp\bin\Release\netcoreapp2.2\YamlDefinitions
我启动 web 应用程序,但我再次收到错误,因为我的 foo libray 试图在 MyWebApp\YamlDefinitions 中查找文件,但文件在 bin 文件夹中,所以没有任何效果。
如何修复我的库并以所有消费者应用程序都可以使用的方式发布为 nuget?
【问题讨论】:
-
@HGSandhagen 对不起,我不明白,我的文件在 nuget 中正确打包,是的,它们没有复制到 bin 目录中,但我不在乎它们在哪里,我只需要一种方法引用它们。我想避免在 nuspec 中为它们中的每一个指定一个输出目录,它们确实是很多文件。我需要一个返回我的 C# 函数:“C:\Users[name].nuget\packages[pakage name][version]\content”
-
恐怕这行不通,因为 nuget 包是在构建磁贴处下载的。当您在目标系统上安装应用程序时,它们将不存在。
-
@H.G. Sandhagen 很抱歉,但我仍然不明白。这些文件由 nuget 库使用,而不是由目标应用程序使用。我需要图书馆能够读取它需要的文件。当您下载 nuget 包时,您还下载了内容文件,只是它们与程序集 dll 不在同一目录中,所以我不能使用相对路径。如果我不能使用相对路径,因为 nuget 将文件放在它想要的位置,我需要一个 C# 函数来检索它们。
-
可能我没理解对。如果我错了,请纠正我。您创建了一个需要一些配置文件才能运行的库。该库需要输出文件夹(可执行文件的文件夹)中的文件。然后从这个库创建一个 nuget 包,并在 ASP.NET Core 应用程序中引用这个包。然后 nuget 包负责将包中的所有内容复制到引用应用程序的文件夹树中。我以前没有这样做,但我知道有办法做到这一点。
标签: c# path directory resources nuget