C# 在资源中嵌入文本文件
我试图将一个文本文件嵌入到我的资源文件中的应用程序中。一段时间前,我一直在关注这个问题帖子C# 在资源中嵌入文本文件,c#,wpf,visual-studio-2010,embedded-resource,C#,Wpf,Visual Studio 2010,Embedded Resource,我试图将一个文本文件嵌入到我的资源文件中的应用程序中。一段时间前,我一直在关注这个问题帖子 我将文本文件添加到Resources.resx中,但不明白如何在代码中调用它。正如您所看到的,OP也有同样的问题,并使用My.Resources.TEXTFILENAME成功地使其工作,而不是Resources.TEXTFILENAME的顶级答案建议。不幸的是,在我的应用程序中两者都没有被识别,我也尝试添加usings,但VS没有提出任何建议。单独编写Resources,它会将其识别为ResourceD
我将文本文件添加到Resources.resx中,但不明白如何在代码中调用它。正如您所看到的,OP也有同样的问题,并使用
My.Resources.TEXTFILENAME
成功地使其工作,而不是Resources.TEXTFILENAME
的顶级答案建议。不幸的是,在我的应用程序中两者都没有被识别,我也尝试添加usings,但VS没有提出任何建议。单独编写Resources
,它会将其识别为ResourceDictionary和FrameworkElement。参考资料,但没有文本文件。。。有什么想法吗?使用.ResX资源与将文本文件嵌入程序集中略有不同。对于后者,您希望检查其属性并使其成为嵌入式资源(即,不需要向ResX文件添加任何内容,只需将文本文件放到您的VS项目中即可)。要检索它,请使用以下命令:
Assembly.GetExecutingAssembly().GetManifestResourceStream(name);
要获取name参数的正确值,请调用GetManifestResourceNames()并检查结果。将文本文件添加到项目中,然后将其定义为内容(
生成操作
=内容
)并始终复制
以输出
如果您的项目有安装程序(标准安装程序),则可以设置文件系统,以便安装程序自动复制文本文件
要获取运行应用程序的文件夹,我使用以下方法:
Path.GetDirectoryName(System.Reflection.Assembly.getExecutionGassembly.Location)代码>
如果您正在使用新的安装程序(ClicOnce),我无法帮助您,但祝您好运:=)像这样嵌入文本资源似乎是可行的(visual c#express):
打开项目属性
浏览到资源,单击Addnew并选择创建或添加现有资源,以正确为准。
此时会出现“野生资源”文件夹
像这样使用它们:
string foo = global::[ProjectName].Properties.Resources.Muistio;
string bar = global::[ProjectName].Properties.Resources.asd;
资源生成操作为无,复制到输出目录为不复制
如果有人能验证这一点就太好了,当exe被传输到我的服务器2k8时,它可以工作,但我仍然需要独立的验证。尤其是因为ResourceHacker没有看到字符串 如果文件很小,项目资源文件可以按照其他人的描述使用,但这样一来,该文件只能作为Unicode字符串检索,可能/可能比原始文件大两倍,并一次性全部加载到内存中
原始问题中提到的方法是将文本文件放在项目中的某个位置,在解决方案资源管理器中选择它,点击F4显示属性,然后将构建操作设置为嵌入资源,并将复制到输出目录设置为不复制
这与添加到.csproj中相同:
<ItemGroup>
<EmbeddedResource Include="Resources\TextFile.txt"/>
</ItemGroup>
这些名称类似于类名,以点分隔。如果您的项目是NamespaceName.ProjectName
,则资源文件位于Resources
子文件夹中,名为TextFile.txt
,资源名称将为
NamespaceName.ProjectName.Resources.TextFile.txt
GetManifestResourceStream
有一个重载,它接受一个类型,以便您可以执行
typeof(Program).Assembly.GetManifestResourceStream(
typeof(Program),
"Resources.TextFile.txt")
永远不依赖默认命名空间或项目输出文件名
这样做的缺点是,在“手表”窗口中,它们似乎无法工作。你可能会得到一个例外
System.ArgumentException "Cannot evaluate a security function."
在这种情况下,只需将代码编写到您可以随意执行的某个地方—例如,在静态方法中。因此,代码从程序集运行,而不是从调试器运行
并通过IFileProvider
:
dotnet add package Microsoft.Extensions.FileProviders.Embedded
using Microsoft.Extensions.FileProviders;
var fp = new EmbeddedFileProvider(typeof(Program).Assembly);
// get all resources as an enumerable
foreach (var fileInfo in fp.GetDirectoryContents(""))
Console.WriteLine($"Name: {fileInfo.Name}, Length: {fileInfo.Length}, ...");
// get a specific one by name
var stream = fp.GetFileInfo("Resources.TextFile.txt").CreateReadStream();
作为一个IFileProvider
,您可能会尝试从纯嵌入式资源托管.NET核心网站。Hmm。。。所以我使用了Assembly.getExecutionGassembly().GetManifestResourceStream(“Explaination.txt”)代码>和Explaination.txt在我的调试文件夹中,但这一行似乎没有任何作用。想法?我只是想在记事本中打开文本文件。实际上我没有使用任何安装程序。只是使用我生成的exe。但这不就是将文件复制到输出目录而不是嵌入它吗?@Nenotlep:我想你是对的。我必须是:Build Action=Resource/并且不复制。我会更新,如果你确认,不要犹豫,张贴一个答案,如果你能带来一些英特尔。+1有用的屏幕截图。另外,一个野生资源文件夹。。。太棒了。是的,但你不能流式传输。您必须使用属性@Nenotlep,或者使用ResourceManager.GetString(名称),但这会产生一个Unicode字符串-可能比文件大两倍。这在VS 2017中对我有效。截图非常有用。
dotnet add package Microsoft.Extensions.FileProviders.Embedded
using Microsoft.Extensions.FileProviders;
var fp = new EmbeddedFileProvider(typeof(Program).Assembly);
// get all resources as an enumerable
foreach (var fileInfo in fp.GetDirectoryContents(""))
Console.WriteLine($"Name: {fileInfo.Name}, Length: {fileInfo.Length}, ...");
// get a specific one by name
var stream = fp.GetFileInfo("Resources.TextFile.txt").CreateReadStream();