Imports System.IO Imports System.Net Imports WebDav Public Class UpdateInstaller Public Event InstallProgessUpdated(result As UpdateCheckResult, processedSyncs As Integer) Public Event CheckingProgressUpdated(toCheck As Integer, processed As Integer) Private ReadOnly updateConfig As UpdateConfig Private ReadOnly localPath As String Private webdavClient As WebDavClient = Nothing Public Sub New(updateConfig As UpdateConfig, localPath As String) Me.updateConfig = updateConfig Me.localPath = localPath End Sub Private Function CreateClient() As WebDavClient If webdavClient Is Nothing Then Dim params As New WebDavClientParams With { .BaseAddress = New Uri(updateConfig.WebdavURL), .Credentials = New NetworkCredential(updateConfig.WebdavUsername, updateConfig.WebdavPassword) } webdavClient = New WebDavClient(params) End If Return webdavClient End Function Public Async Function CheckForUpdates(ignoreRevmoedFiles As Boolean) As Task(Of UpdateCheckResult) Dim result As New UpdateCheckResult Dim client As WebDavClient = CreateClient() Dim resTopFolder As WebDavResource = Nothing Dim checkedFiles = New List(Of String)() Dim responseSuccessfull As Boolean = False 'Check for new & updated files Dim response = Await client.Propfind(String.Empty, New PropfindParameters() With {.ApplyTo = ApplyTo.Propfind.ResourceAndAncestors}) If resTopFolder Is Nothing AndAlso response.IsSuccessful AndAlso response.Resources.Any() Then resTopFolder = response.Resources.ElementAtOrDefault(0) responseSuccessfull = True End If If responseSuccessfull AndAlso response.Resources.Count > 1 Then Dim i As Integer = 1 Dim loopTo As Integer = response.Resources.Count - 1 Do While i <= loopTo Dim res = response.Resources.ElementAtOrDefault(i) Dim isFolder As Boolean = res.Uri.EndsWith("/") If Not isFolder Then Dim syncAction? As UpdateSyncAction = Nothing Dim localFile As String Dim remoteFile As String 'Get remote file path remoteFile = res.Uri 'Get local file path localFile = Path.Combine(localPath, Uri.UnescapeDataString(res.Uri.Substring(resTopFolder.Uri.Length)).Replace("/", "\")) 'Check action If File.Exists(localFile) Then If File.GetLastWriteTime(localFile) < res.LastModifiedDate = True Then syncAction = UpdateSyncAction.UpdatedFile End If Else syncAction = UpdateSyncAction.NewFile End If 'Add to list checkedFiles.Add(localFile) If syncAction IsNot Nothing Then result.SyncFiles.Add(New UpdateSyncFile(syncAction, localFile, remoteFile)) End If End If i += 1 RaiseEvent CheckingProgressUpdated(loopTo, i) Loop End If 'Find all old files to remove If responseSuccessfull Then Dim allLocalFiles = Directory.GetFiles(localPath, "*", SearchOption.AllDirectories) For Each lf As String In allLocalFiles Dim isKnown As Boolean = False For Each checkedFile As String In checkedFiles If Not isKnown AndAlso If(checkedFile, "") = If(lf, "") Then isKnown = True End If Next If Not isKnown Then result.SyncFiles.Add(New UpdateSyncFile(If(ignoreRevmoedFiles, UpdateSyncAction.None, UpdateSyncAction.RemovedFile), lf, String.Empty)) End If Next End If Return result End Function Public Async Function InstallUpdates(checkResult As UpdateCheckResult, Optional ignoreActions As UpdateSyncAction = UpdateSyncAction.None) As Task(Of Boolean?) Dim client As WebDavClient = CreateClient() Dim success As Boolean? = False Dim processed As Integer = 0 'Init process update RaiseEvent InstallProgessUpdated(checkResult, processed) For Each syncFile In checkResult.SyncFiles If syncFile.SyncAction <> (ignoreActions And syncFile.SyncAction) Then If syncFile.SyncAction = UpdateSyncAction.UpdatedFile OrElse syncFile.SyncAction = UpdateSyncAction.RemovedFile Then If File.Exists(syncFile.LocalFile) Then File.Delete(syncFile.LocalFile) End If End If If syncFile.SyncAction = UpdateSyncAction.UpdatedFile OrElse syncFile.SyncAction = UpdateSyncAction.NewFile Then Dim response = Await client.GetProcessedFile(syncFile.RemoveFile) Dim dirParent As New DirectoryInfo(Path.GetDirectoryName(syncFile.LocalFile)) If response.IsSuccessful Then If Not dirParent.Exists Then dirParent.Create() End If Dim fs As New FileStream(syncFile.LocalFile, FileMode.Create, FileAccess.Write) response.Stream.CopyTo(fs) fs.Close() success = True End If End If End If processed += 1 RaiseEvent InstallProgessUpdated(checkResult, processed) Next Return success End Function End Class