2012-01-13 29 views
12

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:

enter image description here

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:

enter image description here

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).

enter image description here

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:

enter image description here

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.

Respuesta

9

Supongo que el Método 1 está agregando los archivos dos veces.

Al menos esa es la conclusión de la thread above.

Cita:

Usted fue a la página de recursos de las propiedades del proyecto y ha añadido los archivos allí, ¿verdad? Luego ingresaste al Explorador de soluciones y cambiaste la Acción de creación de los archivos al Recurso incrustado, ¿verdad? Es por eso que duplicaba el tamaño del archivo: estaba agregando cada archivo dos veces.

Existen dos formas diferentes de agregar recursos: en la página Recursos de las propiedades del proyecto y en el Explorador de soluciones. NO haces las dos cosas. Si desea utilizar GetManifestResourcestream, entonces NO utiliza la página de Recursos. Agregue los archivos al proyecto en el Explorador de soluciones manualmente, luego configure la Acción de compilación en el Recurso incrustado.

En el futuro, haga uno u otro, no ambos.

  1. añadir un archivo a la página de recursos de las propiedades del proyecto y luego acceder a ella a través de My.Resources. Esto agregará automáticamente el archivo al proyecto en el Explorador de soluciones, pero la Acción de compilación será Ninguna y se debe dejar de esa manera.

  2. Agregue el archivo al proyecto en el Explorador de soluciones usando Agregar elemento nuevo o Agregar elemento existente. Establezca la acción de compilación del archivo en el recurso incrustado y luego acceda al recurso utilizando GetManifestResourceStream.

+0

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? –

Cuestiones relacionadas