简体   繁体   English

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

[英]Can an embedded file resource in Visual Studio be referenced by name in code?

In Visual Studio 2010, I am including a zip file into my executable as an Embedded Resource and extracting it for use at runtime. 在Visual Studio 2010中,我将一个zip文件作为嵌入式资源包含到我的可执行文件中,并将其解压缩以在运行时使用。 Such a file cannot be included as a file resource (text or binary) because a file resource is always linked as a separate item, which is not what I want. 这样的文件不能作为文件资源(文本或二进制)包括在内,因为文件资源总是作为单独的项目链接的,这不是我想要的。 Consequently I cannot reference the file in my code through Properties.Resources . 因此,我无法通过Properties.Resources在代码中引用该文件。

To extract the zip file, I have to hardcode its name in my code as follows: 要解压缩该zip文件,我必须在代码中将其名称硬编码如下:

stream = Assembly.GetEntryAssembly().GetManifestResourceStream("myembeddedfile.zip");

I noticed that the zip file is referenced in the .csproj file as follows: 我注意到在.csproj文件中引用了zip文件,如下所示:

<ItemGroup>
    <EmbeddedResource Include="myembeddedfile.zip" />
    <None Include="packages.config" />
</ItemGroup>

However, I don't think that the above can be referenced from code. 但是,我认为以上内容不能从代码中引用。 (I know about the None usage from SO question #1060870 .) (我从#1060870问题中了解“ None用法。)

Is there any way I can include this file as a bonafide project/solution item and prevent having to hardcode the filename? 有什么办法可以将该文件作为真实项目/解决方案项包括在内,而不必对文件名进行硬编码?

EDIT: 编辑:

A non-hardcoded way to reference the file in code would be something like the following: 以非硬编码方式在代码中引用文件的方式将类似于以下内容:

GetManifestResourceStream(Properties.Resources.EmbeddedFile);

But as I have mentioned, the above is not possible because an embedded resource is not included in the Properties.Resources object. 但是,正如我已经提到的,以上是不可能的,因为Properties.Resources对象中没有包含嵌入式资源。

EDIT AFTER FOLLOW-UP EDIT BY DRapp TO HIS ACCEPTED ANSWER: 跟进DRapp编辑接受的答案后进行编辑:

The scheme involving enums by DRapp below is the ultimate solution to this problem, with one modification: when there are multiple resource files being embedded, the resource filenames will be returned by GetManifestResourceNames() in alphabetical order. 下面的DRapp涉及枚举的方案是对该问题的最终解决方案,但有一个修改:当嵌入多个资源文件时, GetManifestResourceNames()将按字母顺序返回资源文件名。 Therefore, the enum names must be arranged accordingly. 因此,必须相应地安排enum名称。 Before the following snapshot taken during debugging, the three embedded files were added manually in the following sequence: 1_FIRST, 3_THIRD, 2_SECOND , but as can be observed, the internal storage is alphabetical: 在调试期间拍摄以下快照之前,已按以下顺序手动添加了三个嵌入式文件: 1_FIRST, 3_THIRD, 2_SECOND ,但是可以看出,内部存储是按字母顺序排列的:

For the above example with three files, the corresponding enum would be defined as: 对于具有三个文件的上述示例,相应的enum将定义为:

public enum MyResources
{
    EmptyZipTest_1_FIRST_zip,
    EmptyZipTest_2_SECOND_zip,
    EmptyZipTest_3_THIRD_zip
}

With binary write stream credit from Jon Skeet's answer for the CopyStream function and calling it... You CAN embed a zip file. 使用Jon Skeet的 CopyStream函数答案的二进制写流功劳并调用它,您可以嵌入一个zip文件。

