![](/img/trans.png)
[英]How to mark a file as an embedded resource in Visual Studio Code?
[英]Can an embedded file resource in Visual Studio be referenced by name in code?
在Visual Studio 2010中,我将一个zip文件作为嵌入式资源包含到我的可执行文件中,并将其解压缩以在运行时使用。 这样的文件不能作为文件资源(文本或二进制)包括在内,因为文件资源总是作为单独的项目链接的,这不是我想要的。 因此,我无法通过Properties.Resources
在代码中引用该文件。
要解压缩该zip文件,我必须在代码中将其名称硬编码如下:
stream = Assembly.GetEntryAssembly().GetManifestResourceStream("myembeddedfile.zip");
我注意到在.csproj文件中引用了zip文件,如下所示:
<ItemGroup>
<EmbeddedResource Include="myembeddedfile.zip" />
<None Include="packages.config" />
</ItemGroup>
但是,我认为以上内容不能从代码中引用。 (我从#1060870问题中了解“ None
用法。)
有什么办法可以将该文件作为真实项目/解决方案项包括在内,而不必对文件名进行硬编码?
编辑:
以非硬编码方式在代码中引用文件的方式将类似于以下内容:
GetManifestResourceStream(Properties.Resources.EmbeddedFile);
但是,正如我已经提到的,以上是不可能的,因为Properties.Resources
对象中没有包含嵌入式资源。
在跟进DRapp编辑接受的答案后进行编辑:
下面的DRapp涉及枚举的方案是对该问题的最终解决方案,但有一个修改:当嵌入多个资源文件时, GetManifestResourceNames()
将按字母顺序返回资源文件名。 因此,必须相应地安排enum
名称。 在调试期间拍摄以下快照之前,已按以下顺序手动添加了三个嵌入式文件: 1_FIRST, 3_THIRD, 2_SECOND
,但是可以看出,内部存储是按字母顺序排列的:
对于具有三个文件的上述示例,相应的enum
将定义为:
public enum MyResources
{
EmptyZipTest_1_FIRST_zip,
EmptyZipTest_2_SECOND_zip,
EmptyZipTest_3_THIRD_zip
}
使用Jon Skeet的 CopyStream函数答案的二进制写流功劳并调用它,您可以嵌入一个zip文件。
另外,正如hintham所提到的,您需要做的事情(我做了并测试了),我创建了一个空zip文件并将其添加到我的项目中。 我称它为“ EmptyZipFile.zip”。 在该文件的属性上,单击“生成操作”,然后更改为“嵌入资源”。 我的项目(和名称空间)的名称是“ EmptyZipTest”
您与资源的获取非常接近,但是必须包含完全限定的名称空间以及嵌入的文件名。 快速查看资源中所有内容的列表。
StringBuilder sb = new StringBuilder();
foreach (string s in Assembly.GetEntryAssembly().GetManifestResourceNames())
sb.AppendLine(s);
MessageBox.Show(sb.ToString());
这样,它将(根据我的示例项目)公开以下资源:
"EmptyZipTest.EmptyZipFile.zip"
这是可执行文件中的文件。 现在,如果要将此基准zip文件OUT复制到某个新文件名,请创建一个简单的函数,该函数可能会获取另一个文件名/位置,并提供该功能来创建文件并写出zip文件。
public void WriteNewZipFile( string newFilePathAndName )
{
Stream zipStream = Assembly.GetEntryAssembly().GetManifestResourceStream(
"EmptyZipTest.EmptyZipFile.zip" );
if (zipStream != null)
{
using (Stream outStream = File.Create( newFilePathAndName ))
{
CopyStream(zipStream, outStream);
}
}
}
public static void CopyStream(Stream input, Stream output)
{
byte[] buffer = new byte[8 * 1024];
int len;
while ((len = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, len);
}
}
显然,我没有快速进行错误检查/验证,但是应该可以为您提供所需的东西。 内部文件名将始终是固定值...您将流OUT写入的内容是不同的...
OPTION与硬编码字符串。
我想我明白您的意思了,您可以尝试一下...创建一个“枚举”实例并在其中放置资源,但用“”代替。 枚举中的“ _”,因为对象名称中不能包含句点...
public enum MyResources
{
EmptyZipTest_EmptyZipFile_zip,
EmptyZipTest_SomeOtherFile_jpg,
EmptyZipTest_AnotherFile_ini
}
然后,使用该枚举作为参数,您不会在整个地方意外地拼写硬编码名称,而是需要具有适当的引用实例。 然后,在处理获取流式资源的函数中,可以将“ _”替换为“。”。 如
public Stream GetMyResource( MyResources myRes )
{
string actualResource = myRes.ToString().Replace( "_", "." );
// This would convert the sample enums above to
// EmptyZipTest.EmptyZipFile.zip,
// EmptyZipTest.SomeOtherFile.jpg,
// EmptyZipTest.AnotherFile.ini
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.