예제 #1
0
 private AppList LoadAppListSafe()
 {
     try
     {
         return(XmlStorage.LoadXml <AppList>(AppList.GetDefaultPath(_machineWide)));
     }
     #region Error handling
     catch (FileNotFoundException)
     {
         return(new AppList());
     }
     catch (IOException ex)
     {
         Log.Warn(Resources.UnableToLoadAppList);
         Log.Warn(ex);
         return(new AppList());
     }
     catch (UnauthorizedAccessException ex)
     {
         Log.Warn(Resources.UnableToLoadAppList);
         Log.Warn(ex);
         return(new AppList());
     }
     catch (InvalidDataException ex)
     {
         Log.Warn(Resources.UnableToLoadAppList);
         Log.Warn(ex);
         return(new AppList());
     }
     #endregion
 }
예제 #2
0
    /// <summary>
    /// Tests the sync logic with custom <see cref="AppList"/>s.
    /// </summary>
    /// <param name="resetMode">The <see cref="SyncResetMode"/> to pass to <see cref="SyncIntegrationManager.Sync"/>.</param>
    /// <param name="appListLocal">The current local <see cref="AppList"/>.</param>
    /// <param name="appListLast">The state of the <see cref="AppList"/> after the last successful sync.</param>
    /// <param name="appListServer">The current server-side <see cref="AppList"/>.</param>
    private static void TestSync(SyncResetMode resetMode, AppList appListLocal, AppList?appListLast, AppList appListServer)
    {
        string appListLocalPath = AppList.GetDefaultPath();

        appListLocal.SaveXml(appListLocalPath);
        appListLast?.SaveXml(appListLocalPath + SyncIntegrationManager.AppListLastSyncSuffix);

        using var appListServerPath = new TemporaryFile("0install-test-applist");
        {
            using (var stream = File.Create(appListServerPath))
                appListServer.SaveXmlZip(stream, CryptoKey);

            using (var appListServerFile = File.OpenRead(appListServerPath))
            {
                using var syncServer = new MicroServer("app-list", appListServerFile);
                var config = new Config
                {
                    SyncServer         = new(syncServer.ServerUri),
                    SyncServerUsername = "******",
                    SyncServerPassword = "******",
                    SyncCryptoKey      = CryptoKey
                };
                using (var integrationManager = new SyncIntegrationManager(config, _ => new Feed(), new SilentTaskHandler()))
                    integrationManager.Sync(resetMode);

                appListServer = AppList.LoadXmlZip(syncServer.FileContent, CryptoKey);
            }
        }

        appListLocal = XmlStorage.LoadXml <AppList>(appListLocalPath);
        appListLast  = XmlStorage.LoadXml <AppList>(appListLocalPath + SyncIntegrationManager.AppListLastSyncSuffix);
        appListServer.Should().Be(appListLocal, because: "Server and local data should be equal after sync");
        appListLast.Should().Be(appListLocal, because: "Last sync snapshot and local data should be equal after sync");
    }
예제 #3
0
        public void GetInstalledPackages([CanBeNull] string name)
        {
            var appList = XmlStorage.LoadXml <AppList>(AppList.GetDefaultPath(MachineWide));

            foreach (var entry in appList.Search(name))
            {
                Yield(entry.EffectiveRequirements);
            }
        }
예제 #4
0
        /// <inheritdoc/>
        public override ExitCode Execute()
        {
            if (!Handler.Ask(Resources.ConfirmRemoveAll, defaultAnswer: true))
            {
                return(ExitCode.NoChanges);
            }

            using var integrationManager = new IntegrationManager(Config, Handler, MachineWide);
            Handler.RunTask(ForEachTask.Create(Resources.RemovingApplications, integrationManager.AppList.Entries.ToList(), integrationManager.RemoveApp));

            // Purge sync status, otherwise next sync would remove everything from server as well instead of restoring from there
            File.Delete(AppList.GetDefaultPath(MachineWide) + SyncIntegrationManager.AppListLastSyncSuffix);

            return(ExitCode.OK);
        }
예제 #5
0
        /// <summary>
        /// Removes all applications from the <see cref="AppList"/> and undoes any desktop environment integration.
        /// </summary>
        /// <param name="handler">A callback object used when the the user is to be informed about the progress of long-running operations such as downloads.</param>
        /// <param name="machineWide">Apply the operation machine-wide instead of just for the current user.</param>
        public static void RemoveAllApps(ITaskHandler handler, bool machineWide)
        {
            #region Sanity checks
            if (handler == null)
            {
                throw new ArgumentNullException(nameof(handler));
            }
            #endregion

            using (var integrationManager = new IntegrationManager(handler, machineWide))
            {
                handler.RunTask(ForEachTask.Create(Resources.RemovingApplications, integrationManager.AppList.Entries.ToList(), integrationManager.RemoveApp));

                // Purge sync status, otherwise next sync would remove everything from server as well instead of restoring from there
                File.Delete(AppList.GetDefaultPath(machineWide) + SyncIntegrationManager.AppListLastSyncSuffix);
            }
        }