Also, as hintham mentioned, what you need to do (and I did and tested), I created an empty zip file and added it to my project. 另外,正如hintham所提到的,您需要做的事情(我做了并测试了),我创建了一个空zip文件并将其添加到我的项目中。 I called it "EmptyZipFile.zip". 我称它为“ EmptyZipFile.zip”。 On this file, for the properties, click on "Build Action" and change to "Embedded Resource". 在该文件的属性上,单击“生成操作”,然后更改为“嵌入资源”。 The name of my project (and namespace) is "EmptyZipTest" 我的项目(和名称空间)的名称是“ EmptyZipTest”

You were very close with getting your resource, but must include the fully qualified namespace PLUS the file name as it is embedded. 您与资源的获取非常接近,但是必须包含完全限定的名称空间以及嵌入的文件名。 To see a quick list of everything in your resources.. 快速查看资源中所有内容的列表。

StringBuilder sb = new StringBuilder();
foreach (string s in Assembly.GetEntryAssembly().GetManifestResourceNames())
   sb.AppendLine(s);

MessageBox.Show(sb.ToString());

By doing this, it would have exposed (per my sample project) a resource of 这样,它将(根据我的示例项目)公开以下资源:

"EmptyZipTest.EmptyZipFile.zip"

This is the file IN your executable. 这是可执行文件中的文件。 Now, if you want to copy this baseline zip file OUT to some new file name, create a simple function that may get another file name / location and provide that to create the file and write the zip file out. 现在,如果要将此基准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);
   }
}   

Obviously I don't have error checking / validation in this quick bit, but it SHOULD get you what you need. 显然,我没有快速进行错误检查/验证,但是应该可以为您提供所需的东西。 The internal file name will ALWAYS be a fixed value... What you write that stream OUT to is different... 内部文件名将始终是固定值...您将流OUT写入的内容是不同的...

OPTION vs Hardcoding strings. OPTION与硬编码字符串。

I think I see your point, and you could try this... Create an "enum" instance and put in your resources there, but substitute "." 我想我明白您的意思了,您可以尝试一下...创建一个“枚举”实例并在其中放置资源,但用“”代替。 for "_" in the enum as you can't have periods in the object names... such as 枚举中的“ _”,因为对象名称中不能包含句点...

   public enum MyResources
   {
      EmptyZipTest_EmptyZipFile_zip,
      EmptyZipTest_SomeOtherFile_jpg,
      EmptyZipTest_AnotherFile_ini
   }

Then, having that enum as a parameter, you won't accidentally misspell the hardcode names all over the place, but be required to have a proper referenced instance. 然后,使用该枚举作为参数,您不会在整个地方意外地拼写硬编码名称,而是需要具有适当的引用实例。 Then, in your function that process the getting of the streamed resource, you can .REPLACE() the "_" to "." 然后,在处理获取流式资源的函数中,可以将“ _”替换为“。”。 such as

   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.

相关问题 如何在 Visual Studio Code 中将文件标记为嵌入资源? - How to mark a file as an embedded resource in Visual Studio Code? 在Visual Studio中使用嵌入式资源的代码或命令 - Code or command to use embedded resource in Visual Studio 大文件作为Visual Studio 2012中的嵌入式资源 - Large file as embedded resource in Visual Studio 2012 如何以编程方式使自动生成的文件成为Visual Studio中的嵌入式资源? - How to programmatically make an autogenerated file an embedded resource in visual studio? 如果文件名中包含语言代码,则未嵌入C#资源 - C# resource not embedded if contains language code in file name 强制Visual Studio重建嵌入式资源 - Force Visual Studio Rebuild on Embedded Resource Changed 在Visual Studio扩展中未执行引用的代码 - Referenced Code not executing in Visual Studio Extension 逐步进入Visual Studio中引用的程序集代码 - Step in through referenced assemblies code in Visual Studio Visual Studio 插件显示资源文件中的文本而不是代码 - Visual Studio plugin to show the text from a resource file instead of the code 即使它具有未引用的类的名称,代码也可以在Visual Studio中编译并运行 - Code compiles and runs in Visual Studio even though it has the name of a class that isn't referenced
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM