/ src / modules / launcher / Wox.Infrastructure / Storage / StoragePowerToysVersionInfo.cs
StoragePowerToysVersionInfo.cs
  1  // Copyright (c) Microsoft Corporation
  2  // The Microsoft Corporation licenses this file to you under the MIT license.
  3  // See the LICENSE file in the project root for more information.
  4  
  5  using System;
  6  using System.IO;
  7  using System.IO.Abstractions;
  8  
  9  using Wox.Plugin.Logger;
 10  
 11  namespace Wox.Infrastructure.Storage
 12  {
 13      public class StoragePowerToysVersionInfo
 14      {
 15          private static readonly IFileSystem FileSystem = new FileSystem();
 16          private static readonly IFile File = FileSystem.File;
 17  
 18          // This detail is accessed by the storage items and is used to decide if the cache must be deleted or not
 19          public bool ClearCache { get; set; }
 20  
 21          private readonly string currentPowerToysVersion = string.Empty;
 22  
 23          private string FilePath { get; set; } = string.Empty;
 24  
 25          // As of now this information is not pertinent but may be in the future
 26          // There may be cases when we want to delete only the .cache files and not the .json storage files
 27          private enum StorageType
 28          {
 29              BINARY_STORAGE = 0,
 30              JSON_STORAGE = 1,
 31          }
 32  
 33          // To compare the version numbers
 34          public static bool LessThan(string version1, string version2)
 35          {
 36              string version = "v";
 37              string period = ".";
 38              const int versionLength = 3;
 39  
 40              // If there is some error in populating/retrieving the version numbers, then the cache must be deleted
 41              // This case will not be hit, but is present as a fail safe
 42              if (string.IsNullOrEmpty(version1) || string.IsNullOrEmpty(version2))
 43              {
 44                  return true;
 45              }
 46  
 47              string[] split1 = version1.Split(new string[] { version, period }, StringSplitOptions.RemoveEmptyEntries);
 48              string[] split2 = version2.Split(new string[] { version, period }, StringSplitOptions.RemoveEmptyEntries);
 49  
 50              // If an incomplete file write resulted in the version number not being saved completely, then the cache must be deleted
 51              if (split1.Length != split2.Length || split1.Length != versionLength)
 52              {
 53                  return true;
 54              }
 55  
 56              for (int i = 0; i < versionLength; i++)
 57              {
 58                  if (int.TryParse(split1[i], out int version1AsInt) && int.TryParse(split2[i], out int version2AsInt))
 59                  {
 60                      if (version1AsInt < version2AsInt)
 61                      {
 62                          return true;
 63                      }
 64                  }
 65  
 66                  // If either of the values could not be parsed, the version number was not saved correctly and the cache must be deleted
 67                  else
 68                  {
 69                      return true;
 70                  }
 71              }
 72  
 73              return false;
 74          }
 75  
 76          public string GetPreviousVersion()
 77          {
 78              if (File.Exists(FilePath))
 79              {
 80                  return File.ReadAllText(FilePath);
 81              }
 82              else
 83              {
 84                  // which means it's an old version of PowerToys
 85                  string oldVersion = "v0.0.0";
 86                  return oldVersion;
 87              }
 88          }
 89  
 90          private static string GetFilePath(string associatedFilePath, int type)
 91          {
 92              string suffix = string.Empty;
 93              string cacheSuffix = ".cache";
 94              string jsonSuffix = ".json";
 95  
 96              if (type == (uint)StorageType.BINARY_STORAGE)
 97              {
 98                  suffix = cacheSuffix;
 99              }
100              else if (type == (uint)StorageType.JSON_STORAGE)
101              {
102                  suffix = jsonSuffix;
103              }
104  
105              string filePath = string.Concat(associatedFilePath.AsSpan(0, associatedFilePath.Length - suffix.Length), "_version.txt");
106              return filePath;
107          }
108  
109          public StoragePowerToysVersionInfo(string associatedFilePath, int type)
110          {
111              ArgumentNullException.ThrowIfNull(associatedFilePath);
112  
113              FilePath = GetFilePath(associatedFilePath, type);
114  
115              // Get the previous version of PowerToys and cache Storage details from the CacheDetails.json storage file
116              string previousVersion = GetPreviousVersion();
117              currentPowerToysVersion = Microsoft.PowerToys.Settings.UI.Library.Utilities.Helper.GetProductVersion();
118  
119              // If the previous version is below a set threshold, then we want to delete the file
120              // However, we do not want to delete the cache if the same version of powerToys is being launched
121              if (LessThan(previousVersion, currentPowerToysVersion))
122              {
123                  ClearCache = true;
124              }
125          }
126  
127          public void Close()
128          {
129              try
130              {
131                  // Update the Version file to the current version of powertoys
132                  File.WriteAllText(FilePath, currentPowerToysVersion);
133              }
134              catch (System.Exception e)
135              {
136                  Log.Exception($"Error in saving version at <{FilePath}>", e, GetType());
137              }
138          }
139      }
140  }