Самообновляющееся приложение в vb.net

Я хочу, чтобы мое приложение самообновлялось, если на удаленном сервере доступен исполняемый файл другого размера. Проблема, с которой я столкнулся, заключается в том, что когда я убиваю процесс для замены исполняемого файла приложения, больше ничего не происходит - после eprocess.Kill() больше ничего не выполняется, хотя я пытаюсь заморозить поток во время процесса замены файла. Есть ли что-то, что я делаю неправильно?

Вот мой код:

            Dim Request As System.Net.WebRequest
            Dim Response As System.Net.WebResponse
            Dim FileSize As Integer
            Request = Net.WebRequest.Create("http://mywebsite.com/File.exe")
            Request.Method = Net.WebRequestMethods.Http.Get
            Response = Request.GetResponse
            FileSize = Response.ContentLength
            Dim mySize As New IO.FileInfo(Application.ExecutablePath)
            If FileSize <> mySize.Length Then                    If File.Exists(tempPath & "\File_tmp.exe") Then
                    File.Delete(tempPath & "\File_tmp.exe")
                End If
                Patcher.DownloadFileAsync(New Uri("http://mywebsite.com/File.exe"), tempPath & "\File_tmp.exe") 'Patcher is defined before, you might think that its not working, but this is just a piece of code, and the new file is downloading properly. The described problem is 
                While Patcher.IsBusy
                    Threading.Thread.Sleep(100)
                End While

                Do While True
                    For Each eprocess As Process In Process.GetProcesses
                        If eprocess.ProcessName = "MyApplication" Then
                            eprocess.Kill()
                        End If
                    Next
                    File.Delete(Application.ExecutablePath)
                    'Copy downloaded file to the application executable path directory
                    File.Copy(tempPath & "\File_tmp.exe", Application.ExecutablePath)
                    Threading.Thread.Sleep(30) 'freeze thread...
                Loop
            End If

person Lucas    schedule 27.06.2013    source источник


Ответы (5)


Один из способов справиться с этим - создать отдельный (меньший exe) в вашем проекте, который обрабатывает загрузку новой версии. Сначала он закроет текущую версию, и, поскольку она не привязана к исходному приложению, приложение для загрузки все еще работает, оно загружает, затем устанавливает его, а затем запускает новую версию.

person OneFineDay    schedule 27.06.2013
comment
Вы имеете в виду что-то вроде загрузки Updater.exe во временный путь, а затем запустить его и убить основное приложение? Кажется законным, я попробую это. - person Lucas; 27.06.2013
comment
Кстати. что вы думаете о выполнении этой работы в пакетном режиме? Это не потребует дополнительных приложений... - person Lucas; 27.06.2013

Есть встроенный функционал, который сделает это за вас.

Взгляните на ClickOnce. Это избавляет от необходимости иметь отдельное приложение для обновления за вас и позволяет указать минимальную и рекомендуемую версию, проверяет ли приложение наличие новой версии до или после запуска и т. д.

Еще несколько ссылок, которые могут быть полезны:

http://msdn.microsoft.com/en-us/magazine/cc163973.aspx http://www.codeproject.com/Articles/38546/Click-Once-Deployment-Technique

person Matt Wilko    schedule 27.06.2013

Я подумал, что добавлю свое предложение к миксу, заключающееся в том, что это все еще лучший результат в Google для stackoverflow.

Во-первых.. Я не могу вынести решение ClickOnce, поскольку оно изменяет большую часть проекта и требует других шагов и т. д. Поэтому я исключил это после 10 минут изучения.

Кроме того, что касается наличия другого исполняемого файла для обработки обновлений ... Это тоже не было идеальным для меня ... Так что моя основная установка исполняемого файла / установки делала все это за меня.

По сути, у меня есть веб-сайт, на котором я размещаю установочные файлы установки с простым файлом данных JSON для хранения информации о версии. Доступ к этому осуществляется через само приложение с использованием http-запроса и декодирования json для запроса последней версии и сравнения ее с текущей версией приложения.

Если будет найдена новая версия, приложение загрузит копию новой установки и поместит ее в основной каталог приложений во временную папку/папку установщиков.

После завершения загрузки я запускаю программу установки из приложения и не жду выхода. Следующий подобный код вызовет функции сохранения и выхода приложений.

На этом этапе у вас запущена установка, но основное приложение закрыто. Отсюда программа установки может продолжить работу в обычном режиме и запустить приложение по завершении.

Конечно, вы можете изменить множество вещей, таких как автоматическая установка и т. д., но с помощью этого метода я могу обойтись только обычным установщиком и исполняемым файлом приложения.

person Angry 84    schedule 22.07.2016

Я говорю, что вы пишете функцию, которая создает пакетный файл, который

  • загружает новую версию вашего exe
  • закрывает ваше приложение и перезаписывает ваш exe новым.
  • Открывает ваше приложение

Затем ваше приложение при запуске должно искать такой командный файл и стирать его.

person Mandolf0    schedule 10.05.2019

Создайте средство обновления, работа которого будет заключаться в загрузке файлов с удаленного сервера, а затем их копировании/перемещении в основной каталог приложения. Я уже давно использую этот подход, и он отлично работает. Возможно, этот подход подойдет вам https://www.codeproject.com/Articles/35787/VB-NET-Background-File-Downloader

person Albert Alberto    schedule 02.10.2020