如何使用生成操作内容发布引用文件



我有一个c#项目,需要加载一些yaml资源才能工作,我用"构建操作":"内容"one_answers"复制到输出目录":"如果更新则复制"设置了它们

为了加载它们,我只使用一个相对路径,所有的东西都在项目中工作。

我实现了xunit项目,该项目加载了库,并且一切仍然正常。

现在我在nuget上发布了库,我正试图在Asp.Net Core上引用,但当我试图加载文件时,应用程序试图在错误的文件夹中找到它们:

这些文件是在根asp.net项目的相对路径中搜索的,但文件位于C:\Users\[name]\.nuget\packages\[package name]\[version]\content 中

所以我想知道如何在C#中获取程序集的"内容"文件夹?

更新:我试图更好地解释

我有一个visual studio解决方案,我们称之为foo.sln,还有一个C#项目,我们称其为foo.csproj

该项目是一个网络标准2.0库,它被其他应用程序使用:cli、asp.net、core、wpf等

该库是为多平台构建的,因此可以在Windows、Mac和Linux 上运行

在foo项目的根目录中有一个文件夹,我们称之为YamlDefinitions在这个文件夹中,我们有很多.yaml文件,这些文件需要由我的foo库加载和解析。

所以foo.csproj有这样的东西:

<Content Include="YamlDefinitionsDefinition1.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="YamlDefinitionsDefinition2.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="YamlDefinitionsDefinition3.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="YamlDefinitionsDefinition4.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="..Foofoo.csproj" />

所有测试都通过了,所以我打包了库并发布了nuget包:foo.nuget

现在我想尝试使用我的nuget包,所以我用Net Core 2.2创建了一个新的控制台应用程序,我们称之为MyConsoleApp.csproj

我安装我的nuget包foo.nuget:

<PackageReference Include="Foo" Version="1.0.0"/>

软件包已安装,所有yaml文件都放置在中

C:UsersUserName\.nugetpackagesFoo1.0.0contentYamlDefinitions

C:UsersUserName\.nugetpackagesFoo1.0.0contentFilesanynetstandard2.0YamlDefinitions

这些文件在MyConsoleApp.csproj中也作为链接文件可见,但它们在项目中并不存在。

现在我启动了MyConsoleApp.exe,,但我遇到了一个错误,因为它无法找到这些yaml文件,因为应用程序试图将它们加载到与MyConsoleApp.exe相同的路径中

解决方法:从visual studio中,我选择MyConsoleApp.csproj中链接的所有yaml文件,并将其设置为CopyIfNewer

现在在cproj视觉工作室内添加以下代码行:

<Content Include="C:UsersUser.nugetpackagesFoo1.0.0contentFilesanynetstandard2.0YamlDefinitionsDefinition1.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

我再次运行MyConsoleApp.exe,一切正常。

这种解决方法很糟糕,因为最终用户应该能够使用nuget库,而无需手动指定复制文件。如果我发布了包含新定义的库的新版本,那么最终用户不应该意识到这些定义必须包含在项目中。

无论如何,还有一个更大的问题:

我创建了一个新的ASP.NET Core 2.2 MVC应用程序,我们称之为MyWebApp.csproj

我安装了Foo.nuget并尝试使用它。

我手动设置为复制输出文件夹中的所有Yaml定义,当我构建它们时,它们会自动复制到MyWebAppbinReleasenetcoreapp2.2YamlDefinitions

我启动了web应用程序,再次遇到错误,因为我的foo库试图在MyWebAppYamlDefinitions中查找文件,但文件在bin文件夹中,所以什么都不起作用。

如何以所有消费者应用程序都可以使用的方式修复我的库并作为nuget发布?

我找不到一个C#函数来检索存储内容文件的nuget文件夹,我怀疑它是否存在,但我找到了这种工作方法:

foo.csproj文件中,您需要指定每个文件都应该复制到输出文件夹中,这可以使用来完成

<Content Include="YamlDefinitionsDefinition1.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<PackageCopyToOutput>true</PackageCopyToOutput>
</Content>

您需要添加PackageCopyToOutput才能使用nuget,不幸的是,这无法从visual studio UI中完成,您必须手动编辑.csproj

在C#中,您必须使用绝对路径,因为相对路径在所有类型的应用程序中都不相同(在.NET cli中与ASP.NET不同(

所以你必须使用这样的代码:

var directory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "YamlDefinitions");
var filePaths = Directory.GetFiles(directory, "*.yaml", SearchOption.TopDirectoryOnly)

其中AppDomain.CurrentDomain.BaseDirectory返回复制内容文件的输出目录

相关内容

  • 没有找到相关文章

最新更新