typeparam see remarks example cref c# resources .net-assembly

see - summary example c#



Use C#exe para modificar recursos de un C#exe diferente (1)

En función de sus suposiciones, puede actualizar / agregar recursos de su ejecutable utilizando la biblioteca Mono.Cecil

Aquí hay tres métodos esenciales para la manipulación de recursos usando Mono.Cecil:

public static void ReplaceResource(string path, string resourceName, byte[] resource) { var definition = AssemblyDefinition.ReadAssembly(path); for (var i = 0; i < definition.MainModule.Resources.Count; i++) if (definition.MainModule.Resources[i].Name == resourceName) { definition.MainModule.Resources.RemoveAt(i); break; } var er = new EmbeddedResource(resourceName, ManifestResourceAttributes.Public, resource); definition.MainModule.Resources.Add(er); definition.Write(path); } public static void AddResource(string path, string resourceName, byte[] resource) { var definition = AssemblyDefinition.ReadAssembly(path); var er = new EmbeddedResource(resourceName, ManifestResourceAttributes.Public, resource); definition.MainModule.Resources.Add(er); definition.Write(path); } public static MemoryStream GetResource(string path, string resourceName) { var definition = AssemblyDefinition.ReadAssembly(path); foreach (var resource in definition.MainModule.Resources) if (resource.Name == resourceName) { var embeddedResource =(EmbeddedResource) resource; var stream = embeddedResource.GetResourceStream(); var bytes = new byte[stream.Length]; stream.Read(bytes, 0, bytes.Length); var memStream = new MemoryStream(); memStream.Write(bytes,0,bytes.Length); memStream.Position = 0; return memStream; } return null; }

Puede usar el método GetResource para recuperar el flujo de recursos actual (Writable),

utilizando las clases ResourceWriter , ResourceReader o ResourceEditor puede leer / escribir o modificar el recurso actual o crear un nuevo recurso, y luego simplemente ponerlo de nuevo en el ejecutable llamando a ReplaceResource o agregarlo como uno nuevo llamando a AddResource

Aquí hay un ejemplo de cómo reemplazar una imagen en un recurso (creando un nuevo recurso desde cero):

var ms = new MemoryStream(); var writer = new ResourceWriter(ms); writer.AddResource("good_luck",new Bitmap("good_luck.png")); writer.Generate(); ReplaceResource(@"my executale.exe", "ResourceTest.Properties.Resources.resources",ms.ToArray());

puede obtener Cecil a través de PM> Install-Package Mono.Cecil nuget.

Resuelto Vea abajo.

Tengo 2 aplicaciones de C #. La aplicación a se supone que modifica los recursos internos de la aplicación b. Se supone que la aplicación b hace algo con sus recursos (modificados) cuando se ejecuta.

¿Cómo puedo lograr eso?

Esto es lo que intenté:

public static void addFileToResources(string dest, string src) { Assembly a_dest = Assembly.LoadFile(dest); using (Stream s_dest = a_dest.GetManifestResourceStream("Elevator.Properties.Resources.resources")) { using (ResourceWriter rw = new ResourceWriter(s_dest)) { byte[] b_src = File.ReadAllBytes(src); rw.AddResource("target", b_src); } } }

Obtengo una System.ArgumentException con The stream is readonly. en System.Resources.ResourceWriter..ctor(Stream stream)

EDITAR
Dado que eso no parece ser posible con los recursos de .net: ¿Hay alguna otra manera?
Quiero producir un solo archivo (es decir, el exe de la aplicación b ) que sea ejecutable y pueda trabajar con los datos (almacenados en el exe) que se proporcionan antes de la ejecución desde la aplicación a . Preferiblemente sin tener que compilar realmente b para darle los datos.

Supuestos para que sea un poco más fácil:

  • a siempre se ejecuta antes de b
  • a solo se ejecuta una vez
  • ambas aplicaciones están escritas por mí

Editar - Sollución
Como no es posible lograr eso a través de los recursos, utilicé la siguiente solución alternativa:
Aparentemente puedes agregar CUALQUIER COSA a un archivo exe y aún será ejecutable, así que esto es lo que se me ocurrió:

public class Packer : IDisposable { // chosen quite arbitrarily; can be anything you''d like but should be reasonably unique private static byte[] MAGIC_NUMBER = { 0x44, 0x61, 0x6c, 0x65, 0x6b, 0x4c, 0x75, 0x63 }; private Stream inStream; public Packer(string filename, bool openReadonly = false) { // The FileAccess.Read is necessary when I whant to read from the file that is being executed. // Hint: To get the path for the executing file I used: // System.Reflection.Assembly.GetExecutingAssembly().Location inStream = File.Open(filename, FileMode.Open, openReadonly ? FileAccess.Read : FileAccess.ReadWrite, openReadonly ? FileShare.Read : FileShare.None); } public byte[] ReadData(int index) { byte[] mn_buf = new byte[MAGIC_NUMBER.Length]; byte[] len_buf = new byte[sizeof(Int32)]; int data_len = 0; inStream.Seek(0, SeekOrigin.End); for (int i = 0; i <= index; ++i) { // Read the last few bytes inStream.Seek(-MAGIC_NUMBER.Length, SeekOrigin.Current); inStream.Read(mn_buf, 0, MAGIC_NUMBER.Length); inStream.Seek(-MAGIC_NUMBER.Length, SeekOrigin.Current); for (int j = 0; j < MAGIC_NUMBER.Length; ++j) { // Check if the last bytes are equals to my MAGIC_NUMBER if (mn_buf[j] != MAGIC_NUMBER[j]) { throw new IndexOutOfRangeException("Not enough data."); } } inStream.Seek(-sizeof(Int32), SeekOrigin.Current); inStream.Read(len_buf, 0, sizeof(Int32)); inStream.Seek(-sizeof(Int32), SeekOrigin.Current); // Read the length of the data data_len = BitConverter.ToInt32(len_buf, 0); inStream.Seek(-data_len, SeekOrigin.Current); } byte[] data = new byte[data_len]; // Read the actual data and return it inStream.Read(data, 0, data_len); return data; } public void AddData(byte[] data) { // append it inStream.Seek(0, SeekOrigin.End); inStream.Write(data, 0, data. inStream.Write(BitConverter.GetBytes(data.Length), 0, sizeof(Int32)); inStream.Write(MAGIC_NUMBER, 0, MAGIC_NUMBER.Length); } public void Dispose() { inStream.Dispose(); } }

Si desea utilizar este fragmento, siga adelante, pero tenga en cuenta que si agrega datos a un archivo, los índices están en orden inverso al recuperarlos:
Digamos que usted escribe el conjunto de datos A primero y luego el conjunto de datos B, si lee los datos más tarde B tendrá el índice 0 y A el índice 1.