![](/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.