Como atualizar um arquivo de resource via programação usando ResXResourceWriter e ResXFileRef


Vou mostrar como atualizar um arquivo de resource do projeto (.resx) utilizando programação.

Para exemplificar, utilizei um projeto Console, então primeiramente crie um projeto do tipo console.

001

1- Criando um arquivo de resource

Para criar um arquivo de resource no projeto clique com o botão direito do mouse no nome do projeto, escolha a opção “Add” e depois “New Item”.

002

Na janela que será exibida, escolha a opção “Resources Files” e clique no botão “Add”

003

O arquivo de resource será adicionado ao projeto e com duplo clique sobre ele, os dados armazenados no resource são exibidos. Note que os itens do arquivo de resource são organizados em grupos: Strings, Images, Icons, Audio, Files e Other.

004

2- Adicionando manualmente itens no arquivo de resource

Agora, vamos entender como funciona um arquivo de resource.

Crie uma pasta “embeded” e adicione arquivos de diferentes tipos, como a seguir:

005

Arraste os arquivos de imagens da pasta “embeded” para dentro do grupo “Images” do resource.

006

Arraste os arquivos de ícones da pasta “embeded” para dentro do grupo “Icons” do resource.

007

Arraste os demais arquivos da pasta “embeded” para dentro do grupo “Files” do resource.

008

No grupo “Strings” adicione um texto qualquer para teste

009

3- Como os itens são armazenados no arquivo de resource

Abrindo o arquivo do resource em modo texto (botão direito sobre o arquivo, opção “Open with” e clique em “XML (Text) Editor”) é possível visualizar como os itens são armazenados no arquivo de resource:

Uma string é armazenada assim:

<data name="texto" xml:space="preserve">  
	<value>bla bla bla</value>  
</data>

Um arquivo é armazenado no formato:

<data name="txt_teste" type="System.Resources.ResXFileRef, System.Windows.Forms">  
	<value>embeded\txt-teste.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>  
</data>

Uma imagem assim:

<data name="png_teste" type="System.Resources.ResXFileRef, System.Windows.Forms">  
	<value>embeded\png-teste.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>  
</data>

E um ícone assim:

<data name="ico_teste" type="System.Resources.ResXFileRef, System.Windows.Forms">  
	<value>embeded\ico-teste.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>  
</data>

Uma das opções para atualizar o arquivo de resource é abri-lo como se fosse um arquivo XML usando XML Document e adicionar essas referências, mas vamos ver como fazer isso utilizando os objetos da Framework .NET

4- Adicionando uma string ao arquivo de Resource

Primeiramente, faça o seguinte:

E utilize o seguinte código para adicionar um item de texto ao Resource:

string BASE_PATH = @"F:\Projetos\Testes\ResourceUpdate\ResourceUpdate";

FileInfo fileInfo = new FileInfo(Path.Combine(BASE_PATH, "Resource1.resx"));  
using (System.Resources.ResXResourceWriter resWriter = new ResXResourceWriter(fileInfo.FullName))  
{  
	resWriter.AddResource("texto", "texto teste 123");
	resWriter.Close();
}

Se você abrir o arquivo do Resource em modo texto novamente, verá que ele foi atualizado e contém a seguinte entrada:

<data name="texto" xml:space="preserve">  
	<value>texto teste 123</value>  
</data>

Note que os dados anteriores do arquivo de resource são perdidos. Se você precisar manter os dados anteriores, precisa usar “ResXResourceReader” para ler o arquivo atual e escrever no novo arquivo.

5- Adicionando um arquivo no formato binário

Uma das opções para incluir o conteúdo de um arquivo é adicionar o seu conteúdo binário, para isso, utilize o seguinte código:

//Diretório do projeto onde o arquivo Resource está  
string BASE_PATH = @"F:\Projetos\Testes\ResourceUpdate\ResourceUpdate";

FileInfo fileInfo = new FileInfo(Path.Combine(BASE_PATH, @"Resource1.resx"));  
using (System.Resources.ResXResourceWriter resWriter = new ResXResourceWriter(fileInfo.FullName))  
{

	//Inclui arquivo no formato binário

	FileInfo fileEmbeded = new FileInfo(Path.Combine(BASE_PATH, @"embeded\js-teste.js"));

	using (FileStream fileStreamContent = new FileStream(fileEmbeded.FullName, FileMode.Open, FileAccess.Read))  
	{  
		byte[] content = new byte[fileStreamContent.Length];  
		int numBytesToRead = (int)fileStreamContent.Length;  
		int numBytesRead = 0;  
		while (numBytesToRead > 0)  
		{  
			int n = fileStreamContent.Read(content, numBytesRead, numBytesToRead);

			if (n == 0)  
			break;

			numBytesRead += n;  
			numBytesToRead -= n;  
		}  
		numBytesToRead = content.Length;

		fileStreamContent.Close();  
		resWriter.AddResource("jsteste", content);  
	}

	//Fecha Resource Writer  
	resWriter.Close();  
}

6- Adicionando uma imagem

//Diretório do projeto onde o arquivo Resource está  
string BASE_PATH = @"F:\Projetos\Testes\ResourceUpdate\ResourceUpdate";

FileInfo fileInfo = new FileInfo(Path.Combine(BASE_PATH, @"Resource1.resx"));  
using (System.Resources.ResXResourceWriter resWriter = new ResXResourceWriter(fileInfo.FullName))  
{  
	//Inclui arquivo de imagem  
	System.Drawing.Image img = System.Drawing.Bitmap.FromFile(Path.Combine(BASE_PATH, @"embeded\jpg-teste.jpg"));  
	resWriter.AddResource("jpgteste", img);

	//Fecha Resource Writer  
	resWriter.Close();  
}

7- Adicionando um ícone

//Diretório do projeto onde o arquivo Resource está  
string BASE_PATH = @"F:\Projetos\Testes\ResourceUpdate\ResourceUpdate";

FileInfo fileInfo = new FileInfo(Path.Combine(BASE_PATH, @"Resource1.resx"));  
using (System.Resources.ResXResourceWriter resWriter = new ResXResourceWriter(fileInfo.FullName))  
{
	//Inclui arquivo de icone  
	System.Drawing.Icon ico = new System.Drawing.Icon(Path.Combine(BASE_PATH, @"embeded\ico-teste.ico"));  
	resWriter.AddResource("icoteste", ico);

	//Fecha Resource Writer  
	resWriter.Close();  
}

8- Adicionando arquivos

//Diretório do projeto onde o arquivo Resource está  
string BASE_PATH = @"F:\Projetos\Testes\ResourceUpdate\ResourceUpdate";

FileInfo fileInfo = new FileInfo(Path.Combine(BASE_PATH, @"Resource1.resx"));  
using (System.Resources.ResXResourceWriter resWriter = new ResXResourceWriter(fileInfo.FullName))  
{
	//Inclui arquivos  
	System.Resources.ResXFileRef resRef = new ResXFileRef(Path.Combine(BASE_PATH, @"embeded\html-teste.html"), typeof(System.String).FullName);  
	resWriter.AddResource("htmlteste", resRef);

	//Fecha Resource Writer  
	resWriter.Close();  
}

Comentários