Announcement

Collapse
No announcement yet.

ClickOnce Update via FTP

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

  • #16
    Hi,

    wenn der Loader im gleichen Verzeichnis wie die Anwendung ist braucht kein Pfad übergeben werden.

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

    Comment


    • #17
      wenn der Loader im gleichen Verzeichnis wie die Anwendung ist braucht kein Pfad übergeben werden.
      Das ist ein gutes Argument

      mfg Uffze

      Comment


      • #18
        @gfoidl

        Ich bin gerade dabei, Deinen Loader für meine Applikation anzupassen. Bei meinem Project erscheint jedoch immer das unötige Konsolen-Fenster (auch bei Auswahl des "Empty Project"-Templates).
        Bei Deinem Projekt klappt das ohne Konsole.

        Hast Du einen Tip, wie ich die wegbekomme bzw. gibt es ein bestimmtes Project-Template, dass man für den Loader verwenden soll?

        mfg,
        Uffze

        P.S. Abgesehen von der Konsole funktioniert das Ganze schon wie's soll: nachdem der Loader die Applikation gestartet hat, kann man die .exe löschen.

        Comment


        • #19
          Hi,

          der Loader ist wie ein Konsolenprogramm erstellt worden und danach in den Projekteigenschaften der Typ auf WinForm umgestellt worden.

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

          Comment


          • #20
            Hallo,

            es klappt! Besten Dank!

            mfg,
            Uffze

            Comment


            • #21
              Hallo,

              ich habe da noch ein Problem. Ist eigentlich eine eigene Sache für sich, hat aber unmittelbar mit den AppDomains zu tun:
              Ich würde gern die AssemblyFileVersion der alten und der neuen .Exe auslesen, damit der Benutzer weiss, ob beim Update über FTP eine neuere Version auf den PC kopiert wurde.

              Das Problem ist, dass nach dem Load der Assembly die entsprechende .exe-Datei gesperrt ist und nicht mit der neuen Version ersetzt werden kann. Auf das Problem bin ich schon unzählige Male im Internet gestossen - jedoch auf keine Lösung, die bei mir funktioniert.

              Ich habe eine Methode geschrieben, die eine Assembly in eine neue Domäne lädt (zumindest ist das mein Vorhaben) und diese anschließend entlädt. Die Methode sollte letztendlich die AssemblyFileVersion als string zurückgeben. Nach Ausführen der Methode sollte die Datei überschrieben werden. Sie ist aber danach noch immer gesperrt.

              Alle Files befinden sich im selben Verzeichnis.

              Hat jemand eine Idee ob sich das überhaupt auf diese Weise oder ähnliche realisieren lässt?

              Testroutine:
              [highlight=c#] public string GetAssemblyFileVersion (string fileName)
              {

              string appName = Path.GetFileName(fileName);

              string startupPath = Path.GetDirectoryName(
              Assembly.GetExecutingAssembly().Location);

              string cachePath = Path.Combine(
              startupPath,
              "__cache");
              string configFile = Path.Combine(
              startupPath,
              (appName + ".config"));
              string assembly = Path.Combine(
              startupPath,
              appName);

              // Create the setup for the new domain:
              AppDomainSetup setup = new AppDomainSetup();
              setup.ApplicationName = appName;
              setup.ShadowCopyFiles = "true"; // note: it isn't a bool
              setup.CachePath = cachePath;
              setup.ConfigurationFile = configFile;

              // Create the application domain. The evidence of this
              // running assembly is used for the new domain:
              AppDomain domain = AppDomain.CreateDomain(
              appName,
              AppDomain.CurrentDomain.Evidence,
              setup);

              // Start MyApplication by executing the assembly:
              string assemblyFileVersion;

              try {
              Assembly asm = domain.Load( AssemblyName.GetAssemblyName(appName));

              assemblyFileVersion="looks good";
              }
              catch {
              assemblyFileVersion="looks bad";
              }
              finally {

              // After the MyApplication has finished clean up:
              AppDomain.Unload(domain);
              Directory.Delete(cachePath, true);
              }
              return( assemblyFileVersion);
              }
              }[/highlight]

              Danach sollte das File gelöscht werden. Aber bei File.Delete: --> Bazong! FileIOException und Schimpfe.
              Wenn jemand eine Idee hat, wie man dem Problem beikommt, bitte ich darum.

              Gruß,
              Uffze

              Comment


              • #22
                Ich habe in einem ähnlichen Fall wo ich eine Assembly laden musste ohne die dll auf der Platte zu sperren die Assembly aus dem Speicher instanziert. Heißt ich habe die Assembly ganz normal als File geladen in einem Memorystream kopiert und dann aus dem Stream instanziert womit ich danach das File wieder freigeben konnte.

                Code:
                        public AssemblyName LoadAssemblyNameWithoutFileLock(string fileName)
                        {
                            using (FileStream fs = File.Open(fileName, FileMode.Open))
                            {
                                using (MemoryStream ms = new MemoryStream())
                                {
                                    byte[] buffer = new byte[1024];
                                    int read = 0;
                                    while ((read = fs.Read(buffer, 0, 1024)) > 0)
                                        ms.Write(buffer, 0, read);
                                    return Assembly.Load(ms.ToArray()).GetName();
                                }
                            }
                        }

                Comment


                • #23
                  @Ralf: Das einlesen braucht nicht "manuell" gepuffert werden. Dies wird standardmäßig erledigt und die Puffergröße ist bereits optimiert.
                  Weiters ist das erstellen eines Memorystream nicht nötig -> Einlesen in byte[] reicht. D.h.
                  Code:
                  Assembly a;
                  using (FileStream fs = new FileStream("Anwendung.exe", FileMode.Open))
                  {
                  	byte[] buffer = new byte[fs.Length];
                  	fs.Read(buffer, 0, buffer.Length);
                  
                  	a = Assembly.Load(buffer);
                  }
                  Anmerkung:
                  Code:
                  using (FileStream fs = File.Open(fileName, FileMode.Open))
                  // ist ident zu
                  using (FileStream fs = new FileStream(FILE, FileMode.Open))
                  Sonst finde ich deine Möglichkeit sehr interessant und als Alternative zum Shodow Copying

                  mfG Gü
                  Zuletzt editiert von gfoidl; 05.11.2008, 19:37. Reason: Hinzufügen der Anmerkung zum MemoryStream
                  "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

                  Comment


                  • #24
                    Danke Ralf,

                    war gerade eine Weile weg - ich teste das jetzt mal...

                    Gruß,
                    Uffze

                    Comment


                    • #25
                      Ich würde gern die AssemblyFileVersion der alten und der neuen .Exe auslesen, damit der Benutzer weiss, ob beim Update über FTP eine neuere Version auf den PC kopiert wurde.
                      Dieses Problem würde ich anders anpacken:
                      • im Update-Teil der Anwendung (diese Assembly wird per Shadow Copying ausgeführt oder nach Ralf's Methode) ist die aktuelle Version bekannt
                      • auf dem Server (FTP) liegt eine Textdatei die die Versionsinfo enthält und wird abgefragt. Ich löse dies meist per Webservice, aber es geht auch anders
                      • ist auf dem Server eine neue Version vorhanden wird diese heruntergeladen

                      Der Vorteil dabei ist dass nicht jedesmal die Datei heruntergeladen werden muss.

                      mfG Gü

                      PS:
                      Ich habe eine Methode geschrieben, die eine Assembly in eine neue Domäne lädt
                      Du meinst wohl kopiert...
                      "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

                      Comment


                      • #26
                        Es funktioniert!

                        Ich kann's noch gar nicht glauben, nachdem ich viele quälende Stunden an dem kleinen Detail verbracht habe!

                        Danke nochmals.

                        Gruß,
                        Uffze

                        Comment


                        • #27
                          Du meinst wohl kopiert...
                          Nun, ich glaube 2 Zeilen weichen vom Original ab.


                          # auf dem Server (FTP) liegt eine Textdatei die die Versionsinfo enthält und wird abgefragt. Ich löse dies meist per Webservice, aber es geht auch anders
                          # ist auf dem Server eine neue Version vorhanden wird diese heruntergeladen
                          Die .txt-Datei ist auch eine nette Idee wenn ich mal grössere Dateien updaten muss. Meine Anwendung (Bootloader für uController) ist wirklich klein (<100k).
                          Ralf's Assembly-Kniff wird einfach vorher und nachher angewendet, der Tag ist gerettet.

                          Gruß,
                          Uffze
                          Zuletzt editiert von H. P. Uffze; 05.11.2008, 19:33. Reason: Feierabend

                          Comment

                          Working...
                          X