Laden...

Assembly unload

Erstellt von a957m vor 13 Jahren Letzter Beitrag vor 12 Jahren 2.648 Views
A
a957m Themenstarter:in
254 Beiträge seit 2007
vor 13 Jahren
Assembly unload

Hallo Kollegen,

bin gerade dabei einen Updater für eine Applikation zuschreiben (hab nichts gefunden, dass in das Umfeld passt). Dabei kopiert ein System Dienst dll's von einem Share und soll die enthaltenen Assemblies dann dynamisch laden. Das hat auch alles funktioniert. Der System-Dienst sollte diese Assemblies bloss auch wieder entladen, damit ggf. wieder eine neue dll kopiert werden kann.

Dies scheint aber nicht ohne weiteres zu gehen, hab hier im Forum recherchiert, dass ich die Assemblies in eine separate AppDomain laden muss und an dieser Stelle hänge ich jetzt schon seit Stunden (und versuche den umfangreichen Posts die Lösung für meinen Fall zu entlocken.)

Meine Anforderung:

* Assembly laden
* Methode ausführen
* Assembly entladen

Anbei mein jetziger Stand für jeden Tipp bin ich dankbar.

  try
            {
               AppDomainSetupsetup = new AppDomainSetup();
                setup.ApplicationBase = System.Environment.CurrentDirectory;
                setup.PrivateBinPath = System.Environment.CurrentDirectory;

                Evidence e = AppDomain.CurrentDomain.Evidence;
                AppDomain otherDomain = AppDomain.CreateDomain("otherDomain",e,setup);
                otherDomain.TypeResolve +=newResolveEventHandler(otherDomain_TypeResolve);

                object dd = otherDomain.CreateInstanceAndUnwrap("UpdLib.dll", "UpdTool.UpdLib");

Danach fliegt eine Exception mit der Message:
"Die Datei oder Assembly ... oder eine abhängige unde nicht gefunden. Der angegebene Assembly Name oder CodeBasis ist ungültig. HRESULT 0X0131047."

Der EventHandler wird nicht angesprungen.

Danke und Sorry für den vielen Text.

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo,

häng Dich doch mal ans AppDomain.AssemblyResolve-Ereignis, vermutlich kann er schon die Assembly nicht laden und kommt daher gar nicht bis zum TypeResolve.

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

A
a957m Themenstarter:in
254 Beiträge seit 2007
vor 13 Jahren

Hi Kollegen,

hab erst mal eine Version hinbekommen. Ich hoffe jetzt nur, dass der Unload auch wirklich funktioniert.

using System;
using System.Collections.Generic;
using System.Text;

using NLog;

using System.Reflection;
using System.Security.Policy;

namespace DAI.UpdService
{
    public interface IUpdModul
    {
        bool Start();
    }

    public class ModulStarter : IDisposable
    {
        private static readonly Logger log =
           LogManager.GetCurrentClassLogger();

         IUpdModul m_modul = null;
         AppDomain m_extDom = null;
         object m_extObj = null;

        public ModulStarter(string _dll)
        {
            try
            {
                m_extDom = AppDomain.CreateDomain("otherDomain");
                AssemblyName extName = new AssemblyName();
                string cb = "file://" + _dll;
                extName.CodeBase = cb;
                Assembly extDll = m_extDom.Load(extName);
                Type extType = extDll.GetExportedTypes()[0];
                m_extObj = m_extDom.CreateInstanceAndUnwrap(extDll.FullName, extType.FullName);

                foreach (Type t in extDll.GetTypes())
                {
                    if (t.IsClass && t.IsPublic && (t.GetInterface(typeof(IUpdModul).FullName) != null))
                    {
                        m_modul = (IUpdModul)Activator.CreateInstance(t);
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                log.Error("Modul: " + _dll + " kann nicht geladen werden! "+ex.Message);
                throw new Exception("Modul: " + _dll + " kann nicht geladen werden! " + ex.Message);
            }
        }

        public bool Start()
        {
            //UpdLib ausführen
            try
            {
                m_modul.Start();

            }
            catch (Exception ex)
            {
                log.Error("Fehler bei Ausführung Update Modul" + ex.Message);
                return false;
            }

            return true;
        }

        public void Dispose()
        {
            m_modul = null;
            m_extObj = null;

            AppDomain.Unload(m_extDom);
        }
    }
}

Bis denne!

A
a957m Themenstarter:in
254 Beiträge seit 2007
vor 13 Jahren

Na so ein Mist, der ganze Aufwand für nix.

Wie ich vermutet habe, kann ich die dll nicht überschreiben, weil sie noch geöffnet ist.

Hat jemand ein Tipp, was da schief gelaufe sein kann ?

436 Beiträge seit 2007
vor 12 Jahren

hi,

wenn der unload nicht sauber "entlädt" kann das an deiner assembly liegen!
hast du irgendwelche referenzen in deiner assembly?

ps: du entwickelst nicht zufällig für daimler?

502 Beiträge seit 2004
vor 12 Jahren

Ich weiß nicht, ob's Dir was bringt, aber ich für ein ähnliches Szenario mal folgendes erfolgreich angewandt:

  • Assembly via Filestream in einen MemoryStream kopieren.
  • Filestream schließen
  • Assembly aus dem MemoryStream laden

Damit blockst Du das File nicht...

Bart Simpson

Praxis ist wenn alles funktioniert und keiner weiss warum.
Theorie ist wenn man alles weiss, aber nichts funktioniert.

Bei uns wird Theorie und Praxis vereint: Nichts funktioniert und keiner weiss warum...