Cómo incrustar y tener acceso a recursos mediante Visual C#

Para una versión de Microsoft Visual Basic .NET de este artículo, consulte 319291 .


En este artículo se refiere a los siguientes espacios de nombres de biblioteca de clases de Microsoft.NET Framework:
  • System.Reflection
  • System.IO

EN ESTA TAREA

Resumen

En este artículo paso a paso se describe cómo utilizar Visual C# para incrustar recursos como parte del ensamblado y, a continuación, tener acceso a los recursos en tiempo de ejecución.


Información general

El.NET Framework puede encapsular los archivos como parte de un ensamblado compilado. Estos archivos se conocen como recursos incrustados. Estos recursos son completamente independientes de los archivos .resources y .resx que están asociados con el ensamblado. Puede tener acceso a estos recursos en tiempo de ejecución a través de la clase del ensamblado del espacio de nombres System.Reflection .

Una ventaja importante de incrustar recursos en el manifiesto es que porque los archivos forman parte de su ensamblado compilado, el usuario no puede accidentalmente eliminar o pierde los archivos que son críticos para su aplicación, que en algunos casos, puede impedir la ejecución del programa. Una limitación de este enfoque es que no puede guardar los cambios en este archivo al ensamblado sin volver a compilar el programa. Por este motivo, sólo incluyen archivos que no cambian durante la vida útil de la aplicación como un recurso incrustado.


Demostración paso a paso

Para agregar recursos incrustados a su proyecto, debe agregar primero los archivos como parte de su proyecto. Después de agregar los archivos al proyecto, puede obtener acceso y mostrar los recursos mediante el espacio de nombres System.Reflection .


Agregar recursos incrustados

Para agregar un archivo de texto y un archivo de imagen al proyecto como recursos incrustados, siga estos pasos:
  1. Cree un nuevo proyecto de aplicación de Windows para esta demostración. Este formulario se utiliza para mostrar los recursos a los que se acceden desde el ensamblado que se ejecuta en tiempo de ejecución.
  2. Haga clic en el nombre del proyecto, haga clic en Agregary, a continuación, haga clic en Agregar nuevo elemento.
  3. En el cuadro de diálogo Nuevo elemento , seleccione Archivo de texto en el menú y nombre del archivo MyTextFile.txt. Cuando el archivo se abre en el entorno de desarrollo integrado (IDE), agregar texto y, a continuación, cierre el archivo.
  4. Repita los pasos 1 y 2 para agregar una imagen de mapa de bits al proyecto, pero en lugar de seleccionar el Archivo de texto como el nuevo tipo de elemento, seleccione Archivo de mapa de bitsy, a continuación, cambie el nombre del archivo a MyImage.bmp. Cuando la nueva imagen se abre en el IDE, dibujar algo en la imagen y, a continuación, cierre el archivo.
  5. Haga clic en el archivo de texto o el mapa de bits y, a continuación, seleccione Propiedades.
  6. En el cuadro de diálogo Propiedades , busque la propiedad Acción de generación . De forma predeterminada, esta propiedad se establece para el contenido. Haga clic en la propiedad y cambie la propiedad Acción de generación a Recurso incrustado.
  7. Repita los pasos 4 y 5 para el otro archivo.
La próxima vez que genere el proyecto, el compilador agrega estos archivos al ensamblado. El compilador agrega el espacio de nombres raíz del proyecto al nombre del recurso cuando se incluye en el proyecto. Por ejemplo, si el espacio de nombres raíz del proyecto es MyNamespace, los recursos se denominan MyNamespace.MyTextFile.txt y MyNamespace.MyImage.bmp.


Nota: los nombres de archivo de recursos distinguen mayúsculas de minúsculas. Cuando tiene acceso a los recursos, debe utilizar la ortografía exacta y el caso del nombre de archivo. Si no utiliza la misma ortografía y minúsculas del nombre de archivo, la llamada al método para tener acceso a la ManifestResourceStream devuelve Nothingy el sistema no provocan una excepción.


Nota: si desea comprobar los nombres de recursos, puede utilizar Microsoft Intermediate Language Disassembler (ILDASM) para ver los datos de manifiesto, que enumeran los recursos incluidos.


Acceso a los recursos

Para tener acceso a los recursos que se han incrustado en el manifiesto del ensamblado, importar el System.IO y los espacios de nombres System.Reflection , como sigue:
   using System.IO;   using System.Reflection;

El espacio de nombres System.IO proporciona la definición de una secuencia y el espacio de nombres System.Reflection define la clase de ensamblado que proporciona métodos para tener acceso a los recursos que están incrustados en el ensamblado.


Cuando se declara lo siguiente en el área de declaración general, se leen los recursos desde el ensamblado cuando se carga el formulario:
   Assembly _assembly;   Stream _imageStream;
StreamReader _textStreamReader;

Nota: para obtener acceso al evento de carga del formulario en el Editor de código, haga doble clic en el formulario en el Editor de diseño.


Para leer el recurso en el ensamblado que se está ejecutando el código actual, debe obtener una instancia de ese ensamblado. Para ello, utilice el método GetExecutingAssembly del ensamblado, como sigue:
   _assembly = Assembly.GetExecutingAssembly();
Leer la información de los recursos en una secuencia se realiza con una llamada de método a GetManifestResourceStream. El parámetro que se pasa a este método es el nombre del recurso que van a tener acceso. Los dos recursos, a continuación, se leen en sus secuencias correspondientes cuando se ejecuta el evento Load del formulario.

   _imageStream = _assembly.GetManifestResourceStream("MyNameSpace.MyImage.bmp");   _textStreamReader = new StreamReader(_assembly.GetManifestResourceStream("MyNameSpace.MyTextFile.txt"));

