mirror of
				https://github.com/velopack/velopack.git
				synced 2025-10-25 15:19:22 +00:00 
			
		
		
		
	Remove Msft.Logging from C# lib
This commit is contained in:
		| @@ -4,20 +4,20 @@ using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Text.RegularExpressions; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Velopack.Exceptions; | ||||
| using Velopack.Logging; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| namespace Velopack.Compression | ||||
| { | ||||
|     internal abstract class DeltaPackage | ||||
|     { | ||||
|         protected readonly ILogger Log; | ||||
|         protected readonly IVelopackLogger Log; | ||||
|         protected readonly string BaseTempDir; | ||||
| 
 | ||||
|         private static Regex DIFF_SUFFIX = new Regex(@"\.(bs|zs)?diff$", RegexOptions.Compiled | RegexOptions.IgnoreCase); | ||||
| 
 | ||||
|         public DeltaPackage(ILogger logger, string baseTmpDir) | ||||
|         public DeltaPackage(IVelopackLogger logger, string baseTmpDir) | ||||
|         { | ||||
|             Log = logger; | ||||
|             BaseTempDir = baseTmpDir; | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| using System; | ||||
| using System.Diagnostics; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Velopack.Logging; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| namespace Velopack.Compression | ||||
| @@ -9,7 +9,7 @@ namespace Velopack.Compression | ||||
|     { | ||||
|         private readonly string _updateExePath; | ||||
| 
 | ||||
|         public DeltaUpdateExe(ILogger logger, string baseTmpDir, string updateExePath) : base(logger, baseTmpDir) | ||||
|         public DeltaUpdateExe(IVelopackLogger logger, string baseTmpDir, string updateExePath) : base(logger, baseTmpDir) | ||||
|         { | ||||
|             _updateExePath = updateExePath; | ||||
|         } | ||||
| @@ -19,11 +19,12 @@ namespace Velopack.Compression | ||||
|             var psi = new ProcessStartInfo(_updateExePath); | ||||
|             psi.AppendArgumentListSafe(new string[] { "patch", "--old", baseFile, "--patch", patchFile, "--output", outputFile }, out var _); | ||||
|             psi.CreateNoWindow = true; | ||||
|             var p = psi.StartRedirectOutputToILogger(Log, LogLevel.Debug); | ||||
|             var p = psi.StartRedirectOutputToILogger(Log, VelopackLogLevel.Debug); | ||||
|             if (!p.WaitForExit(30_000)) { | ||||
|                 p.Kill(); | ||||
|                 throw new TimeoutException("zstd patch process timed out (30s)."); | ||||
|             } | ||||
| 
 | ||||
|             if (p.ExitCode != 0) { | ||||
|                 throw new Exception($"zstd patch process failed with exit code {p.ExitCode}."); | ||||
|             } | ||||
|   | ||||
| @@ -6,7 +6,7 @@ using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Velopack.Logging; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| namespace Velopack.Compression | ||||
| @@ -15,7 +15,7 @@ namespace Velopack.Compression | ||||
|     { | ||||
|         private const string SYMLINK_EXT = ".__symlink"; | ||||
| 
 | ||||
|         public static void ExtractZipToDirectory(ILogger logger, string inputFile, string outputDirectory, bool expandSymlinks = false) | ||||
|         public static void ExtractZipToDirectory(IVelopackLogger logger, string inputFile, string outputDirectory, bool expandSymlinks = false) | ||||
|         { | ||||
|             logger.Debug($"Extracting '{inputFile}' to '{outputDirectory}' using System.IO.Compression..."); | ||||
|             IoUtil.DeleteFileOrDirectoryHard(outputDirectory); | ||||
| @@ -85,7 +85,7 @@ namespace Velopack.Compression | ||||
| 
 | ||||
|         internal static string SanitizeEntryFilePath(string entryPath) => entryPath.Replace('\0', '_'); | ||||
| 
 | ||||
|         public static async Task CreateZipFromDirectoryAsync(ILogger logger, string outputFile, string directoryToCompress, Action<int>? progress = null, | ||||
|         public static async Task CreateZipFromDirectoryAsync(IVelopackLogger logger, string outputFile, string directoryToCompress, Action<int>? progress = null, | ||||
|             CompressionLevel compressionLevel = CompressionLevel.Optimal, CancellationToken cancelToken = default) | ||||
|         { | ||||
|             progress ??= (x => { }); | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using NuGet.Versioning; | ||||
| using Velopack.Logging; | ||||
| 
 | ||||
| namespace Velopack.Locators | ||||
| { | ||||
| @@ -39,6 +40,9 @@ namespace Velopack.Locators | ||||
|         /// <summary> The release channel this package was built for. </summary> | ||||
|         public string? Channel { get; } | ||||
|          | ||||
|         /// <summary> The logging interface to use for Velopack diagnostic messages. </summary> | ||||
|         public IVelopackLogger Log { get; } | ||||
|          | ||||
|         /// <summary> | ||||
|         /// A flag indicating if this is a portable build, and that the settings should be self-contained in the package. | ||||
|         /// On Windows, this is true for portable builds, and false for non-portable builds which were installed by Setup.exe | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| using System; | ||||
| using System; | ||||
| using System.IO; | ||||
| using System.Runtime.Versioning; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using NuGet.Versioning; | ||||
| using Velopack.Logging; | ||||
| using Velopack.NuGet; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| @@ -33,6 +33,9 @@ namespace Velopack.Locators | ||||
|         /// <inheritdoc /> | ||||
|         public override string? Channel { get; } | ||||
|          | ||||
|         /// <inheritdoc /> | ||||
|         public override IVelopackLogger Log { get; } | ||||
| 
 | ||||
|         /// <inheritdoc /> | ||||
|         public override string? AppTempDir => CreateSubDirIfDoesNotExist(TempUtil.GetDefaultTempBaseDirectory(), AppId); | ||||
| 
 | ||||
| @@ -58,8 +61,7 @@ namespace Velopack.Locators | ||||
|         /// Creates a new <see cref="OsxVelopackLocator"/> and auto-detects the | ||||
|         /// app information from metadata embedded in the .app. | ||||
|         /// </summary> | ||||
|         public LinuxVelopackLocator(string currentProcessPath, uint currentProcessId, ILogger logger) | ||||
|             : base(logger) | ||||
|         public LinuxVelopackLocator(string currentProcessPath, uint currentProcessId, IVelopackLogger? logger) | ||||
|         { | ||||
|             if (!VelopackRuntimeInfo.IsLinux) | ||||
|                 throw new NotSupportedException("Cannot instantiate LinuxVelopackLocator on a non-linux system."); | ||||
| @@ -67,12 +69,16 @@ namespace Velopack.Locators | ||||
|             ProcessId = currentProcessId; | ||||
|             var ourPath = ProcessExePath = currentProcessPath; | ||||
| 
 | ||||
|             Log.Info($"Initialising {nameof(LinuxVelopackLocator)}"); | ||||
|             logger ??= new FileVelopackLogger("/tmp/velopack.log", currentProcessId); | ||||
|             logger.Info($"Initialising {nameof(LinuxVelopackLocator)}"); | ||||
|             Log = logger; | ||||
| 
 | ||||
|             // are we inside a mounted .AppImage? | ||||
|             var ix = ourPath.IndexOf("/usr/bin/", StringComparison.InvariantCultureIgnoreCase); | ||||
|             if (ix <= 0) { | ||||
|                 Log.Warn($"Unable to locate .AppImage root from '{ourPath}'. This warning indicates that the application is not running from a mounted .AppImage, for example during development."); | ||||
|                 logger.Warn( | ||||
|                     $"Unable to locate .AppImage root from '{ourPath}'. " + | ||||
|                     $"This warning indicates that the application is not running from a mounted .AppImage, for example during development."); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
| @@ -83,7 +89,7 @@ namespace Velopack.Locators | ||||
| 
 | ||||
|             if (!String.IsNullOrEmpty(AppImagePath) && File.Exists(AppImagePath)) { | ||||
|                 if (File.Exists(updateExe) && PackageManifest.TryParseFromFile(metadataPath, out var manifest)) { | ||||
|                     Log.Info("Located valid manifest file at: " + metadataPath); | ||||
|                     logger.Info("Located valid manifest file at: " + metadataPath); | ||||
|                     AppId = manifest.Id; | ||||
|                     RootAppDir = rootDir; | ||||
|                     AppContentDir = contentsDir; | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| using System; | ||||
| using System; | ||||
| using System.IO; | ||||
| using System.Runtime.Versioning; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using NuGet.Versioning; | ||||
| using Velopack.Logging; | ||||
| using Velopack.NuGet; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| @@ -36,6 +36,9 @@ namespace Velopack.Locators | ||||
|         /// <inheritdoc /> | ||||
|         public override string? PackagesDir => CreateSubDirIfDoesNotExist(CachesAppDir, "packages"); | ||||
| 
 | ||||
|         /// <inheritdoc /> | ||||
|         public override IVelopackLogger Log { get; } | ||||
| 
 | ||||
|         private string? CachesAppDir => CreateSubDirIfDoesNotExist(CachesVelopackDir, AppId); | ||||
|         private string? CachesVelopackDir => CreateSubDirIfDoesNotExist(CachesDir, "velopack"); | ||||
|         private string? CachesDir => CreateSubDirIfDoesNotExist(LibraryDir, "Caches"); | ||||
| @@ -55,8 +58,7 @@ namespace Velopack.Locators | ||||
|         /// Creates a new <see cref="OsxVelopackLocator"/> and auto-detects the | ||||
|         /// app information from metadata embedded in the .app. | ||||
|         /// </summary> | ||||
|         public OsxVelopackLocator(string currentProcessPath, uint currentProcessId, ILogger logger) | ||||
|             : base(logger) | ||||
|         public OsxVelopackLocator(string currentProcessPath, uint currentProcessId, IVelopackLogger? logger) | ||||
|         { | ||||
|             if (!VelopackRuntimeInfo.IsOSX) | ||||
|                 throw new NotSupportedException("Cannot instantiate OsxLocator on a non-osx system."); | ||||
| @@ -64,12 +66,16 @@ namespace Velopack.Locators | ||||
|             ProcessId = currentProcessId; | ||||
|             var ourPath = ProcessExePath = currentProcessPath; | ||||
| 
 | ||||
|             Log.Info($"Initialising {nameof(OsxVelopackLocator)}"); | ||||
|             var userLogDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Library", "Logs"); | ||||
|             var logPath = Directory.Exists(userLogDir) ? Path.Combine(userLogDir, "velopack.log") : "/tmp/velopack.log"; | ||||
|             logger ??= new FileVelopackLogger(logPath, currentProcessId); | ||||
|             logger.Info($"Initialising {nameof(OsxVelopackLocator)}"); | ||||
|             Log = logger; | ||||
| 
 | ||||
|             // are we inside a .app? | ||||
|             var ix = ourPath.IndexOf(".app/", StringComparison.InvariantCultureIgnoreCase); | ||||
|             if (ix <= 0) { | ||||
|                 Log.Warn($"Unable to locate .app root from '{ourPath}'"); | ||||
|                 logger.Warn($"Unable to locate .app root from '{ourPath}'"); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
| @@ -80,7 +86,7 @@ namespace Velopack.Locators | ||||
|             var metadataPath = Path.Combine(macosDir, CoreUtil.SpecVersionFileName); | ||||
| 
 | ||||
|             if (File.Exists(updateExe) && PackageManifest.TryParseFromFile(metadataPath, out var manifest)) { | ||||
|                 Log.Info("Located valid manifest file at: " + metadataPath); | ||||
|                 logger.Info("Located valid manifest file at: " + metadataPath); | ||||
|                 AppId = manifest.Id; | ||||
|                 RootAppDir = appPath; | ||||
|                 UpdateExePath = updateExe; | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| using System; | ||||
| using System; | ||||
| using System.Diagnostics.CodeAnalysis; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using NuGet.Versioning; | ||||
| using Velopack.Logging; | ||||
| 
 | ||||
| #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member | ||||
| 
 | ||||
| namespace Velopack.Locators | ||||
| @@ -19,6 +20,7 @@ namespace Velopack.Locators | ||||
|                 if (_id == null) { | ||||
|                     throw new NotSupportedException("AppId is not supported in this test implementation."); | ||||
|                 } | ||||
| 
 | ||||
|                 return _id; | ||||
|             } | ||||
|         } | ||||
| @@ -28,6 +30,7 @@ namespace Velopack.Locators | ||||
|                 if (_root == null) { | ||||
|                     throw new NotSupportedException("RootAppDir is not supported in this test implementation."); | ||||
|                 } | ||||
| 
 | ||||
|                 return _root; | ||||
|             } | ||||
|         } | ||||
| @@ -37,6 +40,7 @@ namespace Velopack.Locators | ||||
|                 if (_packages == null) { | ||||
|                     throw new NotSupportedException("PackagesDir is not supported in this test implementation."); | ||||
|                 } | ||||
| 
 | ||||
|                 return _packages; | ||||
|             } | ||||
|         } | ||||
| @@ -46,6 +50,7 @@ namespace Velopack.Locators | ||||
|                 if (_updatePath == null) { | ||||
|                     throw new NotSupportedException("UpdateExePath is not supported in this test implementation."); | ||||
|                 } | ||||
| 
 | ||||
|                 return _updatePath; | ||||
|             } | ||||
|         } | ||||
| @@ -55,6 +60,7 @@ namespace Velopack.Locators | ||||
|                 if (_version == null) { | ||||
|                     throw new NotSupportedException("CurrentlyInstalledVersion is not supported in this test implementation."); | ||||
|                 } | ||||
| 
 | ||||
|                 return _version; | ||||
|             } | ||||
|         } | ||||
| @@ -64,6 +70,7 @@ namespace Velopack.Locators | ||||
|                 if (_appContent == null) { | ||||
|                     throw new NotSupportedException("AppContentDir is not supported in this test implementation."); | ||||
|                 } | ||||
| 
 | ||||
|                 return _appContent; | ||||
|             } | ||||
|         } | ||||
| @@ -74,11 +81,14 @@ namespace Velopack.Locators | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public override IVelopackLogger Log { get; } | ||||
| 
 | ||||
|         public override VelopackAsset? GetLatestLocalFullPackage() | ||||
|         { | ||||
|             if (_asset != null) { | ||||
|                 return _asset; | ||||
|             } | ||||
| 
 | ||||
|             return base.GetLatestLocalFullPackage(); | ||||
|         } | ||||
| 
 | ||||
| @@ -96,15 +106,14 @@ namespace Velopack.Locators | ||||
|         private readonly VelopackAsset? _asset; | ||||
| 
 | ||||
|         /// <inheritdoc cref="TestVelopackLocator" /> | ||||
|         public TestVelopackLocator(string appId, string version, string packagesDir, ILogger? logger = null) | ||||
|         public TestVelopackLocator(string appId, string version, string packagesDir, IVelopackLogger? logger = null) | ||||
|             : this(appId, version, packagesDir, null, null, null, null, logger) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         /// <inheritdoc cref="TestVelopackLocator" /> | ||||
|         public TestVelopackLocator(string appId, string version, string packagesDir, string? appDir, | ||||
|             string? rootDir, string? updateExe, string? channel = null, ILogger? logger = null, VelopackAsset? localPackage = null, string processPath = null!) | ||||
|             : base(logger) | ||||
|             string? rootDir, string? updateExe, string? channel = null, IVelopackLogger? logger = null, VelopackAsset? localPackage = null, string processPath = null!) | ||||
|         { | ||||
|             _id = appId; | ||||
|             _packages = packagesDir; | ||||
| @@ -115,6 +124,7 @@ namespace Velopack.Locators | ||||
|             _channel = channel; | ||||
|             _asset = localPackage; | ||||
|             ProcessExePath = processPath; | ||||
|             Log = logger ?? new NullVelopackLogger(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,13 +1,11 @@ | ||||
| using System; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Diagnostics; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Microsoft.Extensions.Logging.Abstractions; | ||||
| using NuGet.Versioning; | ||||
| using Velopack.Util; | ||||
| using Velopack.Logging; | ||||
| 
 | ||||
| namespace Velopack.Locators | ||||
| { | ||||
| @@ -16,34 +14,57 @@ namespace Velopack.Locators | ||||
|     /// </summary> | ||||
|     public abstract class VelopackLocator : IVelopackLocator | ||||
|     { | ||||
|         private static VelopackLocator? _current; | ||||
|         private static IVelopackLocator? _current; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Auto-detect the platform from the current operating system. | ||||
|         /// Check if a VelopackLocator has been set for the current process. | ||||
|         /// </summary> | ||||
|         public static VelopackLocator GetDefault(ILogger? logger) | ||||
|         { | ||||
|             var log = logger ?? NullLogger.Instance; | ||||
|         public static bool IsCurrentSet => _current != null; | ||||
| 
 | ||||
|             if (_current != null) | ||||
|         /// <summary> | ||||
|         /// Get the current locator in use, this process-wide locator can be set/overriden during VelopackApp.Build(). | ||||
|         /// Alternatively, most methods which use locators also accept an IVelopackLocator as a parameter. | ||||
|         /// </summary> | ||||
|         public static IVelopackLocator Current { | ||||
|             get { | ||||
|                 if (_current == null) | ||||
|                     throw new InvalidOperationException( | ||||
|                         "No VelopackLocator has been set. Either call VelopackApp.Build() or provide IVelopackLocator as a method parameter."); | ||||
|                 return _current; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> Create a new default locator based on the current operating system. </summary> | ||||
|         public static IVelopackLocator CreateDefaultForPlatform(IVelopackLogger? logger = null) | ||||
|         { | ||||
|             var process = Process.GetCurrentProcess(); | ||||
|             var processExePath = process.MainModule?.FileName ?? throw new InvalidOperationException("Could not determine process path."); | ||||
|             var processId = (uint)process.Id; | ||||
|             var processExePath = process.MainModule?.FileName | ||||
|                                  ?? throw new InvalidOperationException("Could not determine process path, please construct IVelopackLocator manually."); | ||||
|             var processId = (uint) process.Id; | ||||
| 
 | ||||
|             if (VelopackRuntimeInfo.IsWindows) | ||||
|                 return _current = new WindowsVelopackLocator(processExePath, processId, log); | ||||
|                 return _current = new WindowsVelopackLocator(processExePath, processId, logger); | ||||
| 
 | ||||
|             if (VelopackRuntimeInfo.IsOSX) | ||||
|                 return _current = new OsxVelopackLocator(processExePath, processId, log); | ||||
|                 return _current = new OsxVelopackLocator(processExePath, processId, logger); | ||||
| 
 | ||||
|             if (VelopackRuntimeInfo.IsLinux) | ||||
|                 return _current = new LinuxVelopackLocator(processExePath, processId, log); | ||||
|                 return _current = new LinuxVelopackLocator(processExePath, processId, logger); | ||||
| 
 | ||||
|             throw new PlatformNotSupportedException($"OS platform '{VelopackRuntimeInfo.SystemOs.GetOsLongName()}' is not supported."); | ||||
|         } | ||||
| 
 | ||||
|         internal static void SetCurrentLocator(IVelopackLocator locator) | ||||
|         { | ||||
|             _current = locator; | ||||
|         } | ||||
| 
 | ||||
|         internal static IVelopackLocator GetCurrentOrCreateDefault(IVelopackLogger? logger = null) | ||||
|         { | ||||
|             _current ??= CreateDefaultForPlatform(logger); | ||||
|             return _current; | ||||
|         } | ||||
| 
 | ||||
|         /// <inheritdoc/> | ||||
|         public abstract string? AppId { get; } | ||||
| 
 | ||||
| @@ -65,6 +86,9 @@ namespace Velopack.Locators | ||||
|         /// <inheritdoc/> | ||||
|         public abstract string? Channel { get; } | ||||
| 
 | ||||
|         /// <inheritdoc/> | ||||
|         public abstract IVelopackLogger Log { get; } | ||||
| 
 | ||||
|         /// <inheritdoc/> | ||||
|         public abstract uint ProcessId { get; } | ||||
| 
 | ||||
| @@ -90,15 +114,6 @@ namespace Velopack.Locators | ||||
|         /// <inheritdoc/> | ||||
|         public abstract SemanticVersion? CurrentlyInstalledVersion { get; } | ||||
| 
 | ||||
|         /// <summary> The log interface to use for diagnostic messages. </summary> | ||||
|         protected ILogger Log { get; } | ||||
| 
 | ||||
|         /// <inheritdoc cref="VelopackLocator"/> | ||||
|         protected VelopackLocator(ILogger? logger) | ||||
|         { | ||||
|             Log = logger ?? NullLogger.Instance; | ||||
|         } | ||||
| 
 | ||||
|         /// <inheritdoc/> | ||||
|         public virtual List<VelopackAsset> GetLocalPackages() | ||||
|         { | ||||
| @@ -119,6 +134,7 @@ namespace Velopack.Locators | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 return list; | ||||
|             } catch (Exception ex) { | ||||
|                 Log.Error(ex, "Error while reading local packages."); | ||||
| @@ -131,8 +147,7 @@ namespace Velopack.Locators | ||||
|         { | ||||
|             return GetLocalPackages() | ||||
|                 .OrderByDescending(x => x.Version) | ||||
|                 .Where(a => a.Type == VelopackAssetType.Full) | ||||
|                 .FirstOrDefault(); | ||||
|                 .FirstOrDefault(a => a.Type == VelopackAssetType.Full); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
| @@ -161,6 +176,7 @@ namespace Velopack.Locators | ||||
|                     if (!Guid.TryParse(File.ReadAllText(stagedUserIdFile, Encoding.UTF8), out ret)) { | ||||
|                         throw new Exception("File was read but contents were invalid"); | ||||
|                     } | ||||
| 
 | ||||
|                     Log.Info($"Loaded existing staging userId: {ret}"); | ||||
|                     return ret; | ||||
|                 } catch (Exception ex) { | ||||
|   | ||||
| @@ -1,8 +1,9 @@ | ||||
| using System; | ||||
| using System; | ||||
| using System.Diagnostics; | ||||
| using System.IO; | ||||
| using System.Runtime.Versioning; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using NuGet.Versioning; | ||||
| using Velopack.Logging; | ||||
| using Velopack.NuGet; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| @@ -32,6 +33,9 @@ namespace Velopack.Locators | ||||
|         /// <inheritdoc /> | ||||
|         public override string? PackagesDir => CreateSubDirIfDoesNotExist(RootAppDir, "packages"); | ||||
| 
 | ||||
|         /// <inheritdoc /> | ||||
|         public override IVelopackLogger Log { get; } | ||||
| 
 | ||||
|         /// <inheritdoc /> | ||||
|         public override bool IsPortable => RootAppDir != null && File.Exists(Path.Combine(RootAppDir, ".portable")); | ||||
| 
 | ||||
| @@ -45,8 +49,7 @@ namespace Velopack.Locators | ||||
|         public override string ProcessExePath { get; } | ||||
| 
 | ||||
|         /// <inheritdoc cref="WindowsVelopackLocator" /> | ||||
|         public WindowsVelopackLocator(string currentProcessPath, uint currentProcessId, ILogger logger) | ||||
|             : base(logger) | ||||
|         public WindowsVelopackLocator(string currentProcessPath, uint currentProcessId, IVelopackLogger? logger) | ||||
|         { | ||||
|             if (!VelopackRuntimeInfo.IsWindows) | ||||
|                 throw new NotSupportedException("Cannot instantiate WindowsLocator on a non-Windows system."); | ||||
| @@ -66,29 +69,31 @@ namespace Velopack.Locators | ||||
|             var possibleUpdateExe = Path.GetFullPath(Path.Combine(myDirPath, "..", "Update.exe")); | ||||
|             var ixCurrent = ourPath.LastIndexOf("/current/", StringComparison.InvariantCultureIgnoreCase); | ||||
| 
 | ||||
|             Log.Info($"Initializing {nameof(WindowsVelopackLocator)}"); | ||||
| 
 | ||||
|             if (File.Exists(possibleUpdateExe)) { | ||||
|                 Log.Info("Update.exe found in parent directory"); | ||||
|                 // we're running in a directory with an Update.exe in the parent directory | ||||
|                 var manifestFile = Path.Combine(myDirPath, CoreUtil.SpecVersionFileName); | ||||
|                 var rootDir = Path.GetDirectoryName(possibleUpdateExe)!; | ||||
|                 logger ??= new FileVelopackLogger(Path.Combine(rootDir, "velopack.log"), currentProcessId); | ||||
|                 Log = logger; | ||||
|                 if (PackageManifest.TryParseFromFile(manifestFile, out var manifest)) { | ||||
|                     // ideal, the info we need is in a manifest file. | ||||
|                     Log.Info("Located valid manifest file at: " + manifestFile); | ||||
|                     logger.Info($"{nameof(WindowsVelopackLocator)}: Update.exe in parent dir, Located valid manifest file at: " + manifestFile); | ||||
|                     AppId = manifest.Id; | ||||
|                     CurrentlyInstalledVersion = manifest.Version; | ||||
|                     RootAppDir = Path.GetDirectoryName(possibleUpdateExe); | ||||
|                     RootAppDir = rootDir; | ||||
|                     UpdateExePath = possibleUpdateExe; | ||||
|                     AppContentDir = myDirPath; | ||||
|                     Channel = manifest.Channel; | ||||
|                 } else if (PathUtil.PathPartStartsWith(myDirName, "app-") && NuGetVersion.TryParse(myDirName.Substring(4), out var version)) { | ||||
|                     // this is a legacy case, where we're running in an 'root/app-*/' directory, and there is no manifest. | ||||
|                     Log.Warn("Legacy app-* directory detected, sq.version not found. Using directory name for AppId and Version."); | ||||
|                     logger.Warn("Update.exe in parent dir, Legacy app-* directory detected, sq.version not found. Using directory name for AppId and Version."); | ||||
|                     AppId = Path.GetFileName(Path.GetDirectoryName(possibleUpdateExe)); | ||||
|                     CurrentlyInstalledVersion = version; | ||||
|                     RootAppDir = Path.GetDirectoryName(possibleUpdateExe); | ||||
|                     RootAppDir = rootDir; | ||||
|                     UpdateExePath = possibleUpdateExe; | ||||
|                     AppContentDir = myDirPath; | ||||
|                 } else { | ||||
|                     logger.Error("Update.exe in parent dir, but unable to locate a valid manifest file at: " + manifestFile); | ||||
|                 } | ||||
|             } else if (ixCurrent > 0) { | ||||
|                 // this is an attempt to handle the case where we are running in a nested current directory. | ||||
| @@ -98,8 +103,10 @@ namespace Velopack.Locators | ||||
|                 possibleUpdateExe = Path.GetFullPath(Path.Combine(rootDir, "Update.exe")); | ||||
|                 // we only support parsing a manifest when we're in a nested current directory. no legacy fallback. | ||||
|                 if (File.Exists(possibleUpdateExe) && PackageManifest.TryParseFromFile(manifestFile, out var manifest)) { | ||||
|                     Log.Warn("Running in deeply nested directory. This is not an advised use-case."); | ||||
|                     Log.Info("Located valid manifest file at: " + manifestFile); | ||||
|                     logger ??= new FileVelopackLogger(Path.Combine(rootDir, "velopack.log"), currentProcessId); | ||||
|                     Log = logger; | ||||
|                     logger.Warn("Running in deeply nested directory. This is not an advised use-case."); | ||||
|                     logger.Info("Located valid manifest file at: " + manifestFile); | ||||
|                     RootAppDir = Path.GetDirectoryName(possibleUpdateExe); | ||||
|                     UpdateExePath = possibleUpdateExe; | ||||
|                     AppId = manifest.Id; | ||||
| @@ -108,6 +115,15 @@ namespace Velopack.Locators | ||||
|                     Channel = manifest.Channel; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             if (Log == null) { | ||||
|                 try { | ||||
|                     Log = new FileVelopackLogger(Path.Combine(AppContext.BaseDirectory, "velopack.log"), currentProcessId); | ||||
|                 } catch (Exception ex) { | ||||
|                     Debug.WriteLine("Error creating Velopack logger: " + ex); | ||||
|                     Log = new NullVelopackLogger(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										18
									
								
								src/lib-csharp/Logging/ConsoleVelopackLogger.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/lib-csharp/Logging/ConsoleVelopackLogger.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member | ||||
| using System; | ||||
| 
 | ||||
| namespace Velopack.Logging | ||||
| { | ||||
|     public class ConsoleVelopackLogger : IVelopackLogger | ||||
|     { | ||||
|         public void Log(VelopackLogLevel logLevel, string? message, Exception? exception) | ||||
|         { | ||||
|             var logMessage = $"[{DateTime.Now.ToShortTimeString()}] [{logLevel}] {message}"; | ||||
|             if (exception != null) { | ||||
|                 logMessage += Environment.NewLine + exception; | ||||
|             } | ||||
| 
 | ||||
|             Console.WriteLine(logMessage); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										51
									
								
								src/lib-csharp/Logging/FileVelopackLogger.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/lib-csharp/Logging/FileVelopackLogger.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member | ||||
| using System; | ||||
| using System.Diagnostics; | ||||
| using System.IO; | ||||
| 
 | ||||
| namespace Velopack.Logging | ||||
| { | ||||
|     public class FileVelopackLogger : IVelopackLogger, IDisposable | ||||
|     { | ||||
|         public uint ProcessId { get; } | ||||
|         private readonly object _lock = new(); | ||||
|         private readonly StreamWriter _writer; | ||||
|         private readonly FileStream _fileStream; | ||||
| 
 | ||||
|         public FileVelopackLogger(string filePath, uint processId) | ||||
|         { | ||||
|             ProcessId = processId; | ||||
|             _fileStream = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); | ||||
|             _writer = new StreamWriter(_fileStream); | ||||
|         } | ||||
| 
 | ||||
|         public void Log(VelopackLogLevel logLevel, string? message, Exception? exception) | ||||
|         { | ||||
|             try { | ||||
|                 lock (_lock) { | ||||
|                     var logMessage = $"[lib-csharp:{ProcessId}] [{DateTime.Now.ToShortTimeString()}] [{logLevel}] {message}"; | ||||
|                     if (exception != null) { | ||||
|                         logMessage += Environment.NewLine + exception; | ||||
|                     } | ||||
| 
 | ||||
|                     _writer.WriteLine(logMessage); | ||||
|                 } | ||||
|             } catch (Exception ex) { | ||||
|                 Debug.WriteLine($"Error writing to log file: {ex}"); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void Dispose() | ||||
|         { | ||||
|             try { | ||||
|                 lock (_lock) { | ||||
|                     _writer.Flush(); | ||||
|                     _writer.Dispose(); | ||||
|                     _fileStream.Dispose(); | ||||
|                 } | ||||
|             } catch (Exception ex) { | ||||
|                 Debug.WriteLine($"Error disposing log file: {ex}"); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										11
									
								
								src/lib-csharp/Logging/IVelopackLogger.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/lib-csharp/Logging/IVelopackLogger.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member | ||||
| 
 | ||||
| using System; | ||||
| 
 | ||||
| namespace Velopack.Logging | ||||
| { | ||||
|     public interface IVelopackLogger | ||||
|     { | ||||
|         void Log(VelopackLogLevel logLevel, string? message, Exception? exception); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										166
									
								
								src/lib-csharp/Logging/LoggingExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								src/lib-csharp/Logging/LoggingExtensions.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,166 @@ | ||||
| #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member | ||||
| 
 | ||||
| using System; | ||||
| using System.Diagnostics.CodeAnalysis; | ||||
| 
 | ||||
| namespace Velopack.Logging | ||||
| { | ||||
|     [ExcludeFromCodeCoverage] | ||||
|     public static class LoggerExtensions | ||||
|     { | ||||
|         public static void Log(this IVelopackLogger logger, VelopackLogLevel logLevel, string message) | ||||
|         { | ||||
|             logger.Log(logLevel, message, null); | ||||
|         } | ||||
| 
 | ||||
|         public static void LogTrace(this IVelopackLogger logger, string message) | ||||
|         { | ||||
|             logger.Log(VelopackLogLevel.Trace, message, null); | ||||
|         } | ||||
| 
 | ||||
|         public static void LogTrace(this IVelopackLogger logger, Exception ex, string message) | ||||
|         { | ||||
|             logger.Log(VelopackLogLevel.Trace, message, ex); | ||||
|         } | ||||
| 
 | ||||
|         public static void LogDebug(this IVelopackLogger logger, string message) | ||||
|         { | ||||
|             logger.Log(VelopackLogLevel.Debug, message, null); | ||||
|         } | ||||
| 
 | ||||
|         public static void LogDebug(this IVelopackLogger logger, Exception ex, string message) | ||||
|         { | ||||
|             logger.Log(VelopackLogLevel.Debug, message, ex); | ||||
|         } | ||||
| 
 | ||||
|         public static void LogInformation(this IVelopackLogger logger, string message) | ||||
|         { | ||||
|             logger.Log(VelopackLogLevel.Information, message, null); | ||||
|         } | ||||
| 
 | ||||
|         public static void LogInformation(this IVelopackLogger logger, Exception ex, string message) | ||||
|         { | ||||
|             logger.Log(VelopackLogLevel.Information, message, ex); | ||||
|         } | ||||
| 
 | ||||
|         public static void LogWarning(this IVelopackLogger logger, string message) | ||||
|         { | ||||
|             logger.Log(VelopackLogLevel.Warning, message, null); | ||||
|         } | ||||
| 
 | ||||
|         public static void LogWarning(this IVelopackLogger logger, Exception ex, string message) | ||||
|         { | ||||
|             logger.Log(VelopackLogLevel.Warning, message, ex); | ||||
|         } | ||||
| 
 | ||||
|         public static void LogError(this IVelopackLogger logger, string message) | ||||
|         { | ||||
|             logger.Log(VelopackLogLevel.Error, message, null); | ||||
|         } | ||||
| 
 | ||||
|         public static void LogError(this IVelopackLogger logger, Exception ex, string message) | ||||
|         { | ||||
|             logger.Log(VelopackLogLevel.Error, message, ex); | ||||
|         } | ||||
| 
 | ||||
|         public static void LogCritical(this IVelopackLogger logger, string message) | ||||
|         { | ||||
|             logger.Log(VelopackLogLevel.Critical, message, null); | ||||
|         } | ||||
| 
 | ||||
|         public static void LogCritical(this IVelopackLogger logger, Exception ex, string message) | ||||
|         { | ||||
|             logger.Log(VelopackLogLevel.Critical, message, ex); | ||||
|         } | ||||
| 
 | ||||
|         public static void Trace(this IVelopackLogger logger, string message) | ||||
|         { | ||||
|             logger.LogTrace(message); | ||||
|         } | ||||
| 
 | ||||
|         public static void Trace(this IVelopackLogger logger, Exception ex, string message) | ||||
|         { | ||||
|             logger.LogTrace(ex, message); | ||||
|         } | ||||
| 
 | ||||
|         public static void Trace(this IVelopackLogger logger, Exception ex) | ||||
|         { | ||||
|             logger.LogTrace(ex, ex.Message); | ||||
|         } | ||||
| 
 | ||||
|         public static void Debug(this IVelopackLogger logger, string message) | ||||
|         { | ||||
|             logger.LogDebug(message); | ||||
|         } | ||||
| 
 | ||||
|         public static void Debug(this IVelopackLogger logger, Exception ex, string message) | ||||
|         { | ||||
|             logger.LogDebug(ex, message); | ||||
|         } | ||||
| 
 | ||||
|         public static void Debug(this IVelopackLogger logger, Exception ex) | ||||
|         { | ||||
|             logger.LogDebug(ex, ex.Message); | ||||
|         } | ||||
| 
 | ||||
|         public static void Info(this IVelopackLogger logger, string message) | ||||
|         { | ||||
|             logger.LogInformation(message); | ||||
|         } | ||||
| 
 | ||||
|         public static void Info(this IVelopackLogger logger, Exception ex, string message) | ||||
|         { | ||||
|             logger.LogInformation(ex, message); | ||||
|         } | ||||
| 
 | ||||
|         public static void Info(this IVelopackLogger logger, Exception ex) | ||||
|         { | ||||
|             logger.LogInformation(ex, ex.Message); | ||||
|         } | ||||
| 
 | ||||
|         public static void Warn(this IVelopackLogger logger, string message) | ||||
|         { | ||||
|             logger.LogWarning(message); | ||||
|         } | ||||
| 
 | ||||
|         public static void Warn(this IVelopackLogger logger, Exception ex, string message) | ||||
|         { | ||||
|             logger.LogWarning(ex, message); | ||||
|         } | ||||
| 
 | ||||
|         public static void Warn(this IVelopackLogger logger, Exception ex) | ||||
|         { | ||||
|             logger.LogWarning(ex, ex.Message); | ||||
|         } | ||||
| 
 | ||||
|         public static void Error(this IVelopackLogger logger, string message) | ||||
|         { | ||||
|             logger.LogError(message); | ||||
|         } | ||||
| 
 | ||||
|         public static void Error(this IVelopackLogger logger, Exception ex, string message) | ||||
|         { | ||||
|             logger.LogError(ex, message); | ||||
|         } | ||||
| 
 | ||||
|         public static void Error(this IVelopackLogger logger, Exception ex) | ||||
|         { | ||||
|             logger.LogError(ex, ex.Message); | ||||
|         } | ||||
| 
 | ||||
|         public static void Fatal(this IVelopackLogger logger, string message) | ||||
|         { | ||||
|             logger.LogCritical(message); | ||||
|         } | ||||
| 
 | ||||
|         public static void Fatal(this IVelopackLogger logger, Exception ex, string message) | ||||
|         { | ||||
|             logger.LogCritical(ex, message); | ||||
|         } | ||||
| 
 | ||||
|         public static void Fatal(this IVelopackLogger logger, Exception ex) | ||||
|         { | ||||
|             logger.LogCritical(ex, ex.Message); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										15
									
								
								src/lib-csharp/Logging/NullVelopackLogger.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/lib-csharp/Logging/NullVelopackLogger.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member | ||||
| using System; | ||||
| 
 | ||||
| namespace Velopack.Logging | ||||
| { | ||||
|     public class NullVelopackLogger : IVelopackLogger | ||||
|     { | ||||
|         public static readonly NullVelopackLogger Instance = new(); | ||||
| 
 | ||||
|         public void Log(VelopackLogLevel logLevel, string? message, Exception? exception) | ||||
|         { | ||||
|             // Do nothing | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										14
									
								
								src/lib-csharp/Logging/VelopackLogLevel.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/lib-csharp/Logging/VelopackLogLevel.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member | ||||
| 
 | ||||
| namespace Velopack.Logging | ||||
| { | ||||
|     public enum VelopackLogLevel | ||||
|     { | ||||
|         Trace = 0, | ||||
|         Debug = 1, | ||||
|         Information = 2, | ||||
|         Warning = 3, | ||||
|         Error = 4, | ||||
|         Critical = 5, | ||||
|     } | ||||
| } | ||||
| @@ -3,7 +3,7 @@ using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Threading; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Velopack.Logging; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| namespace Velopack.Sources | ||||
| @@ -49,7 +49,7 @@ namespace Velopack.Sources | ||||
|         } | ||||
| 
 | ||||
|         /// <inheritdoc /> | ||||
|         public virtual Task DownloadReleaseEntry(ILogger logger, VelopackAsset releaseEntry, string localFile, Action<int> progress, CancellationToken cancelToken) | ||||
|         public virtual Task DownloadReleaseEntry(IVelopackLogger logger, VelopackAsset releaseEntry, string localFile, Action<int> progress, CancellationToken cancelToken) | ||||
|         { | ||||
|             if (releaseEntry is GitBaseAsset githubEntry) { | ||||
|                 // this might be a browser url or an api url (depending on whether we have a AccessToken or not) | ||||
| @@ -62,7 +62,8 @@ namespace Velopack.Sources | ||||
|         } | ||||
| 
 | ||||
|         /// <inheritdoc /> | ||||
|         public virtual async Task<VelopackAssetFeed> GetReleaseFeed(ILogger logger, string channel, Guid? stagingId = null, VelopackAsset? latestLocalRelease = null) | ||||
|         public virtual async Task<VelopackAssetFeed> GetReleaseFeed(IVelopackLogger logger, string? appId, string channel, Guid? stagingId = null, | ||||
|             VelopackAsset? latestLocalRelease = null) | ||||
|         { | ||||
|             var releases = await GetReleases(Prerelease).ConfigureAwait(false); | ||||
|             if (releases == null || releases.Length == 0) { | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| using System; | ||||
| using System.Threading; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Velopack.Logging; | ||||
| 
 | ||||
| namespace Velopack.Sources | ||||
| { | ||||
| @@ -14,21 +14,22 @@ namespace Velopack.Sources | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Retrieve the list of available remote releases from the package source. These releases | ||||
|         /// can subsequently be downloaded with <see cref="DownloadReleaseEntry(ILogger, VelopackAsset, string, Action{int}, CancellationToken)"/>. | ||||
|         /// can subsequently be downloaded with <see cref="DownloadReleaseEntry(IVelopackLogger, VelopackAsset, string, Action{int}, CancellationToken)"/>. | ||||
|         /// </summary> | ||||
|         /// <param name="channel">Release channel to filter packages by. Can be null, which is the  | ||||
|         /// default channel for this operating system.</param> | ||||
|         /// <param name="stagingId">A persistent user-id, used for calculating whether a specific | ||||
|         /// release should be available to this user or not. (eg, for the purposes of rolling out | ||||
|         /// an update to only a small portion of users at a time).</param> | ||||
|         /// <param name="latestLocalRelease">The latest / current local release. If specified, | ||||
|         /// metadata from this package may be provided to the remote server (such as package id, | ||||
|         /// or cpu architecture) to ensure that the correct package is downloaded for this user. | ||||
|         /// </param> | ||||
|         /// <param name="logger">The logger to use for any diagnostic messages.</param> | ||||
|         /// <param name="appId"></param> | ||||
|         /// <param name="channel">Release channel to filter packages by. Can be null, which is the  | ||||
|         ///     default channel for this operating system.</param> | ||||
|         /// <param name="stagingId">A persistent user-id, used for calculating whether a specific | ||||
|         ///     release should be available to this user or not. (eg, for the purposes of rolling out | ||||
|         ///     an update to only a small portion of users at a time).</param> | ||||
|         /// <param name="latestLocalRelease">The latest / current local release. If specified, | ||||
|         ///     metadata from this package may be provided to the remote server (such as package id, | ||||
|         ///     or cpu architecture) to ensure that the correct package is downloaded for this user. | ||||
|         /// </param> | ||||
|         /// <returns>An array of <see cref="ReleaseEntry"/> objects that are available for download | ||||
|         /// and are applicable to this user.</returns> | ||||
|         Task<VelopackAssetFeed> GetReleaseFeed(ILogger logger, string channel, Guid? stagingId = null, VelopackAsset? latestLocalRelease = null); | ||||
|         Task<VelopackAssetFeed> GetReleaseFeed(IVelopackLogger logger, string? appId, string channel, Guid? stagingId = null, VelopackAsset? latestLocalRelease = null); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Download the specified <see cref="VelopackAsset"/> to the provided local file path. | ||||
| @@ -40,6 +41,6 @@ namespace Velopack.Sources | ||||
|         /// download is being processed.</param> | ||||
|         /// <param name="logger">The logger to use for any diagnostic messages.</param> | ||||
|         /// <param name="cancelToken">A token to use to cancel the request.</param> | ||||
|         Task DownloadReleaseEntry(ILogger logger, VelopackAsset releaseEntry, string localFile, Action<int> progress, CancellationToken cancelToken = default); | ||||
|         Task DownloadReleaseEntry(IVelopackLogger logger, VelopackAsset releaseEntry, string localFile, Action<int> progress, CancellationToken cancelToken = default); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -3,7 +3,7 @@ using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Threading; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Velopack.Logging; | ||||
| using Velopack.NuGet; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| @@ -25,7 +25,8 @@ namespace Velopack.Sources | ||||
|         } | ||||
| 
 | ||||
|         /// <inheritdoc /> | ||||
|         public virtual Task<VelopackAssetFeed> GetReleaseFeed(ILogger logger, string channel, Guid? stagingId = null, VelopackAsset? latestLocalRelease = null) | ||||
|         public virtual Task<VelopackAssetFeed> GetReleaseFeed(IVelopackLogger logger, string? appId, string channel, Guid? stagingId = null, | ||||
|             VelopackAsset? latestLocalRelease = null) | ||||
|         { | ||||
|             if (!BaseDirectory.Exists) { | ||||
|                 logger.Error($"The local update directory '{BaseDirectory.FullName}' does not exist."); | ||||
| @@ -65,7 +66,7 @@ namespace Velopack.Sources | ||||
|         } | ||||
| 
 | ||||
|         /// <inheritdoc /> | ||||
|         public virtual Task DownloadReleaseEntry(ILogger logger, VelopackAsset releaseEntry, string localFile, Action<int> progress, CancellationToken cancelToken) | ||||
|         public virtual Task DownloadReleaseEntry(IVelopackLogger logger, VelopackAsset releaseEntry, string localFile, Action<int> progress, CancellationToken cancelToken) | ||||
|         { | ||||
|             var releasePath = Path.Combine(BaseDirectory.FullName, releaseEntry.FileName); | ||||
|             if (!File.Exists(releasePath)) | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| using System.Collections.Generic; | ||||
| using System.Threading; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Velopack.Logging; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| namespace Velopack.Sources | ||||
| @@ -37,7 +37,8 @@ namespace Velopack.Sources | ||||
|         } | ||||
| 
 | ||||
|         /// <inheritdoc /> | ||||
|         public async virtual Task<VelopackAssetFeed> GetReleaseFeed(ILogger logger, string channel, Guid? stagingId = null, VelopackAsset? latestLocalRelease = null) | ||||
|         public async virtual Task<VelopackAssetFeed> GetReleaseFeed(IVelopackLogger logger, string? appId, string channel, Guid? stagingId = null, | ||||
|             VelopackAsset? latestLocalRelease = null) | ||||
|         { | ||||
|             var releaseFilename = CoreUtil.GetVeloReleaseIndexName(channel); | ||||
|             var uri = HttpUtil.AppendPathToUri(BaseUri, releaseFilename); | ||||
| @@ -66,7 +67,7 @@ namespace Velopack.Sources | ||||
|         } | ||||
| 
 | ||||
|         /// <inheritdoc /> | ||||
|         public async virtual Task DownloadReleaseEntry(ILogger logger, VelopackAsset releaseEntry, string localFile, Action<int> progress, CancellationToken cancelToken) | ||||
|         public async virtual Task DownloadReleaseEntry(IVelopackLogger logger, VelopackAsset releaseEntry, string localFile, Action<int> progress, CancellationToken cancelToken) | ||||
|         { | ||||
|             if (releaseEntry == null) throw new ArgumentNullException(nameof(releaseEntry)); | ||||
|             if (localFile == null) throw new ArgumentNullException(nameof(localFile)); | ||||
|   | ||||
| @@ -1,20 +1,20 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Threading; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Velopack.Util; | ||||
| using Velopack.Locators; | ||||
| using Velopack.Logging; | ||||
| 
 | ||||
| namespace Velopack.Sources | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Retrieves updates from the hosted Velopack service. | ||||
|     /// </summary> | ||||
|     public sealed class VelopackFlowUpdateSource : IUpdateSource | ||||
|     public sealed class VelopackFlowSource : IUpdateSource | ||||
|     { | ||||
|         /// <inheritdoc cref="SimpleWebSource" /> | ||||
|         public VelopackFlowUpdateSource( | ||||
|         public VelopackFlowSource( | ||||
|             string baseUri = "https://api.velopack.io/", | ||||
|             IFileDownloader? downloader = null) | ||||
|         { | ||||
| @@ -29,17 +29,13 @@ namespace Velopack.Sources | ||||
|         public IFileDownloader Downloader { get; } | ||||
| 
 | ||||
|         /// <inheritdoc /> | ||||
|         public async Task<VelopackAssetFeed> GetReleaseFeed(ILogger logger, string channel, Guid? stagingId = null, | ||||
|         public async Task<VelopackAssetFeed> GetReleaseFeed(IVelopackLogger logger, string? appId, string channel, Guid? stagingId = null, | ||||
|             VelopackAsset? latestLocalRelease = null) | ||||
|         { | ||||
|             string? packageId = latestLocalRelease?.PackageId ?? VelopackLocator.GetDefault(logger).AppId; | ||||
|             if (string.IsNullOrWhiteSpace(packageId)) { | ||||
|                 //Without a package id, we can't get a feed. | ||||
|                 return new VelopackAssetFeed(); | ||||
|             } | ||||
|             if (appId is null) return new VelopackAssetFeed(); // without an appId, we can't get any releases. | ||||
| 
 | ||||
|             Uri baseUri = new(BaseUri, $"v1.0/manifest/"); | ||||
|             Uri uri = HttpUtil.AppendPathToUri(baseUri, $"{packageId}/{channel}"); | ||||
|             Uri uri = HttpUtil.AppendPathToUri(baseUri, $"{appId}/{channel}"); | ||||
|             var args = new Dictionary<string, string>(); | ||||
| 
 | ||||
|             if (VelopackRuntimeInfo.SystemArch != RuntimeCpu.Unknown) { | ||||
| @@ -61,30 +57,37 @@ namespace Velopack.Sources | ||||
| 
 | ||||
|             var uriAndQuery = HttpUtil.AddQueryParamsToUri(uri, args); | ||||
| 
 | ||||
|             logger.LogInformation("Downloading releases from '{Uri}'.", uriAndQuery); | ||||
|             logger.LogInformation($"Downloading releases from '{uriAndQuery}'."); | ||||
| 
 | ||||
|             var json = await Downloader.DownloadString(uriAndQuery.ToString()).ConfigureAwait(false); | ||||
| 
 | ||||
|             var releaseAssets = CompiledJson.DeserializeVelopackFlowAssetArray(json); | ||||
|             if (releaseAssets is null) { | ||||
|                 return new VelopackAssetFeed(); | ||||
|             } | ||||
| 
 | ||||
|             return new VelopackAssetFeed() { | ||||
|                 Assets = releaseAssets | ||||
|                 Assets = releaseAssets.Cast<VelopackAsset>().ToArray() | ||||
|             }; | ||||
|         } | ||||
| 
 | ||||
|         /// <inheritdoc /> | ||||
|         public async Task DownloadReleaseEntry(ILogger logger, VelopackAsset releaseEntry, string localFile, Action<int> progress, CancellationToken cancelToken = default) | ||||
|         public async Task DownloadReleaseEntry(IVelopackLogger logger, VelopackAsset releaseEntry, string localFile, Action<int> progress, | ||||
|             CancellationToken cancelToken = default) | ||||
|         { | ||||
|             if (releaseEntry is null) throw new ArgumentNullException(nameof(releaseEntry)); | ||||
|             if (releaseEntry is not VelopackFlowReleaseAsset velopackRelease) { | ||||
|                 throw new ArgumentException($"Expected {nameof(releaseEntry)} to be {nameof(VelopackFlowReleaseAsset)} but was {releaseEntry.GetType().FullName}"); | ||||
|                 throw new ArgumentException( | ||||
|                     $"Expected {nameof(releaseEntry)} to be {nameof(VelopackFlowReleaseAsset)} but was {releaseEntry.GetType().FullName}"); | ||||
|             } | ||||
| 
 | ||||
|             if (localFile is null) throw new ArgumentNullException(nameof(localFile)); | ||||
| 
 | ||||
|             Uri sourceBaseUri = HttpUtil.EnsureTrailingSlash(BaseUri); | ||||
| 
 | ||||
|             Uri downloadUri = new(sourceBaseUri, $"v1.0/download/{velopackRelease.Id}"); | ||||
| 
 | ||||
|             logger.LogInformation("Downloading '{ReleaseFileName}' from '{Uri}'.", releaseEntry.FileName, downloadUri); | ||||
|             logger.LogInformation($"Downloading '{releaseEntry.FileName}' from '{downloadUri}'."); | ||||
|             await Downloader.DownloadFile(downloadUri.AbsoluteUri, localFile, progress, cancelToken: cancelToken).ConfigureAwait(false); | ||||
|         } | ||||
|     } | ||||
| @@ -1,4 +1,4 @@ | ||||
| using System; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.ComponentModel; | ||||
| using System.Diagnostics; | ||||
| @@ -6,9 +6,8 @@ using System.IO; | ||||
| using System.Runtime.InteropServices; | ||||
| using System.Threading; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Microsoft.Extensions.Logging.Abstractions; | ||||
| using Velopack.Locators; | ||||
| using Velopack.Logging; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| namespace Velopack | ||||
| @@ -24,7 +23,7 @@ namespace Velopack | ||||
|         [return: MarshalAs(UnmanagedType.Bool)] | ||||
|         private static extern bool AllowSetForegroundWindow(int dwProcessId); | ||||
| 
 | ||||
|         private static Process StartUpdateExe(ILogger logger, IVelopackLocator locator, IEnumerable<string> args) | ||||
|         private static Process StartUpdateExe(IVelopackLogger logger, IVelopackLocator locator, IEnumerable<string> args) | ||||
|         { | ||||
|             var psi = new ProcessStartInfo() { | ||||
|                 CreateNoWindow = true, | ||||
| @@ -61,11 +60,9 @@ namespace Velopack | ||||
|         /// <param name="waitPid">Optionally wait for the specified process to exit before continuing.</param> | ||||
|         /// <param name="locator">The locator to use to find the path to Update.exe and the packages directory.</param> | ||||
|         /// <param name="startArgs">The arguments to pass to the application when it is restarted.</param> | ||||
|         /// <param name="logger">The logger to use for diagnostic messages</param> | ||||
|         public static void Start(IVelopackLocator? locator = null, uint waitPid = 0, string[]? startArgs = null, ILogger? logger = null) | ||||
|         public static void Start(IVelopackLocator? locator = null, uint waitPid = 0, string[]? startArgs = null) | ||||
|         { | ||||
|             logger ??= NullLogger.Instance; | ||||
|             locator ??= VelopackLocator.GetDefault(logger); | ||||
|             locator ??= VelopackLocator.Current; | ||||
| 
 | ||||
|             var args = new List<string>(); | ||||
|             args.Add("start"); | ||||
| @@ -82,14 +79,13 @@ namespace Velopack | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             StartUpdateExe(logger, locator, args); | ||||
|             StartUpdateExe(locator.Log, locator, args); | ||||
|         } | ||||
| 
 | ||||
|         private static Process ApplyImpl(IVelopackLocator? locator, VelopackAsset? toApply, bool silent, uint waitPid, bool restart, | ||||
|             string[]? restartArgs = null, ILogger? logger = null) | ||||
|             string[]? restartArgs = null) | ||||
|         { | ||||
|             logger ??= NullLogger.Instance; | ||||
|             locator ??= VelopackLocator.GetDefault(logger); | ||||
|             locator ??= VelopackLocator.Current; | ||||
| 
 | ||||
|             var args = new List<string>(); | ||||
|             if (silent) args.Add("--silent"); | ||||
| @@ -118,7 +114,7 @@ namespace Velopack | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return StartUpdateExe(logger, locator, args); | ||||
|             return StartUpdateExe(locator.Log, locator, args); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
| @@ -132,12 +128,11 @@ namespace Velopack | ||||
|         /// <param name="toApply">The update package you wish to apply, can be left null.</param> | ||||
|         /// <param name="waitPid">Optionally wait for the specified process to exit before continuing.</param> | ||||
|         /// <param name="restartArgs">The arguments to pass to the application when it is restarted.</param> | ||||
|         /// <param name="logger">The logger to use for diagnostic messages</param> | ||||
|         /// <exception cref="Exception">Thrown if Update.exe does not initialize properly.</exception> | ||||
|         public static void Apply(IVelopackLocator? locator, VelopackAsset? toApply, bool silent, uint waitPid, bool restart, | ||||
|             string[]? restartArgs = null, ILogger? logger = null) | ||||
|             string[]? restartArgs = null) | ||||
|         { | ||||
|             var process = ApplyImpl(locator, toApply, silent, waitPid, restart, restartArgs, logger); | ||||
|             var process = ApplyImpl(locator, toApply, silent, waitPid, restart, restartArgs); | ||||
|             Thread.Sleep(500); | ||||
| 
 | ||||
|             if (process.HasExited) { | ||||
| @@ -146,10 +141,10 @@ namespace Velopack | ||||
|         } | ||||
| 
 | ||||
|         /// <inheritdoc cref="Apply"/> | ||||
|         public static async Task ApplyAsync(IVelopackLocator? locator, VelopackAsset? toApply, bool silent, uint waitPid, bool restart, string[]? restartArgs = null, | ||||
|             ILogger? logger = null) | ||||
|         public static async Task ApplyAsync(IVelopackLocator? locator, VelopackAsset? toApply, bool silent, uint waitPid, bool restart, | ||||
|             string[]? restartArgs = null) | ||||
|         { | ||||
|             var process = ApplyImpl(locator, toApply, silent, waitPid, restart, restartArgs, logger); | ||||
|             var process = ApplyImpl(locator, toApply, silent, waitPid, restart, restartArgs); | ||||
|             await Task.Delay(500).ConfigureAwait(false); | ||||
| 
 | ||||
|             if (process.HasExited) { | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| using System; | ||||
| using System; | ||||
| using System.ComponentModel; | ||||
| using System.Threading.Tasks; | ||||
| 
 | ||||
| @@ -45,13 +45,13 @@ namespace Velopack | ||||
|         /// <param name="restartArgs">The arguments to pass to the application when it is restarted.</param> | ||||
|         public void WaitExitThenApplyUpdates(VelopackAsset? toApply, bool silent = false, bool restart = true, string[]? restartArgs = null) | ||||
|         { | ||||
|             UpdateExe.Apply(Locator, toApply, silent, Locator.ProcessId, restart, restartArgs, Log); | ||||
|             UpdateExe.Apply(Locator, toApply, silent, Locator.ProcessId, restart, restartArgs); | ||||
|         } | ||||
|          | ||||
|         /// <inheritdoc cref="WaitExitThenApplyUpdates"/> | ||||
|         public async Task WaitExitThenApplyUpdatesAsync(VelopackAsset? toApply, bool silent = false, bool restart = true, string[]? restartArgs = null) | ||||
|         { | ||||
|             await UpdateExe.ApplyAsync(Locator, toApply, silent, Locator.ProcessId, restart, restartArgs, Log).ConfigureAwait(false); | ||||
|             await UpdateExe.ApplyAsync(Locator, toApply, silent, Locator.ProcessId, restart, restartArgs).ConfigureAwait(false); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,15 +1,14 @@ | ||||
| using System; | ||||
| using System; | ||||
| using System.ComponentModel; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Threading; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Microsoft.Extensions.Logging.Abstractions; | ||||
| using NuGet.Versioning; | ||||
| using Velopack.Compression; | ||||
| using Velopack.Exceptions; | ||||
| using Velopack.Locators; | ||||
| using Velopack.Logging; | ||||
| using Velopack.NuGet; | ||||
| using Velopack.Sources; | ||||
| using Velopack.Util; | ||||
| @@ -52,7 +51,7 @@ namespace Velopack | ||||
|         protected IUpdateSource Source { get; } | ||||
| 
 | ||||
|         /// <summary> The logger to use for diagnostic messages. </summary> | ||||
|         protected ILogger Log { get; } | ||||
|         protected IVelopackLogger Log { get; } | ||||
| 
 | ||||
|         /// <summary> The locator to use when searching for local file paths. </summary> | ||||
|         protected IVelopackLocator Locator { get; } | ||||
| @@ -74,12 +73,10 @@ namespace Velopack | ||||
|         /// </summary> | ||||
|         /// <param name="urlOrPath">A basic URL or file path to use when checking for updates.</param> | ||||
|         /// <param name="options">Override / configure default update behaviors.</param> | ||||
|         /// <param name="logger">The logger to use for diagnostic messages. If one was provided to <see cref="VelopackApp.Run(ILogger)"/> but is null here,  | ||||
|         /// it will be cached and used again.</param> | ||||
|         /// <param name="locator">This should usually be left null. Providing an <see cref="IVelopackLocator" /> allows you to mock up certain application paths.  | ||||
|         /// For example, if you wanted to test that updates are working in a unit test, you could provide an instance of <see cref="TestVelopackLocator"/>. </param> | ||||
|         public UpdateManager(string urlOrPath, UpdateOptions? options = null, ILogger? logger = null, IVelopackLocator? locator = null) | ||||
|             : this(CreateSimpleSource(urlOrPath), options, logger, locator) | ||||
|         public UpdateManager(string urlOrPath, UpdateOptions? options = null, IVelopackLocator? locator = null) | ||||
|             : this(CreateSimpleSource(urlOrPath), options, locator) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
| @@ -89,19 +86,13 @@ namespace Velopack | ||||
|         /// <param name="source">The source describing where to search for updates. This can be a custom source, if you are integrating with some private resource, | ||||
|         /// or it could be one of the predefined sources. (eg. <see cref="SimpleWebSource"/> or <see cref="GithubSource"/>, etc).</param> | ||||
|         /// <param name="options">Override / configure default update behaviors.</param> | ||||
|         /// <param name="logger">The logger to use for diagnostic messages. If one was provided to <see cref="VelopackApp.Run(ILogger)"/> but is null here,  | ||||
|         /// it will be cached and used again.</param> | ||||
|         /// <param name="locator">This should usually be left null. Providing an <see cref="IVelopackLocator" /> allows you to mock up certain application paths.  | ||||
|         /// For example, if you wanted to test that updates are working in a unit test, you could provide an instance of <see cref="TestVelopackLocator"/>. </param> | ||||
|         public UpdateManager(IUpdateSource source, UpdateOptions? options = null, ILogger? logger = null, IVelopackLocator? locator = null) | ||||
|         public UpdateManager(IUpdateSource source, UpdateOptions? options = null, IVelopackLocator? locator = null) | ||||
|         { | ||||
|             if (source == null) { | ||||
|                 throw new ArgumentNullException(nameof(source)); | ||||
|             } | ||||
| 
 | ||||
|             Source = source; | ||||
|             Log = logger ?? VelopackApp.DefaultLogger ?? NullLogger.Instance; | ||||
|             Locator = locator ?? VelopackApp.DefaultLocator ?? VelopackLocator.GetDefault(Log); | ||||
|             Source = source ?? throw new ArgumentNullException(nameof(source)); | ||||
|             Locator = locator ?? VelopackLocator.Current; | ||||
|             Log = Locator.Log; | ||||
|             Channel = options?.ExplicitChannel ?? DefaultChannel; | ||||
|             ShouldAllowVersionDowngrade = options?.AllowVersionDowngrade ?? false; | ||||
|         } | ||||
| @@ -126,7 +117,7 @@ namespace Velopack | ||||
|             var latestLocalFull = Locator.GetLatestLocalFullPackage(); | ||||
| 
 | ||||
|             Log.Debug("Retrieving latest release feed."); | ||||
|             var feedObj = await Source.GetReleaseFeed(Log, Channel, stagedUserId, latestLocalFull).ConfigureAwait(false); | ||||
|             var feedObj = await Source.GetReleaseFeed(Log, AppId, Channel, stagedUserId, latestLocalFull).ConfigureAwait(false); | ||||
|             var feed = feedObj.Assets; | ||||
| 
 | ||||
|             var latestRemoteFull = feed.Where(r => r.Type == VelopackAssetType.Full).MaxByPolyfill(x => x.Version).FirstOrDefault(); | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| using System; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Diagnostics; | ||||
| using System.IO; | ||||
| @@ -6,8 +6,7 @@ using System.Linq; | ||||
| using System.Security.Cryptography; | ||||
| using System.Threading; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Microsoft.Extensions.Logging.Abstractions; | ||||
| using Velopack.Logging; | ||||
| 
 | ||||
| namespace Velopack.Util | ||||
| { | ||||
| @@ -73,9 +72,9 @@ namespace Velopack.Util | ||||
|         /// <param name="renameFirst">Try to rename this object first before deleting. Can help prevent partial delete of folders.</param> | ||||
|         /// <param name="logger">Logger for diagnostic messages.</param> | ||||
|         /// <returns>True if the file system object was deleted, false otherwise.</returns> | ||||
|         public static bool DeleteFileOrDirectoryHard(string path, bool throwOnFailure = true, bool renameFirst = false, ILogger? logger = null) | ||||
|         public static bool DeleteFileOrDirectoryHard(string path, bool throwOnFailure = true, bool renameFirst = false, IVelopackLogger? logger = null) | ||||
|         { | ||||
|             logger ??= NullLogger.Instance; | ||||
|             logger ??= NullVelopackLogger.Instance; | ||||
|             logger.Debug($"Starting to delete: {path}"); | ||||
| 
 | ||||
|             string? currentExePath = null; | ||||
| @@ -111,7 +110,7 @@ namespace Velopack.Util | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private static void DeleteFsiTree(FileSystemInfo fileSystemInfo, string? currentExePath, ILogger logger) | ||||
|         private static void DeleteFsiTree(FileSystemInfo fileSystemInfo, string? currentExePath, IVelopackLogger logger) | ||||
|         { | ||||
|             // if junction / symlink, don't iterate, just delete it. | ||||
|             if (fileSystemInfo.Attributes.HasFlag(FileAttributes.ReparsePoint)) { | ||||
| @@ -135,7 +134,7 @@ namespace Velopack.Util | ||||
|             DeleteFsiVeryHard(fileSystemInfo, currentExePath, logger); | ||||
|         } | ||||
| 
 | ||||
|         private static void DeleteFsiVeryHard(FileSystemInfo fileSystemInfo, string? currentExePath, ILogger logger) | ||||
|         private static void DeleteFsiVeryHard(FileSystemInfo fileSystemInfo, string? currentExePath, IVelopackLogger logger) | ||||
|         { | ||||
|             // don't try to delete the running process | ||||
|             if (currentExePath != null && PathUtil.FullPathEquals(fileSystemInfo.FullName, currentExePath)) { | ||||
| @@ -171,7 +170,7 @@ namespace Velopack.Util | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public static void Retry(this Action block, int retries = 4, int retryDelay = 250, ILogger? logger = null) | ||||
|         public static void Retry(this Action block, int retries = 4, int retryDelay = 250, IVelopackLogger? logger = null) | ||||
|         { | ||||
|             Retry( | ||||
|                 () => { | ||||
| @@ -183,7 +182,7 @@ namespace Velopack.Util | ||||
|                 logger); | ||||
|         } | ||||
| 
 | ||||
|         public static T Retry<T>(this Func<T> block, int retries = 4, int retryDelay = 250, ILogger? logger = null) | ||||
|         public static T Retry<T>(this Func<T> block, int retries = 4, int retryDelay = 250, IVelopackLogger? logger = null) | ||||
|         { | ||||
|             while (true) { | ||||
|                 try { | ||||
| @@ -198,7 +197,7 @@ namespace Velopack.Util | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public static Task RetryAsync(this Func<Task> block, int retries = 4, int retryDelay = 250, ILogger? logger = null) | ||||
|         public static Task RetryAsync(this Func<Task> block, int retries = 4, int retryDelay = 250, IVelopackLogger? logger = null) | ||||
|         { | ||||
|             return RetryAsync( | ||||
|                 async () => { | ||||
| @@ -210,7 +209,7 @@ namespace Velopack.Util | ||||
|                 logger); | ||||
|         } | ||||
| 
 | ||||
|         public static async Task<T> RetryAsync<T>(this Func<Task<T>> block, int retries = 4, int retryDelay = 250, ILogger? logger = null) | ||||
|         public static async Task<T> RetryAsync<T>(this Func<Task<T>> block, int retries = 4, int retryDelay = 250, IVelopackLogger? logger = null) | ||||
|         { | ||||
|             while (true) { | ||||
|                 try { | ||||
|   | ||||
| @@ -6,7 +6,7 @@ using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Velopack.Logging; | ||||
| 
 | ||||
| namespace Velopack.Util | ||||
| { | ||||
| @@ -56,7 +56,7 @@ namespace Velopack.Util | ||||
|         } | ||||
| #endif | ||||
| 
 | ||||
|         public static Process StartRedirectOutputToILogger(this ProcessStartInfo psi, ILogger log, LogLevel outputLevel) | ||||
|         public static Process StartRedirectOutputToILogger(this ProcessStartInfo psi, IVelopackLogger log, VelopackLogLevel outputLevel) | ||||
|         { | ||||
|             psi.RedirectStandardOutput = true; | ||||
|             psi.RedirectStandardError = true; | ||||
|   | ||||
| @@ -24,26 +24,15 @@ | ||||
|     <Reference Include="System.IO.Compression" /> | ||||
|     <Reference Include="System.IO.Compression.FileSystem" /> | ||||
|     <PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> | ||||
|     <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="[2.2.0,)" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
|   <ItemGroup Condition=" $(TargetFramework.StartsWith('netstandard2')) "> | ||||
|     <PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> | ||||
|     <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="[2.2.0,)" /> | ||||
|     <PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
|   <ItemGroup Condition=" $(TargetFramework) == 'net6.0' "> | ||||
|     <PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> | ||||
|     <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="[6.0.0,)" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
|   <ItemGroup Condition=" $(TargetFramework) == 'net8.0' "> | ||||
|     <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="[8.0.0,)" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
|   <ItemGroup Condition=" $(TargetFramework) == 'net9.0' "> | ||||
|     <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="[9.0.0,)" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
| </Project> | ||||
|   | ||||
| @@ -1,12 +1,11 @@ | ||||
| using System; | ||||
| using System; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Runtime.InteropServices; | ||||
| using System.Runtime.Versioning; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Microsoft.Extensions.Logging.Abstractions; | ||||
| using NuGet.Versioning; | ||||
| using Velopack.Locators; | ||||
| using Velopack.Logging; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| namespace Velopack | ||||
| @@ -27,18 +26,15 @@ namespace Velopack | ||||
|         [DllImport("shell32.dll", SetLastError = true)] | ||||
|         private static extern void SetCurrentProcessExplicitAppUserModelID([MarshalAs(UnmanagedType.LPWStr)] string AppID); | ||||
| 
 | ||||
|         internal static ILogger DefaultLogger { get; private set; } = NullLogger.Instance; | ||||
| 
 | ||||
|         internal static IVelopackLocator? DefaultLocator { get; private set; } | ||||
| 
 | ||||
|         VelopackHook? _install; | ||||
|         VelopackHook? _update; | ||||
|         VelopackHook? _obsolete; | ||||
|         VelopackHook? _uninstall; | ||||
|         VelopackHook? _firstrun; | ||||
|         VelopackHook? _restarted; | ||||
|         string[]? _args; | ||||
|         bool _autoApply = true; | ||||
|         private VelopackHook? _install; | ||||
|         private VelopackHook? _update; | ||||
|         private VelopackHook? _obsolete; | ||||
|         private VelopackHook? _uninstall; | ||||
|         private VelopackHook? _firstrun; | ||||
|         private VelopackHook? _restarted; | ||||
|         private string[]? _args; | ||||
|         private bool _autoApply = true; | ||||
|         private IVelopackLocator? _customLocator; | ||||
| 
 | ||||
|         private VelopackApp() | ||||
|         { | ||||
| @@ -47,7 +43,7 @@ namespace Velopack | ||||
|         /// <summary> | ||||
|         /// Creates and returns a new Velopack application builder. | ||||
|         /// </summary> | ||||
|         public static VelopackApp Build() => new VelopackApp(); | ||||
|         public static VelopackApp Build() => new(); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Override the command line arguments used to determine the Velopack hook to run. | ||||
| @@ -74,14 +70,14 @@ namespace Velopack | ||||
|         /// </summary> | ||||
|         public VelopackApp SetLocator(IVelopackLocator locator) | ||||
|         { | ||||
|             DefaultLocator = locator; | ||||
|             _customLocator = locator; | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// This hook is triggered when the application is started for the first time after installation. | ||||
|         /// </summary> | ||||
|         public VelopackApp WithFirstRun(VelopackHook hook) | ||||
|         public VelopackApp OnFirstRun(VelopackHook hook) | ||||
|         { | ||||
|             _firstrun += hook; | ||||
|             return this; | ||||
| @@ -90,7 +86,7 @@ namespace Velopack | ||||
|         /// <summary> | ||||
|         /// This hook is triggered when the application is restarted by Velopack after installing updates. | ||||
|         /// </summary> | ||||
|         public VelopackApp WithRestarted(VelopackHook hook) | ||||
|         public VelopackApp OnRestarted(VelopackHook hook) | ||||
|         { | ||||
|             _restarted += hook; | ||||
|             return this; | ||||
| @@ -103,7 +99,7 @@ namespace Velopack | ||||
|         /// Only supported on windows; On other operating systems, this will never be called. | ||||
|         /// </summary> | ||||
|         [SupportedOSPlatform("windows")] | ||||
|         public VelopackApp WithAfterInstallFastCallback(VelopackHook hook) | ||||
|         public VelopackApp OnAfterInstallFastCallback(VelopackHook hook) | ||||
|         { | ||||
|             _install += hook; | ||||
|             return this; | ||||
| @@ -116,7 +112,7 @@ namespace Velopack | ||||
|         /// Only supported on windows; On other operating systems, this will never be called. | ||||
|         /// </summary> | ||||
|         [SupportedOSPlatform("windows")] | ||||
|         public VelopackApp WithAfterUpdateFastCallback(VelopackHook hook) | ||||
|         public VelopackApp OnAfterUpdateFastCallback(VelopackHook hook) | ||||
|         { | ||||
|             _update += hook; | ||||
|             return this; | ||||
| @@ -129,7 +125,7 @@ namespace Velopack | ||||
|         /// Only supported on windows; On other operating systems, this will never be called. | ||||
|         /// </summary> | ||||
|         [SupportedOSPlatform("windows")] | ||||
|         public VelopackApp WithBeforeUpdateFastCallback(VelopackHook hook) | ||||
|         public VelopackApp OnBeforeUpdateFastCallback(VelopackHook hook) | ||||
|         { | ||||
|             _obsolete += hook; | ||||
|             return this; | ||||
| @@ -142,7 +138,7 @@ namespace Velopack | ||||
|         /// Only supported on windows; On other operating systems, this will never be called. | ||||
|         /// </summary> | ||||
|         [SupportedOSPlatform("windows")] | ||||
|         public VelopackApp WithBeforeUninstallFastCallback(VelopackHook hook) | ||||
|         public VelopackApp OnBeforeUninstallFastCallback(VelopackHook hook) | ||||
|         { | ||||
|             _uninstall += hook; | ||||
|             return this; | ||||
| @@ -151,9 +147,7 @@ namespace Velopack | ||||
|         /// <summary> | ||||
|         /// Runs the Velopack application startup code and triggers any configured hooks. | ||||
|         /// </summary> | ||||
|         /// <param name="logger">A logging interface for diagnostic messages. This will be | ||||
|         /// cached and potentially re-used throughout the lifetime of the application.</param> | ||||
|         public void Run(ILogger? logger = null) | ||||
|         public void Run() | ||||
|         { | ||||
|             var args = _args ?? Environment.GetCommandLineArgs().Skip(1).ToArray(); | ||||
| 
 | ||||
| @@ -164,11 +158,19 @@ namespace Velopack | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             var log = logger ?? NullLogger.Instance; | ||||
|             var locator = DefaultLocator ?? VelopackLocator.GetDefault(log); | ||||
|             DefaultLogger = log; | ||||
|             if (VelopackLocator.IsCurrentSet) { | ||||
|                 VelopackLocator.Current.Log.Error( | ||||
|                     "VelopackApp.Build().Run() was called more than once. This is not allowed and can lead to unexpected behaviour."); | ||||
|             } | ||||
| 
 | ||||
|             log.Info("Starting Velopack App (Run)."); | ||||
|             if (_customLocator != null) { | ||||
|                 VelopackLocator.SetCurrentLocator(_customLocator); | ||||
|             } | ||||
| 
 | ||||
|             var locator = VelopackLocator.GetCurrentOrCreateDefault(); | ||||
|             var log = locator.Log; | ||||
| 
 | ||||
|             log.Info($"Starting VelopackApp.Run (library version {VelopackRuntimeInfo.VelopackNugetVersion})."); | ||||
| 
 | ||||
|             if (VelopackRuntimeInfo.IsWindows && locator.AppId != null) { | ||||
|                 var appUserModelId = CoreUtil.GetAppUserModelId(locator.AppId); | ||||
| @@ -224,7 +226,7 @@ namespace Velopack | ||||
|                 log.Info($"Launching app is out-dated. Current: {myVersion}, Newest Local Available: {latestLocal.Version}"); | ||||
|                 if (!restarted && _autoApply) { | ||||
|                     log.Info("Auto apply is true, so restarting to apply update..."); | ||||
|                     UpdateExe.Apply(locator, latestLocal, false, locator.ProcessId, true, args, log); | ||||
|                     UpdateExe.Apply(locator, latestLocal, false, locator.ProcessId, true, args); | ||||
|                     Exit(0); | ||||
|                 } else { | ||||
|                     log.Info("Pre-condition failed, we will not restart to apply updates. (restarted: " + restarted + ", autoApply: " + _autoApply + ")"); | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| #nullable disable | ||||
| #nullable disable | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
|   | ||||
| @@ -7,9 +7,9 @@ using System.Linq; | ||||
| using System.Runtime.Versioning; | ||||
| using System.Text.RegularExpressions; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Microsoft.Win32; | ||||
| using NuGet.Versioning; | ||||
| using Velopack.Logging; | ||||
| using Velopack.Sources; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| @@ -76,7 +76,7 @@ namespace Velopack.Windows | ||||
|             public abstract Task<bool> CheckIsSupported(); | ||||
| 
 | ||||
|             /// <summary> Download the latest installer for this runtime to the specified file </summary> | ||||
|             public virtual async Task DownloadToFile(string localPath, Action<int> progress = null, IFileDownloader downloader = null, ILogger log = null) | ||||
|             public virtual async Task DownloadToFile(string localPath, Action<int> progress = null, IFileDownloader downloader = null, IVelopackLogger log = null) | ||||
|             { | ||||
|                 var url = await GetDownloadUrl().ConfigureAwait(false); | ||||
|                 log?.Info($"Downloading {Id} from {url} to {localPath}"); | ||||
| @@ -86,7 +86,7 @@ namespace Velopack.Windows | ||||
| 
 | ||||
|             /// <summary> Execute a runtime installer at a local file path. Typically used after <see cref="DownloadToFile"/> </summary> | ||||
|             [SupportedOSPlatform("windows")] | ||||
|             public virtual async Task<RuntimeInstallResult> InvokeInstaller(string pathToInstaller, bool isQuiet, ILogger log = null) | ||||
|             public virtual async Task<RuntimeInstallResult> InvokeInstaller(string pathToInstaller, bool isQuiet, IVelopackLogger log = null) | ||||
|             { | ||||
|                 var args = new string[] { "/passive", "/norestart", "/showrmui" }; | ||||
|                 var quietArgs = new string[] { "/q", "/norestart" }; | ||||
|   | ||||
| @@ -5,9 +5,8 @@ using System.Diagnostics; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Runtime.Versioning; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Microsoft.Extensions.Logging.Abstractions; | ||||
| using Velopack.Locators; | ||||
| using Velopack.Logging; | ||||
| using Velopack.NuGet; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| @@ -58,16 +57,16 @@ namespace Velopack.Windows | ||||
|     public class Shortcuts | ||||
|     { | ||||
|         /// <summary> Log for diagnostic messages. </summary> | ||||
|         protected ILogger Log { get; } | ||||
|         protected IVelopackLogger Log { get; } | ||||
| 
 | ||||
|         /// <summary> Locator to use for finding important application paths. </summary> | ||||
|         protected IVelopackLocator Locator { get; } | ||||
| 
 | ||||
|         /// <inheritdoc cref="Shortcuts"/> | ||||
|         public Shortcuts(ILogger logger = null, IVelopackLocator locator = null) | ||||
|         public Shortcuts(IVelopackLocator locator = null) | ||||
|         { | ||||
|             Log = logger ?? NullLogger.Instance; | ||||
|             Locator = locator ?? VelopackLocator.GetDefault(Log); | ||||
|             Locator = locator ?? VelopackLocator.Current; | ||||
|             Log = Locator.Log; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
| @@ -80,7 +79,7 @@ namespace Velopack.Windows | ||||
|                 Locator.ThisExeRelativePath, | ||||
|                 location, | ||||
|                 false, | ||||
|                 null,  // shortcut arguments  | ||||
|                 null, // shortcut arguments  | ||||
|                 null); // shortcut icon | ||||
|         } | ||||
| 
 | ||||
| @@ -166,30 +165,31 @@ namespace Velopack.Windows | ||||
|                 Log.Info($"Creating shortcut for {relativeExeName} => {file}"); | ||||
| 
 | ||||
|                 ShellLink sl; | ||||
|                 IoUtil.Retry(() => { | ||||
|                     File.Delete(file); | ||||
|                 IoUtil.Retry( | ||||
|                     () => { | ||||
|                         File.Delete(file); | ||||
| 
 | ||||
|                     var target = Path.Combine(currentDir, relativeExeName); | ||||
|                     sl = new ShellLink { | ||||
|                         Target = target, | ||||
|                         IconPath = icon ?? target, | ||||
|                         IconIndex = 0, | ||||
|                         WorkingDirectory = Path.GetDirectoryName(exePath), | ||||
|                         Description = zf.ProductDescription, | ||||
|                     }; | ||||
|                         var target = Path.Combine(currentDir, relativeExeName); | ||||
|                         sl = new ShellLink { | ||||
|                             Target = target, | ||||
|                             IconPath = icon ?? target, | ||||
|                             IconIndex = 0, | ||||
|                             WorkingDirectory = Path.GetDirectoryName(exePath), | ||||
|                             Description = zf.ProductDescription, | ||||
|                         }; | ||||
| 
 | ||||
|                     if (!String.IsNullOrWhiteSpace(programArguments)) { | ||||
|                         sl.Arguments += String.Format(" -a \"{0}\"", programArguments); | ||||
|                     } | ||||
|                         if (!String.IsNullOrWhiteSpace(programArguments)) { | ||||
|                             sl.Arguments += String.Format(" -a \"{0}\"", programArguments); | ||||
|                         } | ||||
| 
 | ||||
|                     //var appUserModelId = Utility.GetAppUserModelId(zf.Id, exeName); | ||||
|                     //var toastActivatorCLSID = Utility.CreateGuidFromHash(appUserModelId).ToString(); | ||||
|                     //sl.SetAppUserModelId(appUserModelId); | ||||
|                     //sl.SetToastActivatorCLSID(toastActivatorCLSID); | ||||
|                         //var appUserModelId = Utility.GetAppUserModelId(zf.Id, exeName); | ||||
|                         //var toastActivatorCLSID = Utility.CreateGuidFromHash(appUserModelId).ToString(); | ||||
|                         //sl.SetAppUserModelId(appUserModelId); | ||||
|                         //sl.SetToastActivatorCLSID(toastActivatorCLSID); | ||||
| 
 | ||||
|                     Log.Info($"About to save shortcut: {file} (target {sl.Target}, workingDir {sl.WorkingDirectory}, args {sl.Arguments})"); | ||||
|                     sl.Save(file); | ||||
|                 }); | ||||
|                         Log.Info($"About to save shortcut: {file} (target {sl.Target}, workingDir {sl.WorkingDirectory}, args {sl.Arguments})"); | ||||
|                         sl.Save(file); | ||||
|                     }); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| @@ -230,16 +230,16 @@ namespace Velopack.Windows | ||||
|         protected virtual string LinkPathForVersionInfo(ShortcutLocation location, ZipPackage package, FileVersionInfo versionInfo, string rootdir) | ||||
|         { | ||||
|             var possibleProductNames = new[] { | ||||
|                     versionInfo.ProductName, | ||||
|                     package.ProductName, | ||||
|                     versionInfo.FileDescription, | ||||
|                     Path.GetFileNameWithoutExtension(versionInfo.FileName) | ||||
|                 }; | ||||
|                 versionInfo.ProductName, | ||||
|                 package.ProductName, | ||||
|                 versionInfo.FileDescription, | ||||
|                 Path.GetFileNameWithoutExtension(versionInfo.FileName) | ||||
|             }; | ||||
| 
 | ||||
|             var possibleCompanyNames = new[] { | ||||
|                     versionInfo.CompanyName, | ||||
|                     package.ProductCompany, | ||||
|                 }; | ||||
|                 versionInfo.CompanyName, | ||||
|                 package.ProductCompany, | ||||
|             }; | ||||
| 
 | ||||
|             var prodName = possibleCompanyNames.First(x => !String.IsNullOrWhiteSpace(x)); | ||||
|             var pkgName = possibleProductNames.First(x => !String.IsNullOrWhiteSpace(x)); | ||||
| @@ -250,7 +250,8 @@ namespace Velopack.Windows | ||||
|         /// <summary> | ||||
|         /// Given the application info, return the shortcut target path. | ||||
|         /// </summary> | ||||
|         protected virtual string GetLinkPath(ShortcutLocation location, string title, string applicationName, string rootdir, bool createDirectoryIfNecessary = true) | ||||
|         protected virtual string GetLinkPath(ShortcutLocation location, string title, string applicationName, string rootdir, | ||||
|             bool createDirectoryIfNecessary = true) | ||||
|         { | ||||
|             var dir = default(string); | ||||
| 
 | ||||
|   | ||||
| @@ -1,12 +1,45 @@ | ||||
| using System; | ||||
| using System.Diagnostics.CodeAnalysis; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Velopack.Logging; | ||||
| 
 | ||||
| namespace Velopack.Util | ||||
| namespace Velopack.Core | ||||
| { | ||||
|     [ExcludeFromCodeCoverage] | ||||
|     internal static class LoggerExtensions | ||||
|     public static class LoggerExtensions | ||||
|     { | ||||
|         public static IVelopackLogger ToVelopackLogger(this ILogger logger) | ||||
|         { | ||||
|             return new MicrosoftExtensionsLoggerAdapter(logger); | ||||
|         } | ||||
| 
 | ||||
|         private class MicrosoftExtensionsLoggerAdapter(ILogger logger) : IVelopackLogger | ||||
|         { | ||||
|             public void Log(VelopackLogLevel logLevel, string? message, Exception? exception) | ||||
|             { | ||||
|                 switch (logLevel) { | ||||
|                 case VelopackLogLevel.Trace: | ||||
|                     logger.LogTrace(exception, message); | ||||
|                     break; | ||||
|                 case VelopackLogLevel.Debug: | ||||
|                     logger.LogDebug(exception, message); | ||||
|                     break; | ||||
|                 case VelopackLogLevel.Information: | ||||
|                     logger.LogInformation(exception, message); | ||||
|                     break; | ||||
|                 case VelopackLogLevel.Warning: | ||||
|                     logger.LogWarning(exception, message); | ||||
|                     break; | ||||
|                 case VelopackLogLevel.Error: | ||||
|                     logger.LogError(exception, message); | ||||
|                     break; | ||||
|                 case VelopackLogLevel.Critical: | ||||
|                     logger.LogCritical(exception, message); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public static void Trace(this ILogger logger, string message) | ||||
|         { | ||||
|             logger.LogTrace(message); | ||||
| @@ -16,6 +49,7 @@ namespace Velopack.Util | ||||
|         { | ||||
|             logger.LogTrace(ex, message); | ||||
|         } | ||||
| 
 | ||||
|         public static void Trace(this ILogger logger, Exception ex) | ||||
|         { | ||||
|             logger.LogTrace(ex, ex.Message); | ||||
| @@ -15,6 +15,7 @@ | ||||
|   <ItemGroup> | ||||
|     <PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> | ||||
|     <PackageReference Include="System.Net.Http" Version="4.3.4" /> | ||||
|     <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
| </Project> | ||||
|   | ||||
| @@ -3,6 +3,7 @@ using Azure.Storage; | ||||
| using Azure.Storage.Blobs; | ||||
| using Azure.Storage.Blobs.Models; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Velopack.Core; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| namespace Velopack.Deployment; | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Velopack.Core; | ||||
| using Velopack.Packaging; | ||||
| using Velopack.Sources; | ||||
| using Velopack.Util; | ||||
| @@ -68,12 +69,12 @@ public class LocalRepository(ILogger logger) : ObjectRepository<LocalDownloadOpt | ||||
|     protected override Task SaveEntryToFileAsync(LocalDownloadOptions options, VelopackAsset entry, string filePath) | ||||
|     { | ||||
|         var source = new SimpleFileSource(options.TargetPath); | ||||
|         return source.DownloadReleaseEntry(Log, entry, filePath, (i) => { }, default); | ||||
|         return source.DownloadReleaseEntry(Log.ToVelopackLogger(), entry, filePath, (i) => { }, default); | ||||
|     } | ||||
| 
 | ||||
|     protected override Task<VelopackAssetFeed> GetReleasesAsync(LocalDownloadOptions options) | ||||
|     { | ||||
|         var source = new SimpleFileSource(options.TargetPath); | ||||
|         return source.GetReleaseFeed(channel: options.Channel, logger: Log); | ||||
|         return source.GetReleaseFeed(Log.ToVelopackLogger(), null, options.Channel); | ||||
|     } | ||||
| } | ||||
| @@ -3,6 +3,7 @@ using Amazon.Runtime; | ||||
| using Amazon.S3; | ||||
| using Amazon.S3.Model; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Velopack.Core; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| namespace Velopack.Deployment; | ||||
|   | ||||
| @@ -32,25 +32,20 @@ public interface IRepositoryCanDownload<TDown> where TDown : RepositoryOptions | ||||
|     Task DownloadLatestFullPackageAsync(TDown options); | ||||
| } | ||||
| 
 | ||||
| public abstract class SourceRepository<TDown, TSource> : DownRepository<TDown> | ||||
| public abstract class SourceRepository<TDown, TSource>(ILogger logger) : DownRepository<TDown>(logger) | ||||
|     where TDown : RepositoryOptions | ||||
|     where TSource : IUpdateSource | ||||
| { | ||||
|     public SourceRepository(ILogger logger) | ||||
|         : base(logger) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|     protected override Task<VelopackAssetFeed> GetReleasesAsync(TDown options) | ||||
|     { | ||||
|         var source = CreateSource(options); | ||||
|         return source.GetReleaseFeed(channel: options.Channel, logger: Log); | ||||
|         return source.GetReleaseFeed(Log.ToVelopackLogger(), null, options.Channel); | ||||
|     } | ||||
| 
 | ||||
|     protected override Task SaveEntryToFileAsync(TDown options, VelopackAsset entry, string filePath) | ||||
|     { | ||||
|         var source = CreateSource(options); | ||||
|         return source.DownloadReleaseEntry(Log, entry, filePath, (i) => { }); | ||||
|         return source.DownloadReleaseEntry(Log.ToVelopackLogger(), entry, filePath, (i) => { }); | ||||
|     } | ||||
| 
 | ||||
|     public abstract TSource CreateSource(TDown options); | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| using ICSharpCode.SharpZipLib.Tar; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Velopack.Compression; | ||||
| using Velopack.Core; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| namespace Velopack.Packaging.Unix; | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| using System.Runtime.Versioning; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Velopack.Core; | ||||
| using Velopack.Core.Abstractions; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| // https://raw.githubusercontent.com/egramtel/dotnet-bundle/master/DotNet.Bundle/PlistWriter.cs | ||||
| using System.Xml; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Velopack.Core; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| namespace Velopack.Packaging.Unix; | ||||
|   | ||||
| @@ -248,7 +248,7 @@ public class WindowsPackCommandRunner : PackageBuilder<WindowsPackOptions> | ||||
|         // create a .portable file to indicate this is a portable package | ||||
|         File.Create(Path.Combine(dir.FullName, ".portable")).Close(); | ||||
| 
 | ||||
|         await EasyZip.CreateZipFromDirectoryAsync(Log, outputPath, dir.FullName, CoreUtil.CreateProgressDelegate(progress, 40, 100)); | ||||
|         await EasyZip.CreateZipFromDirectoryAsync(Log.ToVelopackLogger(), outputPath, dir.FullName, CoreUtil.CreateProgressDelegate(progress, 40, 100)); | ||||
|         progress(100); | ||||
|     } | ||||
| 
 | ||||
| @@ -301,7 +301,8 @@ public class WindowsPackCommandRunner : PackageBuilder<WindowsPackOptions> | ||||
|             Log.Info($"Use Azure Trusted Signing service for code signing. Metadata file path: {trustedSignMetadataPath}"); | ||||
| 
 | ||||
|             string dlibPath = GetDlibPath(CancellationToken.None); | ||||
|             signParams = $"/fd SHA256 /tr http://timestamp.acs.microsoft.com /v /debug /td SHA256 /dlib {HelperFile.AzureDlibFileName} /dmdf \"{trustedSignMetadataPath}\""; | ||||
|             signParams = | ||||
|                 $"/fd SHA256 /tr http://timestamp.acs.microsoft.com /v /debug /td SHA256 /dlib {HelperFile.AzureDlibFileName} /dmdf \"{trustedSignMetadataPath}\""; | ||||
|             helper.Sign(filePaths, signParams, signParallel, progress, false); | ||||
|         } else if (!string.IsNullOrEmpty(signParams)) { | ||||
|             helper.Sign(filePaths, signParams, signParallel, progress, false); | ||||
|   | ||||
| @@ -33,7 +33,8 @@ public class DeltaPatchCommandRunner : ICommand<DeltaPatchOptions> | ||||
|         using var _1 = TempUtil.GetTempDirectory(out var workDir); | ||||
| 
 | ||||
|         var delta = new DeltaEmbedded(HelperFile.GetZstdPath(), _logger, tmp); | ||||
|         EasyZip.ExtractZipToDirectory(_logger, options.BasePackage, workDir); | ||||
|         var veloLogger = _logger.ToVelopackLogger(); | ||||
|         EasyZip.ExtractZipToDirectory(veloLogger, options.BasePackage, workDir); | ||||
| 
 | ||||
|         await _console.ExecuteProgressAsync( | ||||
|             async (ctx) => { | ||||
| @@ -50,7 +51,7 @@ public class DeltaPatchCommandRunner : ICommand<DeltaPatchOptions> | ||||
|                 await ctx.RunTask( | ||||
|                     $"Building {Path.GetFileName(options.OutputFile)}", | ||||
|                     async (progress) => { | ||||
|                         await EasyZip.CreateZipFromDirectoryAsync(_logger, options.OutputFile, workDir, progress); | ||||
|                         await EasyZip.CreateZipFromDirectoryAsync(veloLogger, options.OutputFile, workDir, progress); | ||||
|                         progress(100); | ||||
|                     }); | ||||
|             }); | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Velopack.Compression; | ||||
| using Velopack.Core; | ||||
| 
 | ||||
| namespace Velopack.Packaging; | ||||
| 
 | ||||
| @@ -21,7 +22,7 @@ public class DeltaEmbedded | ||||
|     { | ||||
|         private readonly Zstd _zstd; | ||||
| 
 | ||||
|         public DeltaImpl(string zstdPath, ILogger logger, string baseTmpDir) : base(logger, baseTmpDir) | ||||
|         public DeltaImpl(string zstdPath, ILogger logger, string baseTmpDir) : base(logger.ToVelopackLogger(), baseTmpDir) | ||||
|         { | ||||
|             _zstd = new Zstd(zstdPath); | ||||
|         } | ||||
|   | ||||
| @@ -76,8 +76,9 @@ public class DeltaPackageBuilder | ||||
|             _logger.Info($"Creating delta for {basePackage.Version} -> {newPackage.Version} with {numParallel} parallel threads."); | ||||
|             _logger.Debug($"Extracting {Path.GetFileName(basePackage.PackageFile)} and {Path.GetFileName(newPackage.PackageFile)} into {tempPath}"); | ||||
| 
 | ||||
|             EasyZip.ExtractZipToDirectory(_logger, basePackage.PackageFile, baseTempInfo.FullName); | ||||
|             EasyZip.ExtractZipToDirectory(_logger, newPackage.PackageFile, tempInfo.FullName); | ||||
|             var veloLogger = _logger.ToVelopackLogger(); | ||||
|             EasyZip.ExtractZipToDirectory(veloLogger, basePackage.PackageFile, baseTempInfo.FullName); | ||||
|             EasyZip.ExtractZipToDirectory(veloLogger, newPackage.PackageFile, tempInfo.FullName); | ||||
| 
 | ||||
|             // Collect a list of relative paths under 'lib' and map them | ||||
|             // to their full name. We'll use this later to determine in | ||||
| @@ -191,7 +192,7 @@ public class DeltaPackageBuilder | ||||
|                     "Delta creation failed for one or more files. See log for details. To skip delta generation, use the '--delta none' argument."); | ||||
|             } | ||||
| 
 | ||||
|             EasyZip.CreateZipFromDirectoryAsync(_logger, outputFile, tempInfo.FullName, CoreUtil.CreateProgressDelegate(progress, 70, 100)).GetAwaiterResult(); | ||||
|             EasyZip.CreateZipFromDirectoryAsync(_logger.ToVelopackLogger(), outputFile, tempInfo.FullName, CoreUtil.CreateProgressDelegate(progress, 70, 100)).GetAwaiterResult(); | ||||
|             progress(100); | ||||
|             fRemoved = baseLibFiles.Count; | ||||
| 
 | ||||
|   | ||||
| @@ -2,10 +2,6 @@ | ||||
| using System.Text; | ||||
| using Microsoft.Extensions.Logging; | ||||
| 
 | ||||
| #if !DEBUG | ||||
| using Velopack.Util; | ||||
| #endif | ||||
| 
 | ||||
| namespace Velopack.Packaging; | ||||
| 
 | ||||
| public static class HelperFile | ||||
| @@ -23,7 +19,7 @@ public static class HelperFile | ||||
| #else | ||||
|         case RuntimeOs.Linux: | ||||
|             if (!target.HasArchitecture) { | ||||
|                 log.Warn("No architecture specified with --runtime, defaulting to x64. If this was not intended please specify via the --runtime parameter"); | ||||
|                 log.LogWarning("No architecture specified with --runtime, defaulting to x64. If this was not intended please specify via the --runtime parameter"); | ||||
|                 return FindHelperFile("UpdateNix_x64"); | ||||
|             } | ||||
| 
 | ||||
|   | ||||
| @@ -293,7 +293,7 @@ public abstract class PackageBuilder<T> : ICommand<T> | ||||
| 
 | ||||
|         AddContentTypesAndRel(nuspecPath); | ||||
| 
 | ||||
|         await EasyZip.CreateZipFromDirectoryAsync(Log, outputPath, stagingDir.FullName, CoreUtil.CreateProgressDelegate(progress, 30, 100)); | ||||
|         await EasyZip.CreateZipFromDirectoryAsync(Log.ToVelopackLogger(), outputPath, stagingDir.FullName, CoreUtil.CreateProgressDelegate(progress, 30, 100)); | ||||
|         progress(100); | ||||
|     } | ||||
| 
 | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| using Velopack.Core.Abstractions; | ||||
| using Velopack.Core; | ||||
| using Velopack.Core.Abstractions; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| namespace Velopack.Vpk.Logging; | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| using System.Threading; | ||||
| using Spectre.Console; | ||||
| using Velopack.Core; | ||||
| using Velopack.Core.Abstractions; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| using System.Threading; | ||||
| using NuGet.Protocol.Core.Types; | ||||
| using Velopack.Core; | ||||
| using Velopack.Packaging.NuGet; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| @@ -21,7 +22,6 @@ public class UpdateChecker | ||||
|     { | ||||
|         if (_defaults.SkipUpdates) return false; | ||||
|         try { | ||||
| 
 | ||||
|             var myVer = VelopackRuntimeInfo.VelopackNugetVersion; | ||||
|             var isPre = myVer.IsPrerelease || myVer.HasMetadata; | ||||
| 
 | ||||
| @@ -38,6 +38,7 @@ public class UpdateChecker | ||||
|                 } else { | ||||
|                     _logger.Warn($"[bold]There is a newer version of vpk available. Run 'dotnet tool update -g vpk --version {cacheVersion}'[/]"); | ||||
|                 } | ||||
| 
 | ||||
|                 return true; | ||||
|             } else { | ||||
|                 _logger.Debug($"vpk is up to date (latest online = {cacheVersion})"); | ||||
| @@ -45,6 +46,7 @@ public class UpdateChecker | ||||
|         } catch (Exception ex) { | ||||
|             _logger.Debug(ex, "Failed to check for updates."); | ||||
|         } | ||||
| 
 | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
| @@ -1,19 +0,0 @@ | ||||
| using Microsoft.Extensions.Logging; | ||||
| 
 | ||||
| class ConsoleLogger : ILogger | ||||
| { | ||||
|     public IDisposable BeginScope<TState>(TState state) where TState : notnull | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     public bool IsEnabled(LogLevel logLevel) | ||||
|     { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) | ||||
|     { | ||||
|         Console.WriteLine(formatter(state, exception)); | ||||
|     } | ||||
| } | ||||
| @@ -2,6 +2,9 @@ | ||||
| using System.Diagnostics; | ||||
| using Velopack; | ||||
| using Velopack.Locators; | ||||
| using Velopack.Logging; | ||||
| 
 | ||||
| var locator = VelopackLocator.CreateDefaultForPlatform(new ConsoleVelopackLogger()); | ||||
| 
 | ||||
| try { | ||||
|     bool shouldExit = false; | ||||
| @@ -14,21 +17,24 @@ try { | ||||
| #if !NO_VELO_BUILDER | ||||
|     VelopackApp.Build() | ||||
|         .SetAutoApplyOnStartup(shouldAutoUpdate) | ||||
|         .WithFirstRun((v) => { | ||||
|             debugFile("firstrun", v.ToString()); | ||||
|             Console.WriteLine("was first run"); | ||||
|             shouldExit = true; | ||||
|         }) | ||||
|         .WithRestarted((v) => { | ||||
|             debugFile("restarted", v.ToString() + "," + String.Join(",", args)); | ||||
|             Console.WriteLine("app just restarted"); | ||||
|             shouldExit = true; | ||||
|         }) | ||||
|         .WithAfterInstallFastCallback((v) => debugFile("args.txt", String.Join(" ", args))) | ||||
|         .WithBeforeUpdateFastCallback((v) => debugFile("args.txt", String.Join(" ", args))) | ||||
|         .WithAfterUpdateFastCallback((v) => debugFile("args.txt", String.Join(" ", args))) | ||||
|         .WithBeforeUninstallFastCallback((v) => debugFile("args.txt", String.Join(" ", args))) | ||||
|         .Run(new ConsoleLogger()); | ||||
|         .OnFirstRun( | ||||
|             (v) => { | ||||
|                 debugFile("firstrun", v.ToString()); | ||||
|                 Console.WriteLine("was first run"); | ||||
|                 shouldExit = true; | ||||
|             }) | ||||
|         .OnRestarted( | ||||
|             (v) => { | ||||
|                 debugFile("restarted", v.ToString() + "," + String.Join(",", args)); | ||||
|                 Console.WriteLine("app just restarted"); | ||||
|                 shouldExit = true; | ||||
|             }) | ||||
|         .SetLocator(locator) | ||||
|         .OnAfterInstallFastCallback((v) => debugFile("args.txt", String.Join(" ", args))) | ||||
|         .OnBeforeUpdateFastCallback((v) => debugFile("args.txt", String.Join(" ", args))) | ||||
|         .OnAfterUpdateFastCallback((v) => debugFile("args.txt", String.Join(" ", args))) | ||||
|         .OnBeforeUninstallFastCallback((v) => debugFile("args.txt", String.Join(" ", args))) | ||||
|         .Run(); | ||||
| 
 | ||||
|     if (shouldAutoUpdate) { | ||||
|         // this shouldn't be reached | ||||
| @@ -41,7 +47,6 @@ try { | ||||
| #endif | ||||
| 
 | ||||
|     if (args.Length == 1 && args[0] == "version") { | ||||
|         var locator = VelopackLocator.GetDefault(new ConsoleLogger()); | ||||
|         Console.WriteLine(locator.CurrentlyInstalledVersion?.ToString() ?? "unknown_version"); | ||||
|         return 0; | ||||
|     } | ||||
| @@ -53,7 +58,7 @@ try { | ||||
| 
 | ||||
|     if (args.Length == 2) { | ||||
|         if (args[0] == "check") { | ||||
|             var um = new UpdateManager(args[1], null, new ConsoleLogger()); | ||||
|             var um = new UpdateManager(args[1], null, locator); | ||||
|             var info = um.CheckForUpdates(); | ||||
|             if (info == null) { | ||||
|                 Console.WriteLine("no updates"); | ||||
| @@ -65,28 +70,29 @@ try { | ||||
|         } | ||||
| 
 | ||||
|         if (args[0] == "download") { | ||||
|             var um = new UpdateManager(args[1], null, new ConsoleLogger()); | ||||
|             var um = new UpdateManager(args[1], null, locator); | ||||
|             var info = um.CheckForUpdates(); | ||||
|             if (info == null) { | ||||
|                 Console.WriteLine("no updates"); | ||||
|                 return -1; | ||||
|             } | ||||
| 
 | ||||
|             um.DownloadUpdates(info, (x) => Console.WriteLine(x)); | ||||
|             return 0; | ||||
|         } | ||||
| 
 | ||||
|         if (args[0] == "apply") { | ||||
|             var um = new UpdateManager(args[1], null, new ConsoleLogger()); | ||||
|             var um = new UpdateManager(args[1], null, locator); | ||||
|             if (um.UpdatePendingRestart == null) { | ||||
|                 Console.WriteLine("not pending restart"); | ||||
|                 return -1; | ||||
|             } | ||||
| 
 | ||||
|             Console.WriteLine("applying..."); | ||||
|             um.ApplyUpdatesAndRestart((VelopackAsset) null, new[] { "test", "args !!" }); | ||||
|             return 0; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } catch (Exception ex) { | ||||
|     Console.WriteLine("exception: " + ex.ToString()); | ||||
|     if (Debugger.IsAttached) throw; | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| using Azure.Storage.Blobs; | ||||
| using NuGet.Versioning; | ||||
| using Velopack.Core; | ||||
| using Velopack.Deployment; | ||||
| using Velopack.Locators; | ||||
| using Velopack.Sources; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| @@ -92,8 +94,9 @@ public class DeploymentTests | ||||
|         // get the latest  | ||||
|         var source = new SimpleWebSource(updateUrl); | ||||
|         VelopackAssetFeed feed = new VelopackAssetFeed(); | ||||
| 
 | ||||
|         try { | ||||
|             feed = await source.GetReleaseFeed(logger, CHANNEL); | ||||
|             feed = await source.GetReleaseFeed(logger.ToVelopackLogger(), null, CHANNEL); | ||||
|         } catch (Exception ex) { | ||||
|             logger.Warn(ex, "Failed to fetch release feed."); | ||||
|         } | ||||
| @@ -116,7 +119,7 @@ public class DeploymentTests | ||||
|         await repo.UploadMissingAssetsAsync(options); | ||||
| 
 | ||||
|         // verify that new version has been uploaded | ||||
|         feed = await source.GetReleaseFeed(logger, CHANNEL); | ||||
|         feed = await source.GetReleaseFeed(logger.ToVelopackLogger(), null, CHANNEL); | ||||
|         latestOnline = feed.Assets.Where(a => a.Version != null && a.Type == VelopackAssetType.Full).MaxBy(a => a.Version); | ||||
| 
 | ||||
|         Assert.True(latestOnline != null, "No latest version found."); | ||||
|   | ||||
| @@ -173,7 +173,7 @@ This is just a _test_! | ||||
| 
 | ||||
|         // update | ||||
|         var source = new GiteaSource(GITEA_REPOURL, GITEA_TOKEN, false); | ||||
|         var releases = source.GetReleaseFeed(channel: uniqueSuffix, logger: logger).GetAwaiterResult(); | ||||
|         var releases = source.GetReleaseFeed(logger.ToVelopackLogger(), null, channel: uniqueSuffix).GetAwaiterResult(); | ||||
| 
 | ||||
|         var ghrel = releases.Assets.Select(r => (GiteaSource.GitBaseAsset) r).ToArray(); | ||||
|         foreach (var g in ghrel) { | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
| using Velopack.Sources; | ||||
| using Octokit; | ||||
| using Velopack.Core; | ||||
| using Velopack.Locators; | ||||
| using Velopack.Packaging.Exceptions; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| @@ -167,7 +168,7 @@ public class GithubDeploymentTests | ||||
| 
 | ||||
|         // update | ||||
|         var source = new GithubSource(GITHUB_REPOURL, GITHUB_TOKEN, false); | ||||
|         var releases = source.GetReleaseFeed(channel: uniqueSuffix, logger: logger).GetAwaiterResult(); | ||||
|         var releases = source.GetReleaseFeed(logger.ToVelopackLogger(), null, channel: uniqueSuffix).GetAwaiterResult(); | ||||
| 
 | ||||
|         var ghrel = releases.Assets.Select(r => (GithubSource.GitBaseAsset) r).ToArray(); | ||||
|         foreach (var g in ghrel) { | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| using System.Runtime.Versioning; | ||||
| using Velopack.Compression; | ||||
| using Velopack.Core; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| namespace Velopack.Packaging.Tests; | ||||
| @@ -32,7 +33,7 @@ public class OsxPackTests | ||||
|         TestApp.PackTestApp(id, "0.0.1", string.Empty, tmpReleaseDir, logger, channel: channel, packTitle: title); | ||||
| 
 | ||||
|         var portablePath = Path.Combine(tmpReleaseDir, $"{id}-{channel}-Portable.zip"); | ||||
|         EasyZip.ExtractZipToDirectory(logger, portablePath, unzipDir); | ||||
|         EasyZip.ExtractZipToDirectory(logger.ToVelopackLogger(), portablePath, unzipDir); | ||||
| 
 | ||||
|         var bundlePath = Path.Combine(unzipDir, $"{title}.app"); | ||||
|         Assert.True(Directory.Exists(bundlePath)); | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| #nullable enable | ||||
| using System.Diagnostics; | ||||
| using Velopack.Core; | ||||
| using Velopack.Packaging.Unix.Commands; | ||||
| using Velopack.Packaging.Windows.Commands; | ||||
| using Velopack.Util; | ||||
|   | ||||
| @@ -79,7 +79,7 @@ public class WindowsPackTests | ||||
|         var releasesPath2 = Path.Combine(tmpReleaseDir, $"releases.asd123.json"); | ||||
|         Assert.True(File.Exists(releasesPath2)); | ||||
| 
 | ||||
|         EasyZip.ExtractZipToDirectory(logger, nupkgPath, unzipDir); | ||||
|         EasyZip.ExtractZipToDirectory(logger.ToVelopackLogger(), nupkgPath, unzipDir); | ||||
| 
 | ||||
|         // does nuspec exist and is it valid | ||||
|         var nuspecPath = Path.Combine(unzipDir, $"{id}.nuspec"); | ||||
| @@ -310,7 +310,7 @@ public class WindowsPackTests | ||||
|         var deltaPath = Path.Combine(releaseDir, $"{id}-2.0.0-delta.nupkg"); | ||||
|         Assert.True(File.Exists(deltaPath)); | ||||
|         using var _2 = TempUtil.GetTempDirectory(out var extractDir); | ||||
|         EasyZip.ExtractZipToDirectory(logger, deltaPath, extractDir); | ||||
|         EasyZip.ExtractZipToDirectory(logger.ToVelopackLogger(), deltaPath, extractDir); | ||||
|         var extractDllDiff = Path.Combine(extractDir, "lib", "app", "testapp.dll.zsdiff"); | ||||
|         var extractDllShasum = Path.Combine(extractDir, "lib", "app", "testapp.dll.shasum"); | ||||
|         Assert.True(File.Exists(extractDllDiff)); | ||||
| @@ -659,7 +659,7 @@ public class WindowsPackTests | ||||
|             () => { | ||||
|                 return File.ReadAllText(path); | ||||
|             }, | ||||
|             logger: logger, | ||||
|             logger: logger.ToVelopackLogger(), | ||||
|             retries: 10, | ||||
|             retryDelay: 1000); | ||||
|     } | ||||
| @@ -730,7 +730,7 @@ public class WindowsPackTests | ||||
|                 }, | ||||
|                 10, | ||||
|                 1000, | ||||
|                 logger); | ||||
|                 logger.ToVelopackLogger()); | ||||
| 
 | ||||
|             using var reader = new StreamReader(fs); | ||||
|             var output = reader.ReadToEnd(); | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| #pragma warning disable CS0618 // Type or member is obsolete | ||||
| using System.Runtime.Versioning; | ||||
| using Velopack.Core; | ||||
| using Velopack.Locators; | ||||
| using Velopack.Util; | ||||
| using Velopack.Windows; | ||||
| @@ -29,8 +30,16 @@ public class ShortcutTests | ||||
|         PathHelper.CopyFixtureTo("AvaloniaCrossPlat-1.0.15-win-full.nupkg", packages.FullName); | ||||
|         PathHelper.CopyFixtureTo(exeName, current.FullName); | ||||
| 
 | ||||
|         var locator = new TestVelopackLocator("AvaloniaCrossPlat", "1.0.0", packages.FullName, current.FullName, rootDir, null, null, logger); | ||||
|         var sh = new Shortcuts(logger, locator); | ||||
|         var locator = new TestVelopackLocator( | ||||
|             "AvaloniaCrossPlat", | ||||
|             "1.0.0", | ||||
|             packages.FullName, | ||||
|             current.FullName, | ||||
|             rootDir, | ||||
|             null, | ||||
|             null, | ||||
|             logger.ToVelopackLogger()); | ||||
|         var sh = new Shortcuts(locator); | ||||
|         var flag = ShortcutLocation.StartMenuRoot | ShortcutLocation.Desktop; | ||||
|         sh.DeleteShortcuts(exeName, flag); | ||||
|         sh.CreateShortcut(exeName, flag, false, ""); | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
| using System.IO.Compression; | ||||
| using NCode.ReparsePoints; | ||||
| using Velopack.Compression; | ||||
| using Velopack.Logging; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| namespace Velopack.Tests; | ||||
| @@ -247,7 +248,7 @@ public class SymbolicLinkTests | ||||
|         using var _2 = TempUtil.GetTempDirectory(out var tempOutput); | ||||
|         var output = Path.Combine(tempOutput, "output.zip"); | ||||
| 
 | ||||
|         await EasyZip.CreateZipFromDirectoryAsync(NullLogger.Instance, output, tempFolder); | ||||
|         await EasyZip.CreateZipFromDirectoryAsync(NullVelopackLogger.Instance, output, tempFolder); | ||||
|         ZipFile.ExtractToDirectory(output, tempOutput); | ||||
| 
 | ||||
|         var appSym = Path.Combine(tempOutput, "App.__symlink"); | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
| #pragma warning disable CS0612 // Type or member is obsolete | ||||
| using System.Text; | ||||
| using Velopack.Core; | ||||
| using Velopack.Logging; | ||||
| using Velopack.Sources; | ||||
| using Velopack.Util; | ||||
| 
 | ||||
| @@ -25,7 +26,7 @@ internal class FakeFixtureRepository : IFileDownloader | ||||
|             .ToList(); | ||||
| 
 | ||||
|         var releasesNew = new SimpleFileSource(new DirectoryInfo(PathHelper.GetFixturesDir())) | ||||
|             .GetReleaseFeed(NullLogger.Instance, null).GetAwaiterResult().Assets | ||||
|             .GetReleaseFeed(NullVelopackLogger.Instance, null, null).GetAwaiterResult().Assets | ||||
|             .Where(r => r.FileName.StartsWith(_pkgId)) | ||||
|             .ToList(); | ||||
| 
 | ||||
|   | ||||
| @@ -49,7 +49,7 @@ public class UpdateManagerTests | ||||
|     { | ||||
|         var feed = new VelopackAssetFeed { | ||||
|             Assets = new VelopackAsset[] { | ||||
|                   new VelopackAsset() { | ||||
|                 new VelopackAsset() { | ||||
|                     PackageId = "MyCoolApp", | ||||
|                     Version = new SemanticVersion(1, 1, 0), | ||||
|                     Type = VelopackAssetType.Full, | ||||
| @@ -81,7 +81,7 @@ public class UpdateManagerTests | ||||
|                     SHA1 = "14db31d2647c6d2284882a2e101924a9c409ee67", | ||||
|                     Size = 80396, | ||||
|                 }, | ||||
|                   new VelopackAsset() { | ||||
|                 new VelopackAsset() { | ||||
|                     PackageId = "MyCoolApp", | ||||
|                     Version = new SemanticVersion(1, 2, 0), | ||||
|                     Type = VelopackAssetType.Delta, | ||||
| @@ -111,22 +111,24 @@ public class UpdateManagerTests | ||||
|         using var logger = _output.BuildLoggerFor<UpdateManagerTests>(); | ||||
|         using var _1 = TempUtil.GetTempDirectory(out var tempPath); | ||||
|         var dl = new FakeDownloader() { | ||||
|             MockedResponseBytes = Encoding.UTF8.GetBytes(SimpleJson.SerializeObject( | ||||
|             new VelopackAssetFeed { | ||||
|                 Assets = new VelopackAsset[] { | ||||
|                   new VelopackAsset() { | ||||
|                     PackageId = "AvaloniaCrossPlat", | ||||
|                     Version = new SemanticVersion(1, 0, 11), | ||||
|                     Type = VelopackAssetType.Full, | ||||
|                     FileName = $"https://mysite.com/releases/AvaloniaCrossPlat$-1.1.0.nupkg", | ||||
|                     SHA1 = IoUtil.CalculateFileSHA1(fixture), | ||||
|                     Size = new FileInfo(fixture).Length, | ||||
|                 } } | ||||
|             })) | ||||
|             MockedResponseBytes = Encoding.UTF8.GetBytes( | ||||
|                 SimpleJson.SerializeObject( | ||||
|                     new VelopackAssetFeed { | ||||
|                         Assets = new VelopackAsset[] { | ||||
|                             new VelopackAsset() { | ||||
|                                 PackageId = "AvaloniaCrossPlat", | ||||
|                                 Version = new SemanticVersion(1, 0, 11), | ||||
|                                 Type = VelopackAssetType.Full, | ||||
|                                 FileName = $"https://mysite.com/releases/AvaloniaCrossPlat$-1.1.0.nupkg", | ||||
|                                 SHA1 = IoUtil.CalculateFileSHA1(fixture), | ||||
|                                 Size = new FileInfo(fixture).Length, | ||||
|                             } | ||||
|                         } | ||||
|                     })) | ||||
|         }; | ||||
|         var source = new SimpleWebSource("http://any.com", dl); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger); | ||||
|         var um = new UpdateManager(source, null, logger, locator); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger.ToVelopackLogger()); | ||||
|         var um = new UpdateManager(source, null, locator); | ||||
|         var info = um.CheckForUpdates(); | ||||
|         Assert.NotNull(info); | ||||
|         Assert.True(new SemanticVersion(1, 0, 11) == info.TargetFullRelease.Version); | ||||
| @@ -150,8 +152,8 @@ public class UpdateManagerTests | ||||
|         using var _1 = TempUtil.GetTempDirectory(out var tempPath); | ||||
|         var dl = GetMockDownloaderNoDelta(); | ||||
|         var source = new SimpleWebSource("http://any.com", dl); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger); | ||||
|         var um = new UpdateManager(source, null, logger, locator); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger.ToVelopackLogger()); | ||||
|         var um = new UpdateManager(source, null, locator); | ||||
|         var info = um.CheckForUpdates(); | ||||
|         Assert.NotNull(info); | ||||
|         Assert.True(new SemanticVersion(1, 1, 0) == info.TargetFullRelease.Version); | ||||
| @@ -167,9 +169,9 @@ public class UpdateManagerTests | ||||
|         using var _1 = TempUtil.GetTempDirectory(out var tempPath); | ||||
|         var dl = GetMockDownloaderNoDelta(); | ||||
|         var source = new SimpleWebSource("http://any.com", dl); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger.ToVelopackLogger()); | ||||
|         var opt = new UpdateOptions { ExplicitChannel = "experimental" }; | ||||
|         var um = new UpdateManager(source, opt, logger, locator); | ||||
|         var um = new UpdateManager(source, opt, locator); | ||||
|         var info = um.CheckForUpdates(); | ||||
|         Assert.NotNull(info); | ||||
|         Assert.True(new SemanticVersion(1, 1, 0) == info.TargetFullRelease.Version); | ||||
| @@ -193,23 +195,32 @@ public class UpdateManagerTests | ||||
|             Size = 1040561, | ||||
|         }; | ||||
|         var source = new SimpleWebSource("http://any.com", dl); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.2.0", tempPath, null, null, null, logger: logger, localPackage: myVer, channel: "stable"); | ||||
|         var locator = new TestVelopackLocator( | ||||
|             "MyCoolApp", | ||||
|             "1.2.0", | ||||
|             tempPath, | ||||
|             null, | ||||
|             null, | ||||
|             null, | ||||
|             logger: logger.ToVelopackLogger(), | ||||
|             localPackage: myVer, | ||||
|             channel: "stable"); | ||||
| 
 | ||||
|         // checking for same version should return null | ||||
|         var um = new UpdateManager(source, null, logger, locator); | ||||
|         var um = new UpdateManager(source, null, locator); | ||||
|         var info = um.CheckForUpdates(); | ||||
|         Assert.Null(info); | ||||
|         Assert.StartsWith("http://any.com/releases.stable.json?", dl.LastUrl); | ||||
| 
 | ||||
|         // checking for same version WITHOUT explicit channel should return null | ||||
|         var opt = new UpdateOptions { AllowVersionDowngrade = true }; | ||||
|         um = new UpdateManager(source, opt, logger, locator); | ||||
|         um = new UpdateManager(source, opt, locator); | ||||
|         Assert.Null(info); | ||||
|         Assert.StartsWith("http://any.com/releases.stable.json?", dl.LastUrl); | ||||
| 
 | ||||
|         // checking for same version with explicit channel & downgrade allowed should return version | ||||
|         opt = new UpdateOptions { ExplicitChannel = "experimental", AllowVersionDowngrade = true }; | ||||
|         um = new UpdateManager(source, opt, logger, locator); | ||||
|         um = new UpdateManager(source, opt, locator); | ||||
|         info = um.CheckForUpdates(); | ||||
|         Assert.True(info.IsDowngrade); | ||||
|         Assert.NotNull(info); | ||||
| @@ -233,17 +244,26 @@ public class UpdateManagerTests | ||||
|             Size = 1040561, | ||||
|         }; | ||||
|         var source = new SimpleWebSource("http://any.com", dl); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "2.0.0", tempPath, null, null, null, logger: logger, localPackage: myVer, channel: "stable"); | ||||
|         var locator = new TestVelopackLocator( | ||||
|             "MyCoolApp", | ||||
|             "2.0.0", | ||||
|             tempPath, | ||||
|             null, | ||||
|             null, | ||||
|             null, | ||||
|             logger: logger.ToVelopackLogger(), | ||||
|             localPackage: myVer, | ||||
|             channel: "stable"); | ||||
| 
 | ||||
|         // checking for lower version should return null | ||||
|         var um = new UpdateManager(source, null, logger, locator); | ||||
|         var um = new UpdateManager(source, null, locator); | ||||
|         var info = um.CheckForUpdates(); | ||||
|         Assert.Null(info); | ||||
|         Assert.StartsWith("http://any.com/releases.stable.json?", dl.LastUrl); | ||||
| 
 | ||||
|         // checking for lower version with downgrade allowed should return lower version | ||||
|         var opt = new UpdateOptions { AllowVersionDowngrade = true }; | ||||
|         um = new UpdateManager(source, opt, logger, locator); | ||||
|         um = new UpdateManager(source, opt, locator); | ||||
|         info = um.CheckForUpdates(); | ||||
|         Assert.True(info.IsDowngrade); | ||||
|         Assert.NotNull(info); | ||||
| @@ -268,8 +288,8 @@ public class UpdateManagerTests | ||||
|         }; | ||||
|         var source = new SimpleWebSource("http://any.com", dl); | ||||
| 
 | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, null, null, null, logger: logger, localPackage: myVer); | ||||
|         var um = new UpdateManager(source, null, logger, locator); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, null, null, null, logger: logger.ToVelopackLogger(), localPackage: myVer); | ||||
|         var um = new UpdateManager(source, null, locator); | ||||
|         var info = um.CheckForUpdates(); | ||||
|         Assert.False(info.IsDowngrade); | ||||
|         Assert.NotNull(info); | ||||
| @@ -287,8 +307,8 @@ public class UpdateManagerTests | ||||
|         using var _1 = TempUtil.GetTempDirectory(out var packagesDir); | ||||
|         var repo = new FakeFixtureRepository(id, false); | ||||
|         var source = new SimpleWebSource("http://any.com", repo); | ||||
|         var locator = new TestVelopackLocator(id, "1.0.0", packagesDir, logger); | ||||
|         var um = new UpdateManager(source, null, logger, locator); | ||||
|         var locator = new TestVelopackLocator(id, "1.0.0", packagesDir, logger.ToVelopackLogger()); | ||||
|         var um = new UpdateManager(source, null, locator); | ||||
| 
 | ||||
|         var info = um.CheckForUpdates(); | ||||
|         Assert.NotNull(info); | ||||
| @@ -321,8 +341,8 @@ public class UpdateManagerTests | ||||
|         using var _1 = TempUtil.GetTempDirectory(out var packagesDir); | ||||
|         var repo = new FakeFixtureRepository(id, false); | ||||
|         var source = new SimpleWebSource("http://any.com", repo); | ||||
|         var locator = new TestVelopackLocator(id, "1.0.0", packagesDir, logger); | ||||
|         var um = new UpdateManager(source, null, logger, locator); | ||||
|         var locator = new TestVelopackLocator(id, "1.0.0", packagesDir, logger.ToVelopackLogger()); | ||||
|         var um = new UpdateManager(source, null, locator); | ||||
| 
 | ||||
|         var info = um.CheckForUpdates(); | ||||
|         Assert.NotNull(info); | ||||
| @@ -352,8 +372,8 @@ public class UpdateManagerTests | ||||
|         using var _1 = TempUtil.GetTempDirectory(out var tempPath); | ||||
|         var dl = GetMockDownloaderWith2Delta(); | ||||
|         var source = new SimpleWebSource("http://any.com", dl); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger: logger); | ||||
|         var um = new UpdateManager(source, null, logger, locator); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger: logger.ToVelopackLogger()); | ||||
|         var um = new UpdateManager(source, null, locator); | ||||
|         var info = um.CheckForUpdates(); | ||||
|         Assert.NotNull(info); | ||||
|         Assert.False(info.IsDowngrade); | ||||
| @@ -368,8 +388,8 @@ public class UpdateManagerTests | ||||
|         using var _1 = TempUtil.GetTempDirectory(out var tempPath); | ||||
|         var dl = GetMockDownloaderWith2Delta(); | ||||
|         var source = new SimpleWebSource("http://any.com", dl); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger: logger); | ||||
|         var um = new UpdateManager(source, null, logger, locator); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger: logger.ToVelopackLogger()); | ||||
|         var um = new UpdateManager(source, null, locator); | ||||
|         var info = um.CheckForUpdates(); | ||||
|         Assert.NotNull(info); | ||||
|         Assert.False(info.IsDowngrade); | ||||
| @@ -383,48 +403,51 @@ public class UpdateManagerTests | ||||
|         // https://github.com/caesay/SquirrelCustomLauncherTestApp | ||||
|         using var logger = _output.BuildLoggerFor<UpdateManagerTests>(); | ||||
|         using var _1 = TempUtil.GetTempDirectory(out var tempPath); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger.ToVelopackLogger()); | ||||
|         var source = new GithubSource("https://github.com/caesay/SquirrelCustomLauncherTestApp", null, false); | ||||
|         var um = new UpdateManager(source, null, logger, locator); | ||||
|         var um = new UpdateManager(source, null, locator); | ||||
|         var info = um.CheckForUpdates(); | ||||
|         Assert.NotNull(info); | ||||
|         Assert.True(new SemanticVersion(1, 0, 1) == info.TargetFullRelease.Version); | ||||
|         Assert.Equal(0, info.DeltasToTarget.Count()); | ||||
|     } | ||||
| 
 | ||||
|     [Fact(Skip = "Consumes API Quota")] | ||||
|     public void CheckGithubWithNonExistingChannel() | ||||
|     { | ||||
|         // https://github.com/caesay/SquirrelCustomLauncherTestApp | ||||
|         using var logger = _output.BuildLoggerFor<UpdateManagerTests>(); | ||||
|         using var _1 = TempUtil.GetTempDirectory(out var tempPath); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger.ToVelopackLogger()); | ||||
|         var source = new GithubSource("https://github.com/caesay/SquirrelCustomLauncherTestApp", null, false); | ||||
|         var opt = new UpdateOptions { ExplicitChannel = "hello" }; | ||||
|         var um = new UpdateManager(source, opt, logger, locator); | ||||
|         var um = new UpdateManager(source, opt, locator); | ||||
|         Assert.Throws<ArgumentException>(() => um.CheckForUpdates()); | ||||
|     } | ||||
| 
 | ||||
|     [Fact(Skip = "Consumes API Quota")] | ||||
|     public void CheckGitea() | ||||
|     { | ||||
|         // https://github.com/caesay/SquirrelCustomLauncherTestApp | ||||
|         using var logger = _output.BuildLoggerFor<UpdateManagerTests>(); | ||||
|         using var _1 = TempUtil.GetTempDirectory(out var tempPath); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger.ToVelopackLogger()); | ||||
|         var source = new GiteaSource("https://gitea.com/remco1271/VeloPackTest", null, false); | ||||
|         var um = new UpdateManager(source, null, logger, locator); | ||||
|         var um = new UpdateManager(source, null, locator); | ||||
|         var info = um.CheckForUpdates(); | ||||
|         Assert.NotNull(info); | ||||
|         Assert.True(new SemanticVersion(1, 0, 1) == info.TargetFullRelease.Version); | ||||
|         Assert.Equal(0, info.DeltasToTarget.Count()); | ||||
|     } | ||||
| 
 | ||||
|     [Fact] | ||||
|     public void CheckFromEmptyFileSource() | ||||
|     { | ||||
|         using var logger = _output.BuildLoggerFor<UpdateManagerTests>(); | ||||
|         using var _1 = TempUtil.GetTempDirectory(out var tempPath); | ||||
|         var source = new SimpleFileSource(new DirectoryInfo(tempPath)); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger); | ||||
|         var um = new UpdateManager(source, null, logger, locator); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.0.0", tempPath, logger.ToVelopackLogger()); | ||||
|         var um = new UpdateManager(source, null, locator); | ||||
|         var info = um.CheckForUpdates(); | ||||
|         Assert.Null(info); | ||||
|     } | ||||
| @@ -436,8 +459,8 @@ public class UpdateManagerTests | ||||
|         using var _1 = TempUtil.GetTempDirectory(out var tempPath); | ||||
|         var dl = GetMockDownloaderNoDelta(); | ||||
|         var source = new SimpleWebSource("http://any.com", dl); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.1.0", tempPath, logger); | ||||
|         var um = new UpdateManager(source, null, logger, locator); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.1.0", tempPath, logger.ToVelopackLogger()); | ||||
|         var um = new UpdateManager(source, null, locator); | ||||
|         var info = um.CheckForUpdates(); | ||||
|         Assert.Null(info); | ||||
|     } | ||||
| @@ -449,8 +472,8 @@ public class UpdateManagerTests | ||||
|         using var _1 = TempUtil.GetTempDirectory(out var tempPath); | ||||
|         var dl = GetMockDownloaderNoDelta(); | ||||
|         var source = new SimpleWebSource("http://any.com", dl); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.2.0", tempPath, logger); | ||||
|         var um = new UpdateManager(source, null, logger, locator); | ||||
|         var locator = new TestVelopackLocator("MyCoolApp", "1.2.0", tempPath, logger.ToVelopackLogger()); | ||||
|         var um = new UpdateManager(source, null, locator); | ||||
|         var info = um.CheckForUpdates(); | ||||
|         Assert.Null(info); | ||||
|     } | ||||
| @@ -464,8 +487,8 @@ public class UpdateManagerTests | ||||
|         using var _1 = TempUtil.GetTempDirectory(out var packagesDir); | ||||
|         var repo = new FakeFixtureRepository(id, false); | ||||
|         var source = new SimpleWebSource("http://any.com", repo); | ||||
|         var locator = new TestVelopackLocator(id, "1.0.0", packagesDir, logger); | ||||
|         var um = new UpdateManager(source, null, logger, locator); | ||||
|         var locator = new TestVelopackLocator(id, "1.0.0", packagesDir, logger.ToVelopackLogger()); | ||||
|         var um = new UpdateManager(source, null, locator); | ||||
| 
 | ||||
|         var info = um.CheckForUpdates(); | ||||
|         Assert.NotNull(info); | ||||
| @@ -490,7 +513,7 @@ public class UpdateManagerTests | ||||
|         var repo = new FakeFixtureRepository(id, true); | ||||
|         var source = new SimpleWebSource("http://any.com", repo); | ||||
| 
 | ||||
|         var feed = await source.GetReleaseFeed(logger, VelopackRuntimeInfo.SystemOs.GetOsShortName()); | ||||
|         var feed = await source.GetReleaseFeed(logger.ToVelopackLogger(), id, VelopackRuntimeInfo.SystemOs.GetOsShortName()); | ||||
|         var basePkg = feed.Assets | ||||
|             .Where(x => x.Type == VelopackAssetType.Full) | ||||
|             .Single(x => x.Version == SemanticVersion.Parse(fromVersion)); | ||||
| @@ -499,9 +522,16 @@ public class UpdateManagerTests | ||||
|         File.Copy(basePkgFixturePath, basePkgPath); | ||||
| 
 | ||||
|         var updateExe = PathHelper.CopyUpdateTo(packagesDir); | ||||
|         var locator = new TestVelopackLocator(id, fromVersion, | ||||
|             packagesDir, null, null, updateExe, null, logger); | ||||
|         var um = new UpdateManager(source, null, logger, locator); | ||||
|         var locator = new TestVelopackLocator( | ||||
|             id, | ||||
|             fromVersion, | ||||
|             packagesDir, | ||||
|             null, | ||||
|             null, | ||||
|             updateExe, | ||||
|             null, | ||||
|             logger.ToVelopackLogger()); | ||||
|         var um = new UpdateManager(source, null, locator); | ||||
| 
 | ||||
|         var info = await um.CheckForUpdatesAsync(); | ||||
|         Assert.NotNull(info); | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
| using System.Runtime.Versioning; | ||||
| using System.Security.Cryptography; | ||||
| using System.Text; | ||||
| using Velopack.Core; | ||||
| using Velopack.Util; | ||||
| using Velopack.Windows; | ||||
| 
 | ||||
|   | ||||
| @@ -19,11 +19,11 @@ | ||||
|   </Choose> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <Compile Include="..\..\src\vpk\Velopack.Core\SimpleJson.cs" Link="SimpleJson.cs" /> | ||||
|     <PackageReference Include="System.IO.Packaging" Version="9.0.2"/> | ||||
|   </ItemGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <PackageReference Include="System.IO.Packaging" Version="9.0.2"/> | ||||
|     <ProjectReference Include="..\..\src\vpk\Velopack.Core\Velopack.Core.csproj"/> | ||||
|   </ItemGroup> | ||||
|  | ||||
|   <ItemGroup Condition=" $(TargetFramework.StartsWith('net4')) "> | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| using System.IO.Packaging; | ||||
| using NuGet.Versioning; | ||||
| using Velopack.Core; | ||||
| using Velopack.NuGet; | ||||
| using Velopack.Tests.TestHelpers; | ||||
| using Velopack.Util; | ||||
| @@ -38,8 +39,8 @@ public class ZipPackageTests | ||||
|         SymbolicLink.Create(symlink, actual); | ||||
|         SymbolicLink.Create(symfile, actualFile); | ||||
| 
 | ||||
|         Compression.EasyZip.CreateZipFromDirectoryAsync(logger, zipFile, tempDir).GetAwaiterResult(); | ||||
|         Compression.EasyZip.ExtractZipToDirectory(logger, zipFile, extractedDir, expandSymlinks: true); | ||||
|         Compression.EasyZip.CreateZipFromDirectoryAsync(logger.ToVelopackLogger(), zipFile, tempDir).GetAwaiterResult(); | ||||
|         Compression.EasyZip.ExtractZipToDirectory(logger.ToVelopackLogger(), zipFile, extractedDir, expandSymlinks: true); | ||||
| 
 | ||||
|         Assert.True(File.Exists(Path.Combine(extractedDir, "actual", "file.txt"))); | ||||
|         Assert.Equal("hello", File.ReadAllText(Path.Combine(extractedDir, "actual", "file.txt"))); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user