РЕДАКТИРОВАТЬ: прочитайте ответ № 1 от Тима Шмельтера, а затем используйте этот вопрос для примеров того, как встраивать ресурсы и получать к ним доступ во время выполнения.
Тема встроенных ресурсов возникаетмного, особенно когда люди спрашивают, как получить доступ к встроенным файлам во время выполнения.Все становится более запутанным, потому что Visual Studio предоставляет вам 2 разных способа встраивания ресурса и разные способы доступа к этим ресурсам во время выполнения.Проблема заключается в том, что в зависимости от того, какой метод вы использовали для встраивания ресурса, метод, который вы пытаетесь использовать для доступа к файлу во время выполнения, может не работать.Этот пост является попыткой прояснить всю путаницу, которую я вижу там, но у меня также есть вопрос, на который никто не может ответить фактически: почему размер моей скомпилированной программы ДВАЖДЫ размер встроенного ресурса (иногда)?Например, если я встраиваю файл размером 20 МБ в мой проект, почему моя программа компилируется в 40 МБ?Я задавал этот вопрос в прошлом, и никто не смог воспроизвести мои результаты.Я обнаружил, что причина, по которой они не смогли воспроизвести, была в том, что они встраивали файл другим способом.См. Здесь:
Метод 1:
Дважды щелкните Мой проект, чтобы открыть страницы свойств и перейти на вкладку Ресурсы.Теперь нажмите Добавить ресурс> Добавить существующий файл.Перейдите к файлу, который вы хотите встроить.Для этого примера я использую исполняемый файл.Теперь вы увидите ваш файл на вкладке Ресурсы:
![enter image description here](https://i.stack.imgur.com/leFt1.jpg)
Вы также увидите, что в вашем проекте была создана папка с именем Resources, а встроенный файл был помещен в эту папку.:
![enter image description here](https://i.stack.imgur.com/8Dts1.jpg)
РЕДАКТИРОВАТЬ: НА ЭТОМ СЛЕДУЮЩЕМ ШАГЕ БЫЛА ПРОБЛЕМА.ВЫРАЖАЕТ, ЧТО, КОГДА ВЫ ДОБАВЛЯЕТЕ ФАЙЛ, ЧЕРЕЗ ТАБЛИЦУ РЕСУРСОВ, КОТОРЫЕ ВЫ ДОЛЖНЫ НЕ УСТАНОВИТЕ ДЕЙСТВИЕ СТРОИТЕЛЬСТВА ДЛЯ ВСТРОЕННОГО РЕСУРСА. Счетчик интуитивно понятен, по меньшей мере!
Теперь с выбранным файломпосмотрите на окно свойств файла и измените действие сборки на Embedded Resource: (этот шаг следует выполнять ТОЛЬКО при добавлении файла с помощью метода 2).
![enter image description here](https://i.stack.imgur.com/lot1P.jpg)
Теперь скомпилируйте вашу программу.Вы увидите, что размер вашей скомпилированной программы как минимум вдвое больше размера вашего встроенного ресурса.Этого не происходит со способом 2. См. Здесь:
Метод 2:
Щелкните правой кнопкой мыши имя вашего проекта и выберите «Добавить»> «Существующий элемент».Перейдите к своему файлу, и на этот раз вы заметите, что, хотя он действительно был размещен в вашем проекте, папка ресурсов не была создана:
![enter image description here](https://i.stack.imgur.com/jauSC.jpg)
Теперь еще раз выберите файл иизмените Build Action на Embedded Resource и скомпилируйте.На этот раз размер скомпилированной программы будет таким, как вы ожидаете, - размером с внедренный файл, а не с удвоенным размером, как при методе 1.
Какой метод вы используете для встраивания вашего файла, будет определять, какой метод вы используете.можно использовать для доступа к файлу во время выполнения.Для метода 1 это очень просто, все, что вам нужно сделать, это:
My.Computer.FileSystem.WriteAllBytes(Path, My.Resources.ResourceName, Append)
Где Path - это местоположение и имя файла, который вы хотите сохранить на жестком диске, ResourceName - это имя встроенного ресурса.который вы видите в окне проекта (за вычетом любого расширения), а «Добавить» означает, хотите ли вы создать новый файл или перезаписать существующий файл.Так, например, используя test.exe из приведенных выше изображений, я мог бы сохранить этот файл на диске C следующим образом:
My.Computer.FileSystem.WriteAllBytes(“C:\test.exe”, My.Resources.test, False)
Не может быть проще.
Метод 2, однако, неПохоже, что у вас нет доступа к My.Resources, поэтому все становится немного сложнее.Вы должны создать поток для хранения ресурса, поместить поток в байтовый массив, а затем записать байты в файловую систему.Я нашел самый простой способ сделать это следующим образом:
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 встраивания ресурса увеличивает мою скомпилированную программу, удваивая ее размер, я был бы очень признателен.