Assemblée ne peut pas trouver assemblage référencé lorsqu'il est compilé à la mémoire avec CodeDomProvider

StackOverflow https://stackoverflow.com/questions/6804147

Question

Je suis en train de compiler un code à la mémoire lors de l'exécution en utilisant un CodeDomProvider.

Le code que je suis un établissement des données ont référence à un ensemble externe que j'inclus dans les paramètres utilisés lors de la compilation du code.

Quand je compile à la mémoire et essayer de la réflexion sur l'utilisation de l'ensemble généré dans un Visual Studio Add-In, il lance une exception en disant qu'il ne peut pas trouver l'assembly référencé.

(Exception)
« Impossible de charger un ou plusieurs des types demandés. Récupérer la propriété LoaderExceptions pour plus d'informations. »

(LoaderException)
"{" Impossible de charger le fichier ou l'assembly 'Dynamo.Jiss.Task, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null' ou une de ses dépendances. Le système ne peut pas trouver le fichier spécifié. ":" Dynamo.Jiss.Task, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null "}"

J'ai essayé référence à l'Assemblée de différents endroits en utilisant le chemin absolu.

Le code exact fonctionne très bien même si elle est exécutée à partir d'une application de la console, et il fonctionne aussi bien dans l'Add-In si je ne compilent pas la mémoire.
Retrait de la référence à l'assemblage externe et le code qui y font référence fonctionne aussi lors de la compilation à la mémoire, il probablement l'exception décrit un problème avec le chargement de l'ensemble référencé.

Do quelqu'un a une idée pourquoi la compilation à la mémoire et un référencement dans un travail de l'Assemblée isnt Add-In?

Y at-il des restrictions dans l'AppDomain il est en cours d'exécution ou quelque chose que je devrais être au courant? (Ma meilleure estimation actuellement)

Faut-il être dans un dossier spécifique? référencé en utilisant un chemin relatif? les paramètres de sécurité? doit être signé? des idées?


Qu'est-ce que je suis en train de réaliser est un moyen de mettre les fichiers avec une extension spécifique dans un projet et laisser le Addin compiler automatiquement et si elle implémente une interface ITask (de l'ensemble externe), il appellera une méthode de configuration () qui permet le code de crochet dans les événements Visual studio et exécuter des tâches / scripts tout en écoutant les différents événements. De cette façon, je peux facilement exécuter des modèles de texte si un autre fichier est modifié, ou de combiner des fichiers sur différents événements Réduire Liste (document sauvegardé, etc construire.).

Est-ce que quelque chose comme cela existe déjà (pour me soulager de la douleur)? :)

Était-ce utile?

La solution

Ceci est le plus probable se passe parce que nous disons CodeDom pour générer un assemblage en mémoire (qui est vraiment un mensonge car il est la génération temporairement sur le disque, le charger, puis la suppression du fichier). Le point est, le répertoire de compilation pour l'assemblage CodeDom n'est pas le même que celui que vous utilisez pour compiler. Autrement dit, si vous utilisez dans bin \ Debug, l'ensemble CodeDom est généré à% temp%.

Vous pourriez résoudre ce dans l'une des deux façons je peux penser:

  1. Compile l'ensemble CodeDom au même chemin que votre exécution assemblage.

    myCodeProvider.GenerateInMemory = false; // may not be necessary...haven't tried this in a while
    myCodeProvider.OutputAssembly = string.Format(@"{0}\{1}", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location, "mydll.dll");
    
  2. Gérer l'événement de AssemblyResolve et de fournir l'ensemble CodeDom l'ensemble référencé il est demandé.

    AppDomain.CurrentDomain.AssemblyResolve += OnCurrentDomainAssemblyResolve
    
    private static Assembly OnCurrentDomainAssemblyResolve(object sender, ResolveEventArgs args)
    {
                    // this is absurdly expensive...don't do this more than once, or load the assembly file in a more efficient way
                    // also, if the code you're using to compile the CodeDom assembly doesn't/hasn't used the referenced assembly yet, this won't work
                    // and you should use Assembly.Load(...)
                    foreach (Assembly @assembly in AppDomain.CurrentDomain.GetAssemblies())
                    {
                        if (@assembly.FullName.Equals(args.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            return @assembly;
                        }
                    }
    }
    
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top