예제 #6
0
        public void TestGetCanonicalUriAliases()
        {
            // Fake an alias
            new AppList
            {
                Entries =
                {
                    new AppEntry
                    {
                        InterfaceUri = FeedTest.Test1Uri,
                        AccessPoints = new AccessPointList{
                            Entries ={ new AppAlias                   {
                          Name = "test"
                      } }
                        }
                    }
                }
            }.SaveXml(AppList.GetDefaultPath());

            Target.GetCanonicalUri("alias:test").Should().Be(FeedTest.Test1Uri);
            Target.Invoking(x => x.GetCanonicalUri("alias:invalid")).ShouldThrow <UriFormatException>();
        }
예제 #7
0
        public void TestGetCanonicalUriAliases()
        {
            // Fake an alias
            new AppList
            {
                Entries =
                {
                    new AppEntry
                    {
                        InterfaceUri = Fake.Feed1Uri,
                        AccessPoints = new AccessPointList{
                            Entries ={ new AppAlias                   {
                          Name = "test"
                      } }
                        }
                    }
                }
            }.SaveXml(AppList.GetDefaultPath());

            Sut.GetCanonicalUri("alias:test").Should().Be(Fake.Feed1Uri);
            Assert.Throws <UriFormatException>(() => Sut.GetCanonicalUri("alias:invalid"));
        }
예제 #8
0
        public void TestGetCanonicalUriAliases()
        {
            // Fake an alias
            new AppList
            {
                Entries =
                {
                    new AppEntry
                    {
                        InterfaceUri = FeedTest.Test1Uri,
                        AccessPoints = new AccessPointList{
                            Entries ={ new AppAlias                   {
                          Name = "test"
                      } }
                        }
                    }
                }
            }.SaveXml(AppList.GetDefaultPath());

            Assert.AreEqual(FeedTest.Test1Uri, Target.GetCanonicalUri("alias:test"));
            Assert.Throws <UriFormatException>(() => Target.GetCanonicalUri("alias:invalid"));
        }
예제 #9
0
    /// <summary>
    /// Creates a new integration manager using the default <see cref="DesktopIntegration.AppList"/> (creating a new one if missing). Performs Mutex-based locking!
    /// </summary>
    /// <param name="config">User settings controlling network behaviour.</param>
    /// <param name="handler">A callback object used when the the user is to be informed about the progress of long-running operations such as downloads.</param>
    /// <param name="machineWide">Apply operations machine-wide instead of just for the current user.</param>
    /// <exception cref="IOException">A problem occurred while accessing the <see cref="AppList"/> file.</exception>
    /// <exception cref="UnauthorizedAccessException">Read or write access to the <see cref="AppList"/> file is not permitted or another desktop integration class is currently active.</exception>
    /// <exception cref="InvalidDataException">A problem occurred while deserializing the XML data.</exception>
    public IntegrationManager(Config config, ITaskHandler handler, bool machineWide = false)
        : base(handler, machineWide)
    {
        Config = config ?? throw new ArgumentNullException(nameof(config));

        try
        {
            AcquireMutex();
        }
        catch (TimeoutException)
        {
            throw new UnauthorizedAccessException(Resources.IntegrationMutex);
        }

        try
        {
            AppListPath = AppList.GetDefaultPath(machineWide);
            if (File.Exists(AppListPath))
            {
                Log.Debug("Loading AppList for IntegrationManager from: " + AppListPath);
                AppList = XmlStorage.LoadXml <AppList>(AppListPath);
            }
            else
            {
                Log.Debug("Creating new AppList for IntegrationManager: " + AppListPath);
                AppList = new AppList();
                AppList.SaveXml(AppListPath);
            }
        }
        #region Error handling
        catch
        {
            // Avoid abandoned mutexes
            Dispose();
            throw;
        }
        #endregion
    }
예제 #10
0
        /// <inheritdoc/>
        public override ExitCode Execute()
        {
            using (var integrationManager = new IntegrationManager(Handler, MachineWide))
            {
                if (AppList.Entries.Count == 0)
                {
                    return(ExitCode.OK);
                }

                if (Handler.Ask(Resources.ConfirmRemoveAll, defaultAnswer: true))
                {
                    Handler.RunTask(new ForEachTask <AppEntry>(Resources.RemovingApplications, AppList.Entries, integrationManager.RemoveApp));

                    // Purge sync status, otherwise next sync would remove everything from server as well instead of restoring from there
                    File.Delete(AppList.GetDefaultPath(MachineWide) + SyncIntegrationManager.AppListLastSyncSuffix);
                }
                else
                {
                    throw new OperationCanceledException();
                }
            }

            return(ExitCode.OK);
        }