AppCache.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.Collections.Generic;
  7  using System.Threading.Tasks;
  8  using Microsoft.CmdPal.Ext.Apps.Programs;
  9  using Microsoft.CmdPal.Ext.Apps.Storage;
 10  using Microsoft.CmdPal.Ext.Apps.Utils;
 11  
 12  namespace Microsoft.CmdPal.Ext.Apps;
 13  
 14  public sealed partial class AppCache : IAppCache, IDisposable
 15  {
 16      private Win32ProgramFileSystemWatchers _win32ProgramRepositoryHelper;
 17  
 18      private PackageRepository _packageRepository;
 19  
 20      private Win32ProgramRepository _win32ProgramRepository;
 21  
 22      private bool _disposed;
 23  
 24      public IList<Win32Program> Win32s => _win32ProgramRepository.Items;
 25  
 26      public IList<IUWPApplication> UWPs => _packageRepository.Items;
 27  
 28      public static readonly Lazy<AppCache> Instance = new(() => new());
 29  
 30      public AppCache()
 31      {
 32          _win32ProgramRepositoryHelper = new Win32ProgramFileSystemWatchers();
 33  
 34          var watchers = new List<IFileSystemWatcherWrapper>(_win32ProgramRepositoryHelper.FileSystemWatchers);
 35  
 36          _win32ProgramRepository = new Win32ProgramRepository(watchers, AllAppsSettings.Instance, _win32ProgramRepositoryHelper.PathsToWatch);
 37  
 38          _packageRepository = new PackageRepository(new PackageCatalogWrapper());
 39  
 40          var a = Task.Run(() =>
 41          {
 42              _win32ProgramRepository.IndexPrograms();
 43          });
 44  
 45          var b = Task.Run(() =>
 46          {
 47              _packageRepository.IndexPrograms();
 48              UpdateUWPIconPath(ThemeHelper.GetCurrentTheme());
 49          });
 50  
 51          try
 52          {
 53              Task.WaitAll(a, b);
 54          }
 55          catch (AggregateException ex)
 56          {
 57              ManagedCommon.Logger.LogError("One or more errors occurred while indexing apps");
 58  
 59              foreach (var inner in ex.InnerExceptions)
 60              {
 61                  ManagedCommon.Logger.LogError(inner.Message, inner);
 62              }
 63          }
 64  
 65          AllAppsSettings.Instance.LastIndexTime = DateTime.Today;
 66      }
 67  
 68      private void UpdateUWPIconPath(Theme theme)
 69      {
 70          if (_packageRepository is not null)
 71          {
 72              foreach (UWPApplication app in _packageRepository)
 73              {
 74                  try
 75                  {
 76                      app.UpdateLogoPath(theme);
 77                  }
 78                  catch (Exception ex)
 79                  {
 80                      ManagedCommon.Logger.LogError($"Failed to update icon path for app {app.Name}", ex);
 81                  }
 82              }
 83          }
 84      }
 85  
 86      public bool ShouldReload() => _packageRepository.ShouldReload() || _win32ProgramRepository.ShouldReload();
 87  
 88      public void ResetReloadFlag()
 89      {
 90          _packageRepository.ResetReloadFlag();
 91          _win32ProgramRepository.ResetReloadFlag();
 92      }
 93  
 94      public void Dispose()
 95      {
 96          Dispose(disposing: true);
 97          GC.SuppressFinalize(this);
 98      }
 99  
100      private void Dispose(bool disposing)
101      {
102          if (!_disposed)
103          {
104              if (disposing)
105              {
106                  _win32ProgramRepositoryHelper?.Dispose();
107                  _disposed = true;
108              }
109          }
110      }
111  }