2009-02-27 23 views
1

Ich habe einige UI-Anwendung, die in der Taskleiste des Benutzers lebt, die in C# geschrieben wird. Die EXE für das Tool wird bei einer Reihe von Projekten, die es verwenden, in unser Quellcodeverwaltungssystem eingecheckt, sodass wir die Version, mit der sie ausgeführt werden, aktualisieren können, indem Sie die aktualisierte EXE einchecken.Wie kann ich ein Programm aus dem Speicher in C# starten?

Das Problem ist, dass wenn die Benutzer die neueste Revision der EXE erhalten, das Programm oft ausgeführt wird, und die Synchronisierung auf ihrem Computer fehlschlägt. Ich möchte es reparieren, so dass das Programm die exe und alle abhängigen DLLs nicht blockiert, wenn es läuft, damit sie synchronisieren können, ohne das Programm herunterfahren zu müssen.

Zur Zeit habe ich ein Programm, das eine ausführbare Datei als Parameter nimmt und es aus dem Speicher startet, indem der Inhalt der Assembly im Speicher vorgelesen wird. Unglücklicherweise versagt dies vollständig, wenn es um die DLLs geht, die das Programm benötigt.

Der Code habe ich jetzt wie folgt aussieht etwas:

public class ExecuteFromMemory 
{ 
    public static void Main(string[] args) 
    { 
     //Figure out the name of the EXE to launch and the arguments to forward to it 
     string fileName = args[0]; 
     string[] realArgs = new string[args.Length - 1]; 
     Array.Copy(args, 1, realArgs, 0, args.Length - 1); 

     //Read the assembly from the disk 
     byte[] binary = File.ReadAllBytes(fileName); 

     //Execute the loaded assembly using reflection 
     Assembly memoryAssembly = null; 
     try 
     { 
      memoryAssembly = Assembly.Load(binary); 
     } 
     catch (Exception ex) 
     { 
      //Print error message and exit 
     } 

     MethodInfo method = memoryAssembly.EntryPoint; 
     if (method != null && method.IsStatic) 
     { 
      try 
      { 
       method.Invoke(null, new object[] { realArgs }); 
      } 
      catch(Exception ex) 
      { 
       //Print error message and exit 
      } 
     } 
     else 
     { 
      //Print error message and exit 
     } 
    } 
} 

Meine Frage ist, bin ich etwas total blöd tun? Gibt es einen besseren Weg, damit umzugehen? Wenn nicht, was sollte ich tun, um den Umgang mit externen Abhängigkeiten zu unterstützen?

Zum Beispiel kann der obige Code keine abhängigen Dateien laden, wenn Sie versuchen, "Foo.exe" auszuführen, die Funktionen aus "Bar.dll" verwendet, die "Foo.exe" wird überschreibbar sein, aber "Bar. dll 'ist immer noch gesperrt und kann nicht überschrieben werden.

Ich habe versucht, die Liste der referenzierten Assemblys von der 'GetReferencedAssemblies()' Methode auf dem geladenen assmebly zu bekommen, aber das scheint keinen Hinweis darauf zu geben, wo die Assembly geladen werden soll ... Muss ich suchen für sie selbst? Wenn ja, was ist der beste Weg, dies zu tun?

Es scheint, als wären andere Leute schon einmal darauf gestoßen, und ich möchte das Rad nicht neu erfinden.

- Aktualisierung: Die EXE wird eingecheckt, weil wir unsere internen Tools so an die Teams verteilen, die sie verwenden. Es ist nicht optimal für diesen Anwendungsfall, aber ich habe nicht die Möglichkeit, diese Richtlinie zu ändern.

+0

Und warum möchten Sie aus dem Speicher ausführen? Dies ist ein guter Weg, um Ihr Programm Live-Virus aussehen zu lassen. – Migol

Antwort

1

Benötigt das Programm , um während der Aktualisierung weiterlaufen zu können?

Um ein laufendes Programm zu aktualisieren, werden normalerweise Dateien kopiert, die in einem temporären Ordner ersetzt werden sollen. Dann fahren Sie die alte Instanz herunter, löschen Sie sie und verschieben Sie die neuen Dateien an die richtigen Stellen und starten Sie sie erneut.

Dies ermöglicht eine minimale Ausfallzeit der Anwendung, da der längste Teil normalerweise die Kopie ist und die Dateiverschiebung sehr schnell ist, wenn sich der temporäre Ordner auf demselben logischen Laufwerk befindet.

4

Haftungsausschluss: Ich verwende kein Windows, obwohl ich mit seiner seltsamen Art vertraut bin, Dinge zu sperren.

Um Ihre Anwendung zu aktualisieren, während sie ausgeführt wird, müssen Sie wahrscheinlich zwei Prozesse haben: Die ausführbare Datei selbst und eine Aktualisierung "Helfer" -Anwendung, die den Update-Prozess beendet. Angenommen, Ihre Anwendung ist ProcessA.exe und Ihr Updatehelfer ist Updater.exe. Ihr Hauptprogramm lädt eine neue Kopie der ausführbaren Datei herunter und speichert sie unter einem zufälligen Namen. Dann führen Sie Ihr Updater-Programm aus, das auf die Beendigung Ihres aktuellen Prozesses achtet. Wenn Ihr Prozess beendet wird, wird ein schnelles Fenster angezeigt, in dem der Status des Updates angezeigt wird. Anschließend wird die neue ausführbare Datei an die Stelle des alten verschoben und anschließend neu gestartet.

Es wäre eleganter, in der Lage zu sein, die POSIX-Dateisystem-Semantik zu emulieren und das aktuell laufende Prozessdatenträgerabbild zu löschen und durch eine neue Datei zu ersetzen, aber ich weiß nicht, ob das überhaupt möglich ist Windows. Auf einem POSIX-System können Sie eine In-Use-Datei löschen und sie wird nicht wirklich gelöscht, bis alle verbleibenden Dateizugriffsnummern geschlossen sind. Sie können den Dateinamen jedoch erneut verwenden.

Sie möchten vielleicht einen Artikel unter CodeProject, dass talks about this. Es hat auch eine follow-up article.

Viel Glück!

0

Obwohl Michaels Antwort eine Möglichkeit ist, dies zu tun, gibt es Tools, die explizit dafür gedacht sind, zu verwalten, was auf dem Desktop installiert ist.

Was Sie tun, wenn die Exe in die Quellcodeverwaltung eingecheckt wird, ist nicht normal. Wenn Sie einen Windows-Domänencontroller haben, können Sie mithilfe von Gruppenrichtlinien Programme an den Client senden. Alternativ könnten Sie etwas wie Altiris verwenden, um damit umzugehen.

Wenn Sie den Weg fortsetzen müssen, haben Sie zwei Möglichkeiten. Eine, die eine Helfer/Lader-App benutzt, die beim Start eine Versionskontrolle durchführt. Dies ist ähnlich wie Firefox funktioniert.

Die zweite Möglichkeit besteht darin, einen Hilfsdienst zu erstellen, der im Speicher sitzt und regelmäßig nach Updates sucht. So funktioniert Google Chrome, Adobe, etc.

Verwandte Themen