EDIT: Lea la respuesta número 1 de Tim Schmelter y luego use esta pregunta para ver ejemplos de cómo incrustar recursos y acceder a ellos en tiempo de ejecución.Desentrañando la confusión sobre los recursos incrustados
El tema de los recursos integrados surge mucho, especialmente cuando las personas preguntan cómo acceder a los archivos incrustados en el tiempo de ejecución. Las cosas se vuelven más confusas porque Visual Studio te ofrece 2 formas diferentes de incorporar un recurso y diferentes formas de acceder a esos recursos en tiempo de ejecución. El problema es que, dependiendo del método que utilizó para insertar el recurso, es posible que el método que está intentando usar para acceder al archivo en tiempo de ejecución no funcione. Esta publicación es un intento de aclarar toda la confusión que veo por ahí, pero también tengo una pregunta que nadie puede responder objetivamente: ¿por qué el tamaño de mi programa compilado es DOS veces el tamaño del recurso incrustado (a veces)? Por ejemplo, si incrusto un archivo de 20MB en mi proyecto, ¿por qué mi programa compila a 40MB? He hecho esta pregunta en el pasado y nadie ha podido reproducir mis resultados. Descubrí que la razón por la que no podían reproducirse era porque estaban integrando el archivo de una manera diferente. Ver aquí:
Método 1:
doble clic en Mi Proyecto para abrir las páginas de propiedades e ir a la pestaña Recursos. Ahora haga clic en Agregar recurso> Agregar archivo existente. Busque el archivo que desea incrustar. Para este ejemplo, estoy usando un ejecutable. Ahora verá su archivo en la pestaña Recursos:
También se verá que una carpeta denominada Recursos fue creado en virtud de su proyecto y el archivo incrustado se ha colocado en esta carpeta:
EDITAR: ESTE PRÓXIMO PASO FUE EL PROBLEMA. SE DICE QUE AL AGREGAR UN ARCHIVO MEDIANTE LA PESTAÑA DE RECURSOS, DEBERÍA NO CONFIGURAR LA ACCIÓN DE CONSTRUCCIÓN EN RECURSO INCOMBUSTIBLE. ¡Contador intuitivo por decir lo menos!
Ahora con el archivo seleccionado, observe la ventana de propiedades del archivo y cambie la acción de compilación a Recurso incrustado: (este paso SÓLO debe realizarse cuando agrega un archivo mediante el método 2).
Ahora compilar el programa. Verá que el tamaño de su programa compilado es al menos el doble del tamaño de su recurso incrustado. Esto no sucede con el método 2. Ver aquí:
Método 2:
Haga clic en el nombre del proyecto y seleccione Agregar> elemento existente. Vaya a su archivo, y esta vez se dará cuenta de que si bien era de hecho coloca debajo de su proyecto, no había ninguna carpeta de recursos creados:
Ahora, una vez más, seleccione el archivo y cambie la Acción de generación de Embedded Recurso y compilación. Esta vez, el tamaño del programa compilado será el esperado, aproximadamente el tamaño del archivo incrustado y no el doble del método 1.
El método que utilice para incrustar su archivo determinará qué método puede usar para acceder al archivo en tiempo de ejecución.Para el método 1 es muy simple, todo lo que tiene que hacer es:
My.Computer.FileSystem.WriteAllBytes(Path, My.Resources.ResourceName, Append)
donde ruta es la ubicación y el nombre del archivo que desea guardar en el disco duro, ResourceName es el nombre del recurso incrustado que se ver en la ventana del proyecto (menos cualquier extensión) y Anexar es si desea o no crear un nuevo archivo o sobrescribir un archivo existente. Así, por ejemplo, usando test.exe de las imágenes antedichas, pude guardar el archivo en la unidad C de esta manera:
My.Computer.FileSystem.WriteAllBytes(“C:\test.exe”, My.Resources.test, False)
no podría ser más sencillo.
Sin embargo, el Método 2 no parece darle acceso a Mis.Recursos, por lo que se vuelve un poco más complicado. Debe crear una secuencia para contener el recurso, colocar la secuencia en una matriz de bytes y luego escribir los bytes en el sistema de archivos. La forma más sencilla que he encontrado para hacerlo es la siguiente:
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
Con esta ResourceName método debe contener la extensión de archivo y el nombre del proyecto por lo que usar nuestro ejemplo desde arriba sólo podemos hacer:
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
archivos basados en texto son un poco diferentes:
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
Después de haber luchado con esto en el pasado espero que esto ayude a alguien. Y si crees que puedes explicar de manera fáctica por qué el método 1 de incrustación de un recurso hincha mi programa compilado para duplicar su tamaño, realmente lo agradecería.
Tienes toda la razón. Mi propia confusión fue pensar que la acción de compilación HABÍAN sido configurada como "recurso incrustado" incluso cuando se agregó el archivo a través de la pestaña de recursos. Me imagino que este es un error muy común. Entonces, dado que My.Resources hace las cosas mucho más fáciles, ¿por qué no quiero usar la pestaña de recursos para agregar recursos incrustados? –