Announcement

Collapse
No announcement yet.

Shadow Copying

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Shadow Copying

    hi,

    I'm using a DotNet Application which uses several dlls.
    Every time I create a new version and want to distribute it to the users, I have to remind the users to leave the application.

    So I heard about shadow copying,
    so that it might be possible to update certain dlls while the users are able to work and do not have to leave the application.

    is there any coding example where your whole discription is coded ?

    in my testclass I alwaxs get the message: file is used by other persons, could not be changed ...
    it seems that the shadow copying mechanisms do not work regularly.

    It would be very nice, if you could tell me, when to upload the assembly.
    Do I have to upload the original assembly, how can I do this ?

    Imports System.IO
    Imports System.Reflection


    Public Class Form1

    Public Watcher As FileSystemWatcher
    Private _DomainNumber As String = 1
    Private _currentAssembly As System.Reflection.Assembly




    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Try
    LoadAppDomain()

    InitWatcher()

    Console.ReadLine()

    Catch ex As Exception
    MessageBox.Show(ex.Message)
    End Try
    End Sub


    Private Sub InitWatcher()
    Try
    Watcher = New System.IO.FileSystemWatcher()
    ' Monitoring-Pfad
    Watcher.Path = "C:\Projekte\TestProjekte\ShadowCopying\ShadowCopy ing\bin\Debug\"
    Watcher.Filter = "*.dll"
    Watcher.IncludeSubdirectories = True
    Watcher.EnableRaisingEvents = True
    AddHandler Watcher.Changed, AddressOf OnAssemblyChange

    Catch ex As Exception
    MessageBox.Show(ex.Message)
    End Try
    End Sub


    Private Sub LoadAppDomain()
    Try
    'Dim setup As New AppDomainSetup()
    'setup.ApplicationBase = "Testdll\TB_DAL"
    'setup.ShadowCopyDirectories = "C:\Temp;C:\Downloads"
    'setup.ShadowCopyFiles = "true"

    ' Where do shadow copied bits go?
    'AppDomainSetup.CachePath + AppDomainSetup.ApplicationName control where shadow copied bits go. If both CachePath and ApplicationName are set, shadow copied bits will go to CachePath\ApplicationName. Otherwise shadow copied bits will go to your download cache (which is stored in %userprofile%\local settings\application data\assembly). The combination of CachePath and ApplicationName is really handy for ASP.NET, because they can set a common CachePath, and have each application shadow copy to a different location.
    'You are responsible to clean up the shadow copy cache if you set CachePath+ApplicationName. In the case of download cache as shadow copy cache, it is automatically managed by fusion.


    Dim domain As AppDomain = AppDomain.CreateDomain("ShadowCopy domain " + _DomainNumber, Nothing, Nothing, Nothing, True)
    _currentAssembly = domain.Load("TB_DAL", Nothing)

    _DomainNumber = _DomainNumber + 1


    AppDomain.Unload(domain)

    Catch ex As Exception
    MessageBox.Show(ex.Message)
    End Try
    End Sub


    Sub OnAssemblyChange(ByVal From As Object, ByVal e As FileSystemEventArgs)
    ' Zweck: Reagiert auf dll-Änderungen im Monitoring-Verzeichnis des Watchers und ruft "LoadAppDomain()" auf
    Try
    LoadAppDomain()


    Catch ex As Exception
    MessageBox.Show(ex.Message)
    End Try
    End Sub


    End Class

  • #2
    Hvorfor skriver du paa engelsk?
    Christian

    Comment


    • #3
      Hallo,

      um eine Anwendung per Show-Copy laufen zu lassen (wie in ASP.net) muss die Anwendung von einem Bootstrapper geladen werden. Der Code für den Bootstrapper ist nachfolgend (in C#-Ausführung).

      [highlight=c#]
      using System;
      using System.IO;

      namespace ShadowCopy
      {
      class Program
      {
      [LoaderOptimization(LoaderOptimization.MultiDomainH ost)]
      static void Main(string[] args)
      {
      // Shadow-Copying ermöglichen:
      string cachePath = Path.Combine(
      Environment.CurrentDirectory,
      "__cache");
      string configFile = Path.Combine(
      Environment.CurrentDirectory,
      "Anwendung.exe.config");

      AppDomainSetup setup = new AppDomainSetup();
      setup.ApplicationName = "Anwendung";
      setup.ShadowCopyFiles = "true";
      setup.CachePath = cachePath;
      setup.ConfigurationFile = configFile;

      AppDomain domain = AppDomain.CreateDomain(
      "Beispiel",
      AppDomain.CurrentDomain.Evidence,
      setup);

      // Anwendung starten:
      domain.ExecuteAssembly("Anwendung.exe");

      // Cache bereinigen:
      AppDomain.Unload(domain);
      Directory.Delete(cachePath, true);
      }
      }
      }
      [/highlight]

      Die Aufgabe darin ist eine neue Application-Domain zu erstellen in der Shadow-Copying ermöglicht ist. In dieser Domain läuft dann deine Anwendung. Somit ist es möglich die "originalen" EXE und DLLs während der Programmausführung zu löschen/updaten -> Möglichkeit für Autoupdate.

      Hoffe es hilft.

      mfG Gü

      PS: Ich habe gelernt wir sind ein DEUTSCHES Forum, darum bitte auf deutsch posten da nicht alle Englisch können.
      "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

      Comment


      • #4
        Vielen Dank für die Hilfe jedoch noch folgende Fragen bleiben mir offen:

        1) Ist es überhaupt grundsätzlich sinnvoll, eine Architektur zu erreichen, bei der man die dlls im laufenden Betrieb austauschen kann ? Geht das so einfach oder muss man davor nicht imemr das komplette Projekt neu kompilieren ? es kann doch nicht so einfach sein, dass man die dlls einfach austauscht ? oder geht das dann nur, falls sich in der dll selbst etwas ändert aber an den Schnittstellen nach aussen nichts ???

        2) Das ShadowCopyladen der Assemblies:
        macht man das normalerweise für die dlls, auf die man in den Referenzen verweist ?

        3) Mit Bootstrapper und ShadowCopy.
        Bitte nochmals ganz langsam:
        Also ich habe ein projekt Bootstrapper, und ein weiteres projekt Anwendung(Anwendung.exe), das eine bestimmte dll (AnwendungTESTDLL.dll) benutzt.
        In welchen projektordern auf dem File-System muss ich jetzt welche dlls vorhalten ?
        das ist mir nicht ganz klar ....

        in das projekt Anwendung: muss in den bin ordner dort die AnwendungTESTDLL.dll als File reinkopiert werden ?

        im projekt bootstrapper: muss dort in den bin ordner die Anwendung.exe + die AnwendungTESTDLL.dll reinkopiert werden ?


        4) ich habe geselen, es gitb auch die möglichkeit "Shadwo Copying zu umgehen", indem man die dlls in byte arrays entlädt .. dann kann man sie ändern und löschen. ist das eine sinnvolle alternative ?

        Comment


        • #5
          Hallo Schorschi,

          hab ein Beispielprojekt - ist für den Anhang leider zu groß, kanns dir per Email schicken.

          Zu deinen Fragen:
          1. Ob sinnvoll oder nicht muss für das jeweilige Projekt entschieden werden. In ASP.net basiert das automatisch und macht sinn. Ich verwende es in einigen Projekte um eine Auto-Update zu ermöglichen.

            DLLs können ausgetauscht werden solange die Schnittstellen gleich bleiben. Ansonsten muss der DLL-Hostprozess bzw. dessen Anwendung auch getauscht werden.
          2. Beim Shadow-Copy laden werden (wie in meinem Bsp) alle Assemblies - außer jene des GAC - ins Shadow-Copy Verzeichnis kopiert.


          Die restlichen Punkte sind in dem Beispielprojekt zu sehen (Email?).

          Ich halte es für umständlicher die DLLs in byte[] zu entladen da Shadow-Copying leicht zu implementieren ist.

          mfG Gü
          "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

          Comment

          Working...
          X