2010-02-25 11 views
12

Mam zestaw .exe i zestaw odwołań złożeń, dla których chciałbym móc zainstalować zaktualizowany kod. Nie muszę właściwie zmieniać uruchomionego kodu, ale następnym razem, gdy uruchomię plik wykonywalny, chcę, aby pobrał zaktualizowany kod. Obecnie, gdy próbuję skopiować na działający plik, pojawia się błąd związany z tym, że .exe jest używane przez inny proces.Jak zaktualizować zespół dla działającego procesu C# (AKA hot deploy)?

Podsumowując; w jaki sposób mogę zaktualizować kod podczas korzystania z .exe?

+0

Wygląda na to, że projekt na Codeplex ma na celu wdrożenie na gorąco dla .NET. Nie próbowałem go jednak: http://hotdeploy.codeplex.com/ –

Odpowiedz

17

Jest to łatwe do zrobienia. Możesz zmienić nazwę pliku, Windows ma blokadę uchwytu, a nie pozycję katalogu dla pliku. Teraz możesz po prostu skopiować aktualizację bez problemów. Pozostaje nam tylko pozbyć się pliku o zmienionej nazwie po ponownym uruchomieniu aplikacji. Jeśli to konieczne.

+0

Czy możesz podać więcej szczegółów/kod? – Jerry

+0

Oprócz odpowiedzi, warto zauważyć, że użytkownik może najpierw odłączyć się od procesu debugowania przed zmianą nazwy pliku, w przeciwnym razie IDE (tj. Visual Studio) nie pozwoli na edycję źródła. –

+0

To złe rozwiązanie, ponieważ po zmianie nazwy otrzymasz uszkodzone skróty. Zamiast tego należy użyć aplikacji pomocniczej. – l0pan

3

Nie sądzę, że to możliwe. Na przykład podczas wdrażania aplikacji asp.net z zerowym czasem przestoju, najlepszą praktyką jest posiadanie modułu równoważenia obciążenia, aby można było usunąć jedno wystąpienie, zaktualizować je, a następnie usunąć drugie w celu aktualizacji.

2

Nie można zaktualizować zespołu, gdy jest on używany. Najlepszą opcją dla tego typu sytuacji jest utworzenie małego pliku wykonywalnego, który wykonuje kopię kopii złożeń i uruchamia je z nowej lokalizacji.

W ten sposób, gdy użytkownik uruchamia program, można kopiować w tle (lokalnie) ze strony wdrożenia, które zawsze można zastąpić.

1

co następuje:

  1. Deploy exe do folderu aktualizacji.
  2. Za każdym razem, gdy uruchomi się aplikacja, będzie to sprawdzić folder aktualizacji.
  3. Jeśli jej nie jest pusta, wykonać kopię programu
  4. Program kopia będzie następnie zastąpić istniejące exe z jednego w folderze aktualizacji
  5. usuwać wszystko w folderze aktualizacji
  6. Następnie ponownie uruchom exe
1

Najlepszym pomysłem byłaby jedna z innych sugerowanych odpowiedzi ... takich jak użycie rekompozycji z MEF i lub ClickOnce. Jednak te rozwiązania nie pomogą ci w "tej instalacji". Wymagają one wprowadzenia zmian w pliku exe i utworzenia pliku wykonywalnego paska startowego, który pomoże tylko w następnym wdrożeniu.

Dla to wdrożyć można spróbować zrobić to (nigdy nie zrobiłeś tego wcześniej, ale teoretycznie może to działać):

  1. Skopiuj nowych dll do podkatalogu gdzieś
  2. dodać polecenie komenda line xcopy do RunOnce registry key, aby skopiować nową bibliotekę dll z podfolderu do końcowego folderu exe, gdzie chcesz go uruchomić.
  3. Uruchom ponownie.

Klucz RunOnce zawiera polecenia wiersza poleceń, które są uruchamiane raz podczas ponownego uruchamiania, a następnie usuwane z rejestru, aby nie były uruchamiane ponownie. W ten sposób InstallShield pozwala na nadpisanie pewnych bibliotek dll, gdy są one używane przez inne aplikacje.

0

Klasa ta będzie zmienić nazwę pliku wykonywalnego aktualnie uruchomione, jeśli uzupełnia bez wyjątku, można po prostu napisać nowy plik wykonywalny, a następnie wznowienia, na przykład:

Ourself.Rename(); 
// Download or copy new version 
File.Copy(newVersion, Ourself.FileName()); 
// Launch new version 
System.Diagnostics.Process.Start(Ourself.FileName()); 
// Close current version 
Close(); // Exit(); 

dość łatwe?

class Ourself 
{ 
    public static string FileName() { 
     Assembly _objParentAssembly; 

     if (Assembly.GetEntryAssembly() == null) 
      _objParentAssembly = Assembly.GetCallingAssembly(); 
     else 
      _objParentAssembly = Assembly.GetEntryAssembly(); 

     if (_objParentAssembly.CodeBase.StartsWith("http://")) 
      throw new IOException("Deployed from URL"); 

     if (File.Exists(_objParentAssembly.Location)) 
      return _objParentAssembly.Location; 
     if (File.Exists(System.AppDomain.CurrentDomain.BaseDirectory + System.AppDomain.CurrentDomain.FriendlyName)) 
      return System.AppDomain.CurrentDomain.BaseDirectory + System.AppDomain.CurrentDomain.FriendlyName; 
     if (File.Exists(Assembly.GetExecutingAssembly().Location)) 
      return Assembly.GetExecutingAssembly().Location; 

     throw new IOException("Assembly not found"); 
    } 

    public static bool Rename() 
    { 
     string currentName = FileName(); 
     string newName = FileName() + ".ori"; 
     if (File.Exists(newName)) 
     { 
      File.Delete(newName); 
     } 
     File.Move(currentName, newName); 
     return true; 
    } 
} 
Powiązane problemy