【发布时间】:2012-02-09 17:46:02
【问题描述】:
编辑:阅读 Tim Schmelter 的第 1 个答案,然后使用此问题作为示例,了解如何嵌入资源并在运行时访问它们。
嵌入式资源的主题出现了很多,尤其是人们询问如何在运行时访问嵌入式文件。事情变得更加混乱,因为 Visual Studio 为您提供了两种不同的嵌入资源的方式,以及在运行时访问这些资源的不同方式。问题在于,根据您用于嵌入资源的方法,您尝试在运行时访问文件的方法可能不起作用。这篇文章试图澄清我在那里看到的所有困惑,但我还有一个似乎没人能如实回答的问题:为什么我编译的程序的大小是嵌入资源的大小(有时)的两倍?例如,如果我将一个 20MB 的文件嵌入到我的项目中,为什么我的程序编译为 40MB?我过去曾问过这个问题,但没有人能够重现我的结果。我发现他们无法重现的原因是因为他们以不同的方式嵌入文件。见这里:
方法一:
双击我的项目打开属性页并转到资源选项卡。现在单击添加资源 > 添加现有文件。浏览到要嵌入的文件。对于此示例,我使用的是可执行文件。您现在将在“资源”选项卡上看到您的文件:
您还将看到在您的项目下创建了一个名为 Resources 的文件夹,并且嵌入的文件已放置在此文件夹中:
编辑:下一步就是问题所在。事实证明,当您通过资源选项卡添加文件时,您不应该不将构建操作设置为嵌入资源。至少可以说是反直觉的!
现在选择文件,向下查看文件的属性窗口并将构建操作更改为 Embedded Resource:(此步骤仅应在您通过方法 2 添加文件时执行)。
现在编译你的程序。您将看到编译程序的大小至少是嵌入式资源大小的两倍。方法 2 不会发生这种情况。请参见此处:
方法二:
右键单击您的项目名称并选择“添加”>“现有项目”。浏览到你的文件,这一次你会注意到虽然它确实放在你的项目下,但没有创建 Resources 文件夹:
现在再次选择文件并将 Build Action 更改为 Embedded Resource 并编译。这次编译程序的大小将如您所料 - 大约是嵌入文件的大小,而不是方法 1 的两倍。
您使用哪种方法嵌入文件将决定您可以使用哪种方法在运行时访问该文件。对于方法1,这很简单,你所要做的就是:
My.Computer.FileSystem.WriteAllBytes(Path, My.Resources.ResourceName, Append)
其中 Path 是您要保存在硬盘上的文件的位置和名称,ResourceName 是您在项目窗口中看到的嵌入资源的名称(减去任何扩展名),Append 是您是否想要创建新文件或覆盖现有文件。因此,例如,使用上图中的 test.exe,我可以像这样将该文件保存到 C 盘:
My.Computer.FileSystem.WriteAllBytes(“C:\test.exe”, My.Resources.test, False)
再简单不过了。
然而,方法 2 似乎无法让您访问 My.Resources,因此它变得有点复杂。您必须创建一个 Stream 来保存资源,将流放入字节数组,然后将字节写入文件系统。我发现的最简单的方法是这样的:
Using s As Stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(Project.ResourceName)
Dim bytes(s.Length) As Byte
s.Read(bytes, 0, bytes.Length)
File.WriteAllBytes(OutputFile, bytes)
End Using
使用此方法,ResourceName 必须包含文件扩展名和项目名称,因此使用上面的示例,我们可以这样做:
Using s As Stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(WindowsApplication1.test.exe)
Dim bytes(s.Length) As Byte
s.Read(bytes, 0, bytes.Length)
File.WriteAllBytes(“C:\test.exe”, bytes)
End Using
基于文本的文件有点不同:
Dim output As String
Using sr As StreamReader = New StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(WindowsApplication1.test.txt))
output = sr.ReadToEnd()
End Using
Using sw As StreamWriter = New StreamWriter(“C:\test.txt”)
sw.Write(output)
End Using
过去一直在努力解决这个问题,我希望这会对某人有所帮助。如果您认为您可以如实解释为什么嵌入资源的方法 1 会使我编译的程序膨胀到两倍大小,我将不胜感激。
【问题讨论】:
标签: vb.net visual-studio embedded-resource