El código en el evento Load del formulario es similar a la siguiente:

   try   {
_assembly = Assembly.GetExecutingAssembly();
_imageStream = _assembly.GetManifestResourceStream("MyNamespace.MyImage.bmp");
_textStreamReader = new StreamReader(_assembly.GetManifestResourceStream("MyNamespace.MyTextFile.txt"));
}
catch
{
MessageBox.Show("Error accessing resources!");
}

La instrucción Try-Catch , conocida como control de errores estructurado en. NET, se utiliza para detectar los errores que se hayan producido mientras la instancia de la clase del ensamblado tiene acceso a los recursos.


Mostrar recursos

Este ejemplo utiliza dos botones para mostrar los recursos incrustados. Al hacer clic en el primer botón, una imagen de mapa de bits que se basa en el recurso que se lee desde el ensamblado y se muestra en el control PictureBox del formulario. El segundo botón lee de un recurso de texto y muestra el texto en un cuadro de texto.


Para mostrar los recursos incrustados, siga estos pasos:
  1. Agregue un control PictureBox al formulario.
  2. Agregar un nuevo control de botón al formulario y cambie su propiedad Text para Mostrar imagen.
  3. Haga doble clic en el botón para abrir su evento Click en el Visor de código y, a continuación, pegue el código siguiente en este evento:
       try   {
    pictureBox1.Image = new Bitmap(_imageStream); }
    catch
    {
    MessageBox.Show("Error creating image!");
    }

    Este código genera una nueva instancia de un mapa de bits que se basa en la secuencia de recursos que se leyó en el evento Load del formulario.

  4. Agregue un control TextBox al formulario.
  5. Agregue otro control Button al formulario y cambie su propiedad Text para Obtener el texto.
  6. Haga doble clic en el botón para abrir el Click_Event para el botón en el Editor de diseño y, a continuación, pegue el código siguiente en el evento:
       try   {
    if(_textStreamReader.Peek() != -1)
    {
    textBox1.Text = _textStreamReader.ReadLine();
    }
    }
    catch
    {
    MessageBox.Show("Error writing text!");
    }

    Este código determina si todavía existen caracteres que leer en la secuencia. Si se encuentran caracteres, se lee una línea al cuadro de texto.

  7. Presione F5 para ejecutar la aplicación.

Código completo

   using System;   using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

using System.IO;
using System.Reflection;

namespace MyNamespace
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;

public Form1()
{
//
// Required for Windows Form Designer support.
//
InitializeComponent();

//
// TODO: Add any constructor code after InitializeComponent call.
//
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.textBox1 = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// pictureBox1
//
this.pictureBox1.Location = new System.Drawing.Point(4, 8);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(284, 192);
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(92, 236);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(192, 20);
this.textBox1.TabIndex = 1;
this.textBox1.Text = "textBox1";
//
// button1
//
this.button1.Location = new System.Drawing.Point(8, 208);
this.button1.Name = "button1";
this.button1.TabIndex = 2;
this.button1.Text = "Show Image";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(8, 236);
this.button2.Name = "button2";
this.button2.TabIndex = 3;
this.button2.Text = "Get Text";
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.AddRange(new System.Windows.Forms.Control[]{
this.button2,
this.button1,
this.textBox1,
this.pictureBox1});

this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
#endregion

Assembly _assembly;
Stream _imageStream;
StreamReader _textStreamReader;

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}

private void Form1_Load(object sender, System.EventArgs e)
{
try
{
_assembly = Assembly.GetExecutingAssembly();
_imageStream = _assembly.GetManifestResourceStream("MyNamespace.MyImage.bmp");
_textStreamReader = new StreamReader(_assembly.GetManifestResourceStream("MyNamespace.MyTextFile.txt"));
}
catch
{
MessageBox.Show("Error accessing resources!");
}
}

private void button1_Click(object sender, System.EventArgs e)
{
try
{
pictureBox1.Image = new Bitmap(_imageStream);
}
catch
{
MessageBox.Show("Error creating image!");
}
}

private void button2_Click(object sender, System.EventArgs e)
{
try
{
if(_textStreamReader.Peek() != -1)
{
textBox1.Text = _textStreamReader.ReadLine();
}
}
catch
{
MessageBox.Show("Error writing text!");
}
}
}
}

Nota: El código debe cambiarse en Visual Studio 2005 o en Visual Studio 2008. Cuando crea un proyecto de formularios Windows Forms, Visual C# agrega un formulario al proyecto de forma predeterminada. Este formulario se denomina Form1. Los dos archivos que lo representan se denominan Form1.cs y Form1.designer.cs. Escriba el código en Form1.cs. El archivo Designer.cs es donde el Diseñador de Windows Forms escribe el código que implementa todas las acciones que realizó agregando controles. Para obtener más información acerca de cómo el Diseñador de Windows Forms en Visual C# 2005 o en Visual Studio 2008, visite el siguiente sitio Web de Microsoft:

Solución de problemas

Dado que los nombres de recursos distinguen mayúsculas de minúsculas, compruebe que está utilizando la ortografía correcta y el caso de los recursos que se tiene acceso. Se puede utilizar ILDASM para leer los datos para comprobar la ortografía exacta de los recursos de manifiesto.


Referencias

Para obtener más información, consulte los siguientes sitios Web de Microsoft Developer Network (MSDN):
Propiedades

Id. de artículo: 319292 - Última revisión: 17 ene. 2017 - Revisión: 1

Comentarios