Услуги Сертификаты Новости Статьи База знаний Алгоритмы Портфолио Скачать Ссылки Поиск
Услуги arrow Статьи arrow .NET Application Updater: разработка модуля авто-обновления приложения
.NET Application Updater: разработка модуля авто-обновления приложения Версия для печати Отправить на e-mail
10.07.2009

Рано или поздно, но многие сталкиваются с разработкой утилиты, которая бы могла автоматически обновлять ваше приложение, либо его части.

Задача является типовой, многие хорошие приложения, особенно коробочные, имеют данный модуль. Я хочу рассмотреть его реализацию с примерами.

Для реализации нам понадобится:

  1. web-служба, которая будет предоставлять последние версии нашего приложения;
  2. модуль на стороне клиента, который сможет подключиться к web-службе, запросить у нее последние обновления, принять их и обновить себя и другие модули.

web-служба автообновлений

В разделе "Кодерам" есть пример такой web-службы. В дополнение, хочу заметить, что нужно совсем немного времени, чтобы доработать код службы для нужд автообновления приложения.

Подробнее я хочу рассмотреть приложение на стороне клиента, которое сможет подключаться к web-службе и получать обновления. Примеры кода приводятся на C#.

Клиентское приложение службы автообновления версий

Задачи, которые требуется реализовать для обновления приложения:

  1. проверка уже существующей у клиента версии;
  2. если версия нуждается в обновлении, обновление версии;
  3. перезапуск уже работающего приложения.

Проверка существующей версии приложения

Сравнить версии приложения с информацией, которая предоставляется службой автообновления можно следующим образом.

Пример 

string ExistingFileName = "c:\\MyApp\\MyApp.exe"; // Версия 1.0.1.9
string appNewVersion = "1.0.1.10";
Assembly myAssembly = Assembly.LoadFrom(ExistingFileName);
AssemblyName assemName = myAssembly.GetName();
Version oldVersion = assemName.Version;
Res = ((new Version(appNewVersion)).CompareTo(oldVersion) > 0);

Предполагается, что значение appNewVersion будет получено из web-службы, а наш модуль, который требует обновления имеет имя "c:\MyApp\MyApp.exe".

Переменная Res содержит результат проверки: true - версия существующего файла нуждается в обновлении.

Обновление запущенного приложения

Чтобы обновить запущенное приложение, нужно:

  • переименовать файлы приложения;
  • записать под прежним именем файлы новой версии;
  • запустить новый поток, в котором нужно стартовать новую версию приложения, а старую версию приложения завершить;
  • при повторном запуске приложения проверить наличие прежних переименованных версий приложения и удалить старые файлы.

Удаление прежней версии

Пример

try
{
    foreach (FileInfo FI in (new DirectoryInfo("<Рабочий каталог>")).GetFiles("*.old")) { if (FI.Exists) { FI.Delete(); } }
}
catch (Exception ex)
{
  MessageBox.Show(String.Format("Ошибка удаления старой версии {0}", ex.Message));
}

Переименование прежней версии, запись новых файлов на её место

Пример

private bool UpdateUpdaterRobot()
{
    bool Res = true;
    try
    {               
        // Создается временная папка в папке приема обновлений
        string DirTmp = Path.Combine(config.FolderTemp, Guid.NewGuid().ToString());
        DirectoryInfo tmpDI = Directory.CreateDirectory(DirTmp);
        if (Directory.Exists(DirTmp))
        {
            // Обновление файлов
            foreach (FileInfo fi in tmpDI.GetFiles())
            {
                string srcFileName = Path.Combine(<Каталог, где хранится принятый файл новой версии>, fi.Name);
                if (File.Exists(srcFileName))
                {
                    string newName = srcFileName + ".old";
                    try
                    {
                        // Переименовать старый файл в файл с расширением "old"
                        File.Move(srcFileName, newName);
                    }
                    catch (Exception ex)
                    {
                        Res = false;
                        ErrorMessage = String.Format("Ошибка переноса обновляемого файла: {0}", ex.Message);
                    }
                }
                // В целевую папку перемещается из временной папки принятый файл
                File.Move(Path.Combine(DirTmp, fi.Name), srcFileName);
            }
            // Удаление файла обновления и временной папки
            if (Res)
            {
                try
                {
                    File.Delete(<Имя файла обновления>);
                    Directory.Delete(DirTmp);
                }
                catch (Exception ex)
                {
                    ErrorMessage = String.Format("Ошибка удаления временного файла или папки: {0}", ex.Message);
                }
            }
        }
    }
    catch (Exception ex)
    {
        ErrorMessage = String.Format("Ошибка обновления {0}", ex.Message);
    }
    return Res;
}

Перезапуск приложения

Пример 

string UpdateAppFile = <Файл приложения, который запускаем>
string WorkFolder = <Рабочкий каталог приложения>
if (File.Exists())
{
    ProcessStartInfo myProcess = new ProcessStartInfo(UpdateAppFile);               
    myProcess.WorkingDirectory = WorkFolder;
    myProcess.UseShellExecute = false; // Здесь не нужно запускать отдельный сеанс системной оболочки 
    try
    {
        // Старт процесса
        Process.Start(myProcess);
    }
    catch (Exception ex)
    {
        Messagebox.Show("Ошибка перезапуска приложения : " + ex.ToString(), "Результат операции", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

Собрав все части в одно приложение вы получите модуль автообновления.

Последнее обновление ( 21.07.2009 )
 
< Пред.   След. >