РЕДАКТИРОВАТЬ: Прочтите ответ номер 1 от Тима Шмелтера, а затем используйте этот вопрос для примеров того, как встраивать ресурсы и получать к ним доступ во время выполнения.
Тема встроенных ресурсов поднимается часто, особенно когда люди спрашивают, как получить доступ к встроенным файлам во время выполнения. Ситуация становится еще более запутанной, потому что Visual Studio дает вам два разных способа встраивания ресурса и разные способы доступа к этим ресурсам во время выполнения. Проблема в том, что в зависимости от того, какой метод вы использовали для встраивания ресурса, метод, который вы пытаетесь использовать для доступа к файлу во время выполнения, может не работать.Этот пост представляет собой попытку прояснить всю путаницу, которую я вижу, но у меня также есть вопрос, на который никто не может ответить фактически: почему размер моей скомпилированной программы В ДВАЖДЫ больше размера встроенного ресурса (иногда)? Например, если я встраиваю в свой проект файл размером 20 МБ, почему моя программа компилируется до 40 МБ? Я задавал этот вопрос раньше, и никто не смог воспроизвести мои результаты. Я обнаружил, что причина, по которой они не смогли воспроизвести, заключалась в том, что они встраивали файл другим способом. См. Здесь:
Метод 1:
Дважды щелкните «Мой проект», чтобы открыть страницы свойств и перейти на вкладку «Ресурсы». Теперь нажмите Добавить ресурс> Добавить существующий файл. Найдите файл, который хотите встроить. В этом примере я использую исполняемый файл. Теперь вы увидите свой файл на вкладке «Ресурсы»:
Вы также увидите, что папка с именем «Ресурсы» была создана в рамках вашего проекта, а встроенный файл был помещен в эту папку:
РЕДАКТИРОВАТЬ: ЭТОТ СЛЕДУЮЩИЙ ШАГ БЫЛ ПРОБЛЕМОЙ . ВЫКЛЮЧАЕТСЯ, ЧТО ПРИ ДОБАВЛЕНИИ ФАЙЛА ЧЕРЕЗ ВКЛАДКУ РЕСУРСОВ ВЫ ДОЛЖНЫ НЕ УСТАНОВИТЬ ДЕЙСТВИЕ НА ВСТРОЕННЫЙ РЕСУРС. Счетчик интуитивно мягко говоря!
Теперь, когда файл выбран, посмотрите на окно свойств файла и измените действие сборки на Embedded Resource: (этот шаг должен выполняться ТОЛЬКО при добавлении файла с помощью метода 2).
Теперь скомпилируйте вашу программу. Вы увидите, что размер вашей скомпилированной программы как минимум вдвое превышает размер вашего встроенного ресурса. Этого не происходит с методом 2.См. Здесь:
Метод 2:
Щелкните правой кнопкой мыши имя проекта и выберите «Добавить»> «Существующий элемент». Перейдите к своему файлу, и на этот раз вы заметите, что, хотя он действительно был помещен в ваш проект, папка ресурсов не была создана:
Теперь еще раз выберите файл и измените действие сборки на встроенный ресурс и скомпилируйте. На этот раз размер скомпилированной программы будет таким, как вы ожидали - примерно размером встроенного файла, а не вдвое больше, чем в случае метода 1.
Какой метод вы используете для встраивания файла, определит, какой метод вы можете использовать для этого. получить доступ к файлу во время выполнения. Для метода 1 это очень просто, все, что вам нужно сделать, это:
My.Computer.FileSystem.WriteAllBytes(Path, My.Resources.ResourceName, Append)
Где Path - это расположение и имя файла, который вы хотите сохранить на жестком диске, ResourceName - это имя встроенного ресурса, который вы видите в проекте. window (без расширения), а Append - хотите ли вы создать новый файл или перезаписать существующий файл. Так, например, используя 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 встраивания ресурса увеличивает мою скомпилированную программу вдвое, я был бы очень признателен.