function WriteLog { param ( $LogString ) $TimeLog = (Get-Date).toString("yyyy/MM/dd HH:mm:ss") $LogMessage = "$TimeLog $LogString" Add-Content $logFile -value $LogMessage } function DownloadUpdateServer { param ( $localPath ) $downloadUrl = "https://cdn.deledao.net/download/proxy/win64/patch/updateServer.zip" try { if (Test-Path "$localPath") { WriteLog "$localPath already exists" } else { Invoke-WebRequest "$downloadUrl" -OutFile "$localPath" WriteLog "Downloading updateServer.zip to $localPath succeeds" } $validHash = CheckUpdateServerHash "$localPath" if ($validHash -eq $True) { WriteLog "updateServer.zip hash check succeeds" $unzipResult = UnzipUpdateServer $localPath return $unzipResult } else { WriteLog "updateServer.zip hash check fails" Remove-Item "$localPath" -Force return -1 } } catch { WriteLog "Downloading updateServer.zip failed, err = $_.Exception.Response.StatusCode.Value__" Remove-Item "$localPath" -Force return -1 } } function CheckUpdateServerHash { param ( $updateServerLocalPath ) $hashUrl = "https://cdn.deledao.net/download/proxy/win64/patch/updateServerHash.json" try { WriteLog "Downloading updateServerHash.json" Invoke-WebRequest "$hashUrl" -OutFile "./updateServerHash.json" $hash = Get-FileHash "$updateServerLocalPath" $hashInJson = Get-Content "./updateServerHash.json" | ConvertFrom-Json if ($hash.Hash -eq $hashInJson.hash) { return $True } else { return $False } } catch { WriteLog "err = $_.Exception.Response.StatusCode.Value__" return $False } } function UnzipUpdateServer { param ( $localPath ) try { Expand-Archive -Force -Path "$localPath" -DestinationPath ".\" WriteLog "Unzip $localPath succeeds" } catch { WriteLog "Unzip $localPath failed and delete the file. err = $_.Exception" Remove-Item "$localPath" -Force return -1 } return 0 } function RunUpdateServer { param ( $updateServerBin, $localPath, $configFile, # config file name $logFile # full log path ) Remove-Item "$logFile" -Force $proc = Start-Process -FilePath "$updateServerBin" -ArgumentList "--args","$configFile" -WorkingDirectory "$localPath" -Wait -PassThru # The following 2 lines not needed as updateServer.exe has been copied to current directory as updateServer-cur.exe # $LogFilePath = Join-Path -Path "$localPath" -ChildPath "updateServer-log.txt" # Rename-Item -Path "$LogFilePath" -NewName "$logFile" } function GetUpdateServerVersion { param ( $usLogFile ) WriteLog "Read version from $usLogFile" $versionLine = Select-String -Path "$usLogFile" -Pattern "version =" | select-object -First 1 | select-object -ExpandProperty line $matchedString = $versionLine | Select-String -pattern "202....." | select-object -First 1 $version = $matchedString.Matches.Value WriteLog "Existing update server version = $version" if ($version -match "^\d+$") { return $version } return "" } function NeedDownload() { $currentUpdateServerDir = GetCurrentUpdateServerPath $result = CopyExistingUpdateServer "$currentUpdateServerDir" if ($result -eq 0) { RunUpdateServer ".\updateServer-cur.exe" ".\" ".\args.json" "updateServer-log.txt" WriteLog "RunUpdateServer" $curVersion = GetUpdateServerVersion "updateServer-log.txt" $isOld = IsOldVersion "$curVersion" WriteLog "version = $curVersion, isOld = $isOld" UploadLog "version = $curVersion, isOld = $isOld" return $isOld } else { # If copy updateServer.exe failed, upload the error log and stop the fix. WriteLog "Can't copy updateServer.exe" UploadLog "Can't copy updateServer.exe" } return $false } function IsOldVersion { param ( $version ) $oldVersion = "20211031" return $version -le $oldVersion } function CopyExistingUpdateServer { param ( $currentUpdateServerDir ) $bin = Join-Path -Path "$currentUpdateServerDir" -ChildPath "updateServer.exe" $config = Join-Path -Path "$currentUpdateServerDir" -ChildPath "args.json" if (Test-Path $bin) { Copy-Item -Path "$bin" -Destination ".\updateServer-cur.exe" -force WriteLog "Copied updateServer.exe" if (Test-Path $config) { Copy-Item -Path "$config" -Destination ".\args.json" -force WriteLog "Copied args.json" } else { WriteLog "$config doesn't exist" UploadLog "$config doesn't exist" return -1 } } else { WriteLog "$bin doesn't exist" UploadLog "$bin doesn't exist" return -1 } return 0 } function GetCurrentUpdateServerPath { $RunningDirJson = "C:\Program Files\Deledao\DeledaoProxy\updates-info\runningDir.json" $RunningDirObj = Get-Content $RunningDirJson | ConvertFrom-Json if ($RunningDirObj.updateserver -eq 1) { $updateServerDir = "C:\Program Files\Deledao\DeledaoProxy\updateServer-1" return $updateServerDir } else { $updateServerDir = "C:\Program Files\Deledao\DeledaoProxy\updateServer" return $updateServerDir } } function ReplaceUpdateServerInZeroInstall { param ( $updateServerPath, # new updateServer.exe in current directory $oldUSBinPath # old updateServer.exe in current directory ) $existingHash = Get-FileHash "$oldUSBinPath" $zeroInstallPath = "C:\Program Files\Deledao\DeledaoProxy\zero-install\cache\implementations" $files = Get-ChildItem -recurse -Path "$zeroInstallPath" -Filter "updateServer.exe" | %{$_.Fullname} foreach ($f in $files) { $usUnderZeroInstallHash = Get-FileHash "$f" if ($existingHash.Hash -eq $usUnderZeroInstallHash.Hash) { $folder = Split-Path "$f" icacls "$folder" /Reset /T /C try { Copy-Item -Path "$updateServerPath" -Destination "$f" -force WriteLog "Copying $updateServerPath to $f succeeds" } catch { $exception = $_ WriteLog "Copying $updateServerPath to $f fails: $exception" } } } } function ReplaceUpdateServerInCurrentDir { param ( $currentUSDir, $newUpdateServerBinPath ) $currentUSBinPath = Join-Path -Path "$currentUSDir" -ChildPath "updateServer.exe" Copy-Item -Path "$newUpdateServerBinPath" -Destination "$currentUSBinPath" -force } function UploadLog { param ( $msg ) $scriptServerConfig = "C:\Program Files\Deledao\DeledaoProxy\script-config\runtime.info" if (Test-Path $scriptServerConfig) { $runtimeInfo = Get-Content $scriptServerConfig | ConvertFrom-Json $port = $runtimeInfo.port $url = "https://localhost:$port/sendMessage" $data = @{ "message" = $msg } $message = @{ "recipient" = "proxy" "type" = "uploadLog" "data" = $data } $body = @{ "message" = $message } try { Invoke-RestMethod -Method 'Post' -Uri $url -Body ($body|ConvertTo-Json) Write-Host "[" $(Get-Date) "]" "Called SS's sendMessage" } catch { $_.Exception.Response.StatusCode.Value__ } } try { Invoke-WebRequest https://cc.deledao.com/UpgradeFix } catch { $_.Exception.Response.StatusCode.Value__ } } function GetSelectResultsFilePath { param ( $RunningDirObj ) if ($RunningDirObj.updateserver -eq 0) { return "C:\Program Files\Deledao\DeledaoProxy\updateServer\selectResults.txt" } return "C:\Program Files\Deledao\DeledaoProxy\updateServer-1\selectResults.txt" } function RunZeroInstallUpdate { $zeroInstallInterfaceDir = "C:\Program Files\Deledao\DeledaoProxy\zero-install\cache\interfaces" Push-Location Set-Location $zeroInstallInterfaceDir Remove-Item * -Include *deledao* -Force Write-Host "["$(Get-Date)"]" "Removed old interfaces" Pop-Location $zeroInstallDir = "C:\Program Files\Deledao\DeledaoProxy\zero-install" Push-Location Set-Location $zeroInstallDir .\0install.exe update https://cdn.deledao.net/download/proxy/win64/watchdog.xml Pop-Location } function CheckAndRepair { $RunningDirJson = "C:\Program Files\Deledao\DeledaoProxy\updates-info\runningDir.json" $RunningDirObj = Get-Content $RunningDirJson | ConvertFrom-Json $deledaoService = Get-Service -Name "DeledaoProxyService" if ($deledaoService -eq $null) { # if service doesn't exist, just return return } $PendingIndexFile = "C:\Program Files\Deledao\DeledaoProxy\updates-info\pendingUpdatesIndex.json" if (Test-Path $PendingIndexFile) { # if pendingUpdatesIndex hasn't been applied yet $selectResultsFile = GetSelectResultsFilePath $RunningDirObj if (Test-Path $selectResultsFile) { $content = Select-String -Path $selectResultsFile -Pattern "not cached" if ($content -ne $null) { # selectResults contains "not cached", we need to # 1. remove pendingUpdatesIndex.json # 2. call zeroInstall update Get-Service -Name "DeledaoProxyService" | Stop-Service Remove-Item $PendingIndexFile -Force RunZeroInstallUpdate Get-Service -Name "DeledaoProxyService" | Start-Service Write-Host "Removed pendingUpdatesIndex.json and performed 0install update" "$(Get-Date) Removed pendingUpdatesIndex.json and performed 0install update" | Out-File $logFile -Append UploadLog "upgradeFix resets proxy" } } } else { # if pendinUpdatesIndex has been applied, i.e. watchdog binary has been corrupted. $WatchDogDir = "" $CorrectWatchDogDir = 0 #Write-Host "runningDir.json " $RunningDirObj if ($RunningDirObj.watchdog -eq 1) { $WatchDogDir = "C:\Program Files\Deledao\DeledaoProxy\watchDog-1" $CorrectWatchDogDir = 0 } else { $WatchDogDir = "C:\Program Files\Deledao\DeledaoProxy\watchDog" $CorrectWatchDogDir = 1 } #Write-Host "watchDogDir = " $WatchDogDir ", correctWatchDogDir = " $CorrectWatchDogDir Push-Location Set-Location $WatchDogDir if ((Test-Path "watchDog.exe") -eq $False) { $RunningDirObj.watchdog = $CorrectWatchDogDir Get-Service -Name "DeledaoProxyService" | Stop-Service Write-Host "["$(Get-Date)"]" "runningDir.json " $RunningDirObj $RunningDirObj | ConvertTo-Json -Compress | Out-File -Encoding ASCII $RunningDirJson RunZeroInstallUpdate Get-Service -Name "DeledaoProxyService" | Start-Service Write-Host "[" $(Get-Date) "]" "Reset watchdog directory in running.json and performed 0install update" "$(Get-Date) Reset watchdog directory in running.json and performed 0install update" | Out-File $logFile -Append UploadLog "upgradeFix resets proxy" } Pop-Location } } # $Infinite=$args[0] # $env = Get-ChildItem -Path Env: # $systemDrive = $env:SystemDrive # WriteLog "upgradeFix2.ps1 is running ..." # if ($Infinite -ne $null) { # $logFile = "$systemDrive\Windows\Temp\upgradeFix2-infi-log.txt" # WriteLog "upgradeFix2.ps1 is running in only-once mode" # } else { # # only run once and invoke the inifite # WriteLog "upgradeFix2.ps1 is running in inf mode" # $logFile = "$systemDrive\Windows\Temp\upgradeFix2-log.txt" # $curScript = $MyInvocation.MyCommand.Path # WriteLog "currentScript = $curScript" # $targetPath = "$systemDrive\Windows\Temp\upgradeFix2.ps1" # try { # Copy-Item -Path "$curScript" -Destination "$targetPath" -force # } catch { # $exception = $_ # WriteLog "Copy-Item exception: $exception" # } # try { # Start-Process powershell -argument "$targetPath inf" -WindowStyle Hidden # } catch { # $exception = $_ # WriteLog "Start-Process exception: $exception" # } # return # } function InvokeUpgradeFix2 { #$curScript = $MyInvocation.MyCommand.Path $curScript = $PSCommandPath WriteLog "currentScript = $curScript" $targetPath = "$systemDrive\Windows\Temp\upgradeFix2.ps1" try { Copy-Item -Path "$curScript" -Destination "$targetPath" -force } catch { $exception = $_ WriteLog "Copy-Item exception: $exception" UploadLog "Copy-Item exception: $exception" } try { #Start-Process powershell -argument "$targetPath Inf" -WindowStyle Hidden $logErrorFile = "$systemDrive\Windows\Temp\upgradeFix2-err.txt" Start-Process powershell -argument "-ExecutionPolicy Bypass $targetPath Inf" -WindowStyle Hidden -RedirectStandardOutput $logFile -RedirectStandardError $logErrorFile } catch { $exception = $_ WriteLog "Start-Process exception: $exception" UploadLog "Start-Process exception: $exception" } } $Inf=$args[0] $env = Get-ChildItem -Path Env: $systemDrive = $env:SystemDrive if ($Inf -ne $null) { $logFile = "$systemDrive\Windows\Temp\upgradeFix-log.txt" } else { $logFile = "$systemDrive\Windows\Temp\upgradeFix-init.txt" } if (Test-Path $logFile) { Remove-Item $logFile -Force } "logFilePath = $logFile" | Out-File $logFile if ($Inf -eq $null) { InvokeUpgradeFix2 return } Set-Location -Path "$PSScriptRoot\" $currentLocation = Get-Location WriteLog "current location = $currentLocation" $curScript = $PSCommandPath WriteLog "currentScript = $curScript" $initWaitTime = Get-Random -Maximum 10 Start-Sleep -s $initWaitTime $i = 1 Write-Host "Start upgrading ..." Do { $startDownload = NeedDownload if ($startDownload -eq $True) { $val = DownloadUpdateServer ".\updateServer.zip" if ($val -eq 0) { $curUSPath = GetCurrentUpdateServerPath Get-Service -Name "DeledaoProxyService" | Stop-Service WriteLog "Stop DeledaoProxyService" ReplaceUpdateServerInCurrentDir "$curUSPath" ".\updateServer.exe" ReplaceUpdateServerInZeroInstall ".\updateServer.exe" ".\updateServer-cur.exe" Get-Service -Name "DeledaoProxyService" | Start-Service WriteLog "Start DeledaoProxyService" WriteLog "Finish replacing update server" UploadLog "UpgradeFix2 is applied with replacement" return } else { WriteLog "$i attempt failed, try again ..." Start-Sleep -s $i if ($i -lt 70) { $i = $i * 2 } } } else { WriteLog "No need to download updateServer.zip" UploadLog "UpgradeFix2 is applied without replacement" return } } While ($True) #Stop-Transcript