7
votes

Intégrer par programme des ressources dans un assemblage .NET

J'ai un assemblage compilé .NET avec un fichier de ressource spécifique incorporé (nommé 'script.xml'). J'ai besoin de le changer de manière programmatique pour un autre.

est-ce possible à faire sans recompilation de la source? P>

Actuellement, je fais une recherche de texte que je connais est dans le fichier et cela fonctionne bien. Mais je dois le faire pour un autre projet où je ne connais aucun des contenus du fichier de ressources et je dois trouver une autre méthode. P>

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();


0 commentaires

4 Réponses :


4
votes

Votre mécanisme actuel est très fragile - il ne fonctionnera pas pour les assemblys signés (car le hachage changera) ou si vous devez remplacer une ressource avec une ressource plus grande (car toutes les autres compensations peuvent bouger). Il a également des problèmes en termes de codages de caractères et du mécanisme général pour trouver le bon point dans le dossier de toute façon, mais ceux-ci sont relativement sans importance que je ne pense pas que l'approche soit appropriée pour commencer.

Si vous avez besoin de ressources remplaçables, je les mettit dans un fichier différent totalement, qui n'a pas le format relativement délicat d'un assemblage.


3 commentaires

Le fichier de ressources peut devenir plus grand et fonctionne toujours car il peut être rembourré avec des espaces (jusqu'à une taille maximale: 'scriptfilesize'). Et malheureusement, il doit être contenu dans un seul fichier pour ce projet.


@Nick: Cela dit efficacement qu'il ne peut pas être plus grand que la ressource existante, car la ressource existante sera toujours scriptfilesize. Je voudrais vraiment essayer de redéfinir cela. Si vous devez absolument le faire, utilisez une bibliothèque qui connaît le format de fichier d'assemblage (comme Cecil - Mono- Project.com/cecil ) mais essayez d'éviter de le faire si possible.


@Jon: True, j'ai oublié de mentionner que l'assemblage est initialement compilé avec une tonne de rembourrage déjà là pour correspondre à la création de Constfilesize. Je donne beaucoup d'espace et je ne l'ai jamais manqué et cela fonctionne actuellement sur des centaines d'ordinateurs avec succès. Mais je veux vraiment, vraiment envie de la repenser, c'est pourquoi je pose ici.



1
votes

Vous recherchez probablement System.Runtime.emit pour compiler dynamiquement un assemblage.


0 commentaires

1
votes

Vous pouvez créer de manière dynamique des assemblages à l'aide de la réflexion, en particulier la classe AssemblyBuilder , et inclure des ressources dans votre assemblage bâti de manière dynamique. Je ne suis pas sûr qu'il soit possible de démonter un assemblage existant à l'aide de la réflexion (bien que maintenant je suis intéressé).

Je voudrais aboyer un autre arbre si possible.


0 commentaires

4
votes

Vous pouvez utiliser Cecil pour ouvrir l'assemblage et insérer une ressource (je le fais). Ymmv


3 commentaires

Il ne casse pas les PDBS si vous utilisez Cecil pour lire et régénérer correctement les PDB.


Je devinais que c'était le cas, mais il y a 1,5 ans, je ne pouvais pas comprendre comment le faire. Avez-vous un exemple?


Il travaillait déjà à l'époque. Mais de nos jours, avec les nouvelles aptitupes, vous l'avez indiqué ici: Github.com/jbevain / Cecil / Wiki / Symboles de débogage