2009-07-10 12 views
7

Tengo un ensamblado .NET compilado con un archivo de recursos específico incrustado (denominado 'Script.xml'). Necesito cambiarlo programáticamente por otro.Incorporar recursos de forma programada en un ensamblado .NET

¿Esto es posible sin recompilar desde la fuente?

Actualmente, hago una búsqueda de texto que sé que está en el archivo y funciona bien. Pero necesito hacerlo para otro proyecto en el que no conozco ninguno de los contenidos del archivo de recursos y necesito encontrar otro método.

FileStream exe = new FileStream(currentexe, FileMode.Open); 

//find xml part of exefile 
string find = "<?xml version=\"1.0\"?>"; 
string lastchars = new string(' ', find.Length); 
while (exe.CanRead) { 
    lastchars = lastchars.Substring(1) + (char)exe.ReadByte(); 
    if (lastchars == find) { 
     exe.Seek(-find.Length, SeekOrigin.Current); 
     break; 
    } 
} 

//output serialized script 
int bytenum = 0; 
foreach (byte c in xml) { 
    if (c == 0) break; 
    exe.WriteByte(c); 
    bytenum++; 
} 

//clean out extra data 
while (bytenum++ < ScriptFileSize) { 
    exe.WriteByte(0x20); 
} 
exe.Close(); 

Respuesta

4

Puede usar Cecil para abrir el conjunto e insertar un recurso (I do). YMMV

+1

No rompe los PDB si usa Cecil para leer y regenerar correctamente los PDB. –

+0

Estaba adivinando que este sería el caso, pero hace 1.5 años no pude encontrar la manera de hacerlo. ¿Tienes un ejemplo? –

+0

Ya estaba funcionando en ese entonces. Pero hoy en día con las nuevas API lo haría como se indica aquí: https://github.com/jbevain/cecil/wiki/Debug-symbols –

4

Su mecanismo actual es muy frágil - no va a funcionar para conjuntos firmados (como el hash va a cambiar) o si necesita reemplazar un recurso con una más grande (como todos los demás compensaciones pueden mover) . También tiene problemas en términos de codificación de caracteres y el mecanismo general para encontrar el punto correcto en el archivo de todos modos, pero estos son relativamente importantes dado que no creo que el enfoque sea apropiado para empezar.

Si necesita recursos reemplazables, los colocaría en un archivo diferente por completo, que no tiene el formato relativamente delicado de un ensamblaje.

+0

El archivo de recursos puede agrandarse y todavía funciona porque se puede rellenar con espacios (hasta un tamaño máximo: 'ScriptFileSize'). Y desafortunadamente necesita estar contenido en un solo archivo para este proyecto. –

+0

@Nick: eso efectivamente dice que no puede ser más grande que el recurso existente, porque el recurso existente siempre será ScriptFileSize. Realmente, realmente trataría de rediseñar esto. Si tiene que hacerlo, use una biblioteca que conozca el formato del archivo de ensamblaje (como Cecil - http://www.mono-project.com/Cecil) pero intente evitar hacerlo si es posible. –

+0

@Jon: Cierto, olvidé mencionar que el ensamblaje se compiló originalmente con una tonelada de relleno que ya existe para coincidir con la const ScriptFileSize. Doy mucho espacio y nunca me he quedado sin él, y esto actualmente se está ejecutando en cientos de computadoras con éxito. Pero realmente, realmente quiero rediseñarlo y es por eso que estoy publicando aquí. –

1

Probablemente esté buscando System.Runtime.Emit para compilar dinámicamente un ensamblaje.

1

Puede construir ensamblajes dinámicamente usando reflexión, específicamente la clase AssemblyBuilder, e incluir recursos en su ensamblado construido dinámicamente. No estoy seguro de que sea posible desmontar un ensamblaje existente mediante reflexión (aunque ahora estoy interesado).

Ladraría otro árbol si fuera posible.

Cuestiones relacionadas