繁体   English   中英

是否可以通过代码中的名称引用Visual Studio中的嵌入式文件资源?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM