public void NoConflicts()
        {
            var accessPointA = new MockAccessPoint {
                ID = "a"
            };
            var appEntry1 = new AppEntry
            {
                Name         = "App1", InterfaceUri = FeedTest.Test1Uri,
                AccessPoints = new AccessPointList {
                    Entries = { accessPointA }
                }
            };
            var accessPointB = new MockAccessPoint {
                ID = "b"
            };
            var appEntry2 = new AppEntry {
                Name = "App2", InterfaceUri = FeedTest.Test2Uri
            };

            var appList = new AppList {
                Entries = { appEntry1 }
            };

            appList.CheckForConflicts(new[] { accessPointB }, appEntry2);
        }
        /// <inheritdoc/>
        protected override void RemoveAccessPointsInternal(AppEntry appEntry, IEnumerable <AccessPoint> accessPoints)
        {
            #region Sanity checks
            if (appEntry == null)
            {
                throw new ArgumentNullException("appEntry");
            }
            if (accessPoints == null)
            {
                throw new ArgumentNullException("accessPoints");
            }
            #endregion

            if (appEntry.AccessPoints == null)
            {
                return;
            }

            foreach (var accessPoint in accessPoints)
            {
                accessPoint.Unapply(appEntry, MachineWide);
            }

            // Remove the access points from the AppList
            appEntry.AccessPoints.Entries.RemoveRange(accessPoints);
            appEntry.Timestamp = DateTime.UtcNow;
        }
示例#3
0
        /// <inheritdoc/>
        public void RemoveAccessPoints(AppEntry appEntry, IEnumerable <AccessPoint> accessPoints)
        {
            #region Sanity checks
            if (appEntry == null)
            {
                throw new ArgumentNullException(nameof(appEntry));
            }
            if (accessPoints == null)
            {
                throw new ArgumentNullException(nameof(accessPoints));
            }
            #endregion

            try
            {
                RemoveAccessPointsInternal(appEntry, accessPoints);
            }
            catch (KeyNotFoundException ex)
            {
                // Wrap exception since only certain exception types are allowed
                throw new InvalidDataException(ex.Message, ex);
            }
            finally
            {
                Finish();
            }
        }
示例#4
0
        /// <inheritdoc/>
        public void UpdateApp(AppEntry appEntry, Feed feed, Requirements requirements)
        {
            #region Sanity checks
            if (appEntry == null)
            {
                throw new ArgumentNullException(nameof(appEntry));
            }
            if (feed == null)
            {
                throw new ArgumentNullException(nameof(feed));
            }
            if (requirements == null)
            {
                throw new ArgumentNullException(nameof(requirements));
            }
            #endregion

            try
            {
                appEntry.Requirements = requirements;
                UpdateAppInternal(appEntry, feed);
            }
            catch (KeyNotFoundException ex)
            {
                // Wrap exception since only certain exception types are allowed
                throw new InvalidDataException(ex.Message, ex);
            }
            finally
            {
                Finish();
            }
        }
        /// <summary>
        /// Tests the sync logic with pre-defined <see cref="AppList"/>s.
        /// local add: appEntry1, local remove: appEntry2, remote add: appEntry3, remote remove: appEntry4
        /// </summary>
        /// <param name="resetMode">The <see cref="SyncResetMode"/> to pass to <see cref="SyncIntegrationManager.Sync"/>.</param>
        /// <param name="ap1Applied">The flag file used to indicate that <see cref="MockAccessPoint.Apply"/> was called for appEntry1.</param>
        /// <param name="ap1NotApplied">The flag file used to indicate that <see cref="MockAccessPoint.Unapply"/> was called for appEntry1.</param>
        /// <param name="ap2Applied">The flag file used to indicate that <see cref="MockAccessPoint.Apply"/> was called for appEntry2.</param>
        /// <param name="ap2NotApplied">The flag file used to indicate that <see cref="MockAccessPoint.Unapply"/> was called for appEntry2.</param>
        /// <param name="ap3Applied">The flag file used to indicate that <see cref="MockAccessPoint.Apply"/> was called for appEntry3.</param>
        /// <param name="ap3NotApplied">The flag file used to indicate that <see cref="MockAccessPoint.Unapply"/> was called for appEntry3.</param>
        /// <param name="ap4Applied">The flag file used to indicate that <see cref="MockAccessPoint.Apply"/> was called for appEntry4.</param>
        /// <param name="ap4NotApplied">The flag file used to indicate that <see cref="MockAccessPoint.Unapply"/> was called for appEntry4.</param>
        private static void TestSync(SyncResetMode resetMode,
                                     TemporaryFlagFile ap1Applied,
                                     TemporaryFlagFile ap1NotApplied,
                                     TemporaryFlagFile ap2Applied,
                                     TemporaryFlagFile ap2NotApplied,
                                     TemporaryFlagFile ap3Applied,
                                     TemporaryFlagFile ap3NotApplied,
                                     TemporaryFlagFile ap4Applied,
                                     TemporaryFlagFile ap4NotApplied)
        {
            var appEntry1 = new AppEntry
            {
                InterfaceUri = FeedTest.Test1Uri,
                AccessPoints = new AccessPointList {
                    Entries = { new MockAccessPoint {
                                    ApplyFlagPath = ap1Applied, UnapplyFlagPath = ap1NotApplied
                                } }
                }
            };
            var appEntry2 = new AppEntry
            {
                InterfaceUri = FeedTest.Test2Uri,
                AccessPoints = new AccessPointList {
                    Entries = { new MockAccessPoint {
                                    ApplyFlagPath = ap2Applied, UnapplyFlagPath = ap2NotApplied
                                } }
                }
            };
            var appEntry3 = new AppEntry
            {
                InterfaceUri = FeedTest.Test3Uri,
                AccessPoints = new AccessPointList {
                    Entries = { new MockAccessPoint {
                                    ApplyFlagPath = ap3Applied, UnapplyFlagPath = ap3NotApplied
                                } }
                }
            };
            var appEntry4 = new AppEntry
            {
                InterfaceUri = new FeedUri("http://example.com/test4.xml"),
                AccessPoints = new AccessPointList {
                    Entries = { new MockAccessPoint {
                                    ApplyFlagPath = ap4Applied, UnapplyFlagPath = ap4NotApplied
                                } }
                }
            };
            var appListLocal = new AppList {
                Entries = { appEntry1, appEntry4 }
            };
            var appListLast = new AppList {
                Entries = { appEntry2, appEntry4 }
            };
            var appListServer = new AppList {
                Entries = { appEntry2, appEntry3 }
            };

            TestSync(resetMode, appListLocal, appListLast, appListServer);
        }
        public void AccessPointCandidatesInternalConflict()
        {
            var accessPoints = new AccessPoint[] { new MockAccessPoint {
                                                       ID = "a"
                                                   }, new MockAccessPoint {
                                                       ID = "a"
                                                   } };
            var appEntry = new AppEntry {
                Name = "App"
            };

            Assert.Throws <ConflictException>(() => accessPoints.GetConflictData(appEntry));
        }
示例#7
0
        public void AccessPointCandidatesInternalConflict()
        {
            var accessPoints = new AccessPoint[] { new MockAccessPoint {
                                                       ID = "a"
                                                   }, new MockAccessPoint {
                                                       ID = "a"
                                                   } };
            var appEntry = new AppEntry {
                Name = "App"
            };

            accessPoints.Invoking(x => x.GetConflictData(appEntry)).ShouldThrow <ConflictException>();
        }
示例#8
0
        /// <summary>
        /// Toggles registry entries indicating whether icons for the application are currently visible.
        /// </summary>
        /// <param name="appEntry">The application being modified.</param>
        /// <param name="iconsVisible"><c>true</c> if the icons are currently visible, <c>false</c> if the icons are currently not visible.</param>
        /// <remarks>This is a special handler to support <see cref="Windows.DefaultProgram"/>.</remarks>
        private static void ToggleIconsVisible(AppEntry appEntry, bool iconsVisible)
        {
            #region Sanity checks
            if (appEntry == null)
            {
                throw new ArgumentNullException(nameof(appEntry));
            }
            #endregion

            foreach (var defaultProgram in appEntry.CapabilityLists.CompatibleCapabilities().OfType <Store.Model.Capabilities.DefaultProgram>())
            {
                Windows.DefaultProgram.ToggleIconsVisible(defaultProgram, iconsVisible);
            }
        }
        /// <inheritdoc/>
        protected override void AddAccessPointsInternal(AppEntry appEntry, Feed feed, IEnumerable <AccessPoint> accessPoints)
        {
            #region Sanity checks
            if (appEntry == null)
            {
                throw new ArgumentNullException("appEntry");
            }
            if (feed == null)
            {
                throw new ArgumentNullException("feed");
            }
            if (accessPoints == null)
            {
                throw new ArgumentNullException("accessPoints");
            }
            if (appEntry.AccessPoints != null && appEntry.AccessPoints.Entries == accessPoints)
            {
                throw new ArgumentException("Must not be equal to appEntry.AccessPoints.Entries", "accessPoints");
            }
            #endregion

            // Skip entries with mismatching hostname
            if (appEntry.Hostname != null && !Regex.IsMatch(Environment.MachineName, appEntry.Hostname))
            {
                return;
            }

            if (appEntry.AccessPoints == null)
            {
                appEntry.AccessPoints = new AccessPointList();
            }

            AppList.CheckForConflicts(accessPoints, appEntry);

            accessPoints.ApplyWithRollback(
                accessPoint => accessPoint.Apply(appEntry, feed, Handler, MachineWide),
                accessPoint =>
            {
                // Don't perform rollback if the access point was already applied previously and this was only a refresh
                if (!appEntry.AccessPoints.Entries.Contains(accessPoint))
                {
                    accessPoint.Unapply(appEntry, MachineWide);
                }
            });

            appEntry.AccessPoints.Entries.RemoveRange(accessPoints); // Replace pre-existing entries
            appEntry.AccessPoints.Entries.AddRange(accessPoints);
            appEntry.Timestamp = DateTime.UtcNow;
        }
示例#10
0
        public void AccessPointCandidates()
        {
            var accessPoints = new AccessPoint[] { new MockAccessPoint {
                                                       ID = "a"
                                                   }, new MockAccessPoint {
                                                       ID = "b"
                                                   } };
            var appEntry = new AppEntry {
                Name = "App"
            };

            accessPoints.GetConflictData(appEntry).Should().Equal(new Dictionary <string, ConflictData>()
            {
                { "mock:a", new ConflictData(accessPoints[0], appEntry) },
                { "mock:b", new ConflictData(accessPoints[1], appEntry) }
            });
        }
示例#11
0
        public void TestAddApp()
        {
            var capabilityList = CapabilityListTest.CreateTestCapabilityList();
            var target         = new FeedTarget(FeedTest.Test1Uri, new Feed {
                Name = "Test", CapabilityLists = { capabilityList }
            });

            _integrationManager.AddApp(target);

            var expectedAppEntry = new AppEntry {
                InterfaceUri = FeedTest.Test1Uri, Name = target.Feed.Name, CapabilityLists = { capabilityList }
            };

            CollectionAssert.AreEqual(new[] { expectedAppEntry }, _integrationManager.AppList.Entries);

            Assert.Throws <InvalidOperationException>(() => _integrationManager.AddApp(target), "Do not allow adding applications to AppList more than once.");
        }
示例#12
0
        public void TestFindAppAlias()
        {
            var appAlias = new AppAlias {
                Name = "foobar"
            };
            var appEntry = new AppEntry {
                AccessPoints = new AccessPointList {
                    Entries = { appAlias }
                }
            };
            var appList = new AppList {
                Entries = { appEntry }
            };

            appList.FindAppAlias("foobar").Should().Be((appAlias, appEntry));

            appList.FindAppAlias("other").Should().BeNull();
        }
        /// <inheritdoc/>
        protected override void UpdateAppInternal(AppEntry appEntry, Feed feed)
        {
            #region Sanity checks
            if (appEntry == null)
            {
                throw new ArgumentNullException("appEntry");
            }
            if (feed == null)
            {
                throw new ArgumentNullException("feed");
            }
            #endregion

            // Temporarily remove capability-based access points but remember them for later reapplication
            var toReapply = new List <AccessPoint>();
            if (appEntry.AccessPoints != null)
            {
                toReapply.AddRange(appEntry.AccessPoints.Entries.Where(accessPoint => accessPoint is DefaultAccessPoint || accessPoint is CapabilityRegistration));
            }
            RemoveAccessPointsInternal(appEntry, toReapply);

            // Update metadata and capabilities
            appEntry.Name = feed.Name;
            appEntry.CapabilityLists.Clear();
            appEntry.CapabilityLists.AddRange(feed.CapabilityLists.CloneElements());

            // Reapply removed access points dumping any that have become incompatible
            foreach (var accessPoint in toReapply)
            {
                try
                {
                    AddAccessPointsInternal(appEntry, feed, new[] { accessPoint });
                }
                #region Error handling
                catch (KeyNotFoundException)
                {
                    Log.Warn(string.Format("Access point '{0}' no longer compatible with interface '{1}'.", accessPoint, appEntry.InterfaceUri));
                }
                #endregion
            }

            WriteAppDir(appEntry);
            appEntry.Timestamp = DateTime.UtcNow;
        }
        //--------------------//

        #region Apps
        /// <inheritdoc/>
        protected override AppEntry AddAppInternal(FeedTarget target)
        {
            // Prevent double entries
            if (AppList.ContainsEntry(target.Uri))
            {
                throw new InvalidOperationException(string.Format(Resources.AppAlreadyInList, target.Feed.Name));
            }

            // Get basic metadata and copy of capabilities from feed
            var appEntry = new AppEntry {
                InterfaceUri = target.Uri, Name = target.Feed.Name, Timestamp = DateTime.UtcNow
            };

            appEntry.CapabilityLists.AddRange(target.Feed.CapabilityLists.CloneElements());

            AppList.Entries.Add(appEntry);
            WriteAppDir(appEntry);
            return(appEntry);
        }
        public void AccessPointCandidates()
        {
            var accessPoints = new AccessPoint[] { new MockAccessPoint {
                                                       ID = "a"
                                                   }, new MockAccessPoint {
                                                       ID = "b"
                                                   } };
            var appEntry = new AppEntry {
                Name = "App"
            };

            CollectionAssert.AreEqual(
                expected: new[]
            {
                new KeyValuePair <string, ConflictData>("mock:a", new ConflictData(accessPoints[0], appEntry)),
                new KeyValuePair <string, ConflictData>("mock:b", new ConflictData(accessPoints[1], appEntry))
            },
                actual: accessPoints.GetConflictData(appEntry));
        }
示例#16
0
        public void TestSearch()
        {
            var appA = new AppEntry {
                InterfaceUri = FeedTest.Test1Uri, Name = "AppA"
            };
            var appB = new AppEntry {
                InterfaceUri = FeedTest.Test2Uri, Name = "AppB"
            };
            var lib = new AppEntry {
                InterfaceUri = FeedTest.Test3Uri, Name = "Lib"
            };
            var appList = new AppList {
                Entries = { appA, appB, lib }
            };

            appList.Search("").Should().Equal(appA, appB, lib);
            appList.Search("App").Should().Equal(appA, appB);
            appList.Search("AppA").Should().Equal(appA);
            appList.Search("AppB").Should().Equal(appB);
        }
        /// <inheritdoc/>
        protected override void RepairAppInternal(AppEntry appEntry, Feed feed)
        {
            #region Sanity checks
            if (appEntry == null)
            {
                throw new ArgumentNullException("appEntry");
            }
            if (feed == null)
            {
                throw new ArgumentNullException("feed");
            }
            #endregion

            var toReAdd = (appEntry.AccessPoints == null)
                ? Enumerable.Empty <AccessPoint>()
                : appEntry.AccessPoints.Entries.ToList();
            AddAccessPointsInternal(appEntry, feed, toReAdd);

            WriteAppDir(appEntry);
        }
示例#18
0
        public void TestSearch()
        {
            var appA = new AppEntry {
                InterfaceUri = FeedTest.Test1Uri, Name = "AppA"
            };
            var appB = new AppEntry {
                InterfaceUri = FeedTest.Test2Uri, Name = "AppB"
            };
            var lib = new AppEntry {
                InterfaceUri = FeedTest.Test3Uri, Name = "Lib"
            };
            var appList = new AppList {
                Entries = { appA, appB, lib }
            };

            CollectionAssert.AreEqual(expected: new[] { appA, appB, lib }, actual: appList.Search(""));
            CollectionAssert.AreEqual(expected: new[] { appA, appB }, actual: appList.Search("App"));
            CollectionAssert.AreEqual(expected: new[] { appA }, actual: appList.Search("AppA"));
            CollectionAssert.AreEqual(expected: new[] { appB }, actual: appList.Search("AppB"));
        }
        /// <inheritdoc/>
        protected override void AddAppInternal(AppEntry prototype, Converter <FeedUri, Feed> feedRetriever)
        {
            #region Sanity checks
            if (prototype == null)
            {
                throw new ArgumentNullException("prototype");
            }
            if (feedRetriever == null)
            {
                throw new ArgumentNullException("feedRetriever");
            }
            #endregion

            var appEntry = prototype.Clone();
            AppList.Entries.Add(appEntry);
            WriteAppDir(appEntry);

            if (appEntry.AccessPoints != null)
            {
                AddAccessPointsInternal(appEntry, feedRetriever(appEntry.InterfaceUri), appEntry.AccessPoints.Clone().Entries);
            }
        }
        /// <inheritdoc/>
        protected override void RemoveAppInternal(AppEntry appEntry)
        {
            #region Sanity checks
            if (appEntry == null)
            {
                throw new ArgumentNullException("appEntry");
            }
            #endregion

            DeleteAppDir(appEntry);

            if (appEntry.AccessPoints != null)
            {
                // Unapply any remaining access points
                foreach (var accessPoint in appEntry.AccessPoints.Entries)
                {
                    accessPoint.Unapply(appEntry, MachineWide);
                }
            }

            AppList.Entries.Remove(appEntry);
        }
示例#21
0
        /// <inheritdoc/>
        public void RemoveApp(AppEntry appEntry)
        {
            #region Sanity checks
            if (appEntry == null)
            {
                throw new ArgumentNullException("appEntry");
            }
            #endregion

            try
            {
                RemoveAppInternal(appEntry);
            }
            catch (KeyNotFoundException ex)
            {
                // Wrap exception since only certain exception types are allowed
                throw new InvalidDataException(ex.Message, ex);
            }
            finally
            {
                Finish();
            }
        }
        public void Conflict()
        {
            var accessPointA = new MockAccessPoint {
                ID = "a"
            };
            var appEntry1 = new AppEntry
            {
                Name         = "App1",
                InterfaceUri = FeedTest.Test1Uri,
                AccessPoints = new AccessPointList {
                    Entries = { accessPointA }
                }
            };
            var appEntry2 = new AppEntry {
                Name = "App2", InterfaceUri = FeedTest.Test2Uri
            };

            var appList = new AppList {
                Entries = { appEntry1 }
            };

            Assert.Throws <ConflictException>(() => appList.CheckForConflicts(new[] { accessPointA }, appEntry2));
        }
示例#23
0
        public void Conflict()
        {
            var accessPointA = new MockAccessPoint {
                ID = "a"
            };
            var appEntry1 = new AppEntry
            {
                Name         = "App1",
                InterfaceUri = FeedTest.Test1Uri,
                AccessPoints = new AccessPointList {
                    Entries = { accessPointA }
                }
            };
            var appEntry2 = new AppEntry {
                Name = "App2", InterfaceUri = FeedTest.Test2Uri
            };

            var appList = new AppList {
                Entries = { appEntry1 }
            };

            appList.Invoking(x => x.CheckForConflicts(new[] { accessPointA }, appEntry2))
            .ShouldThrow <ConflictException>();
        }
示例#24
0
 /// <summary>
 /// Reapplies all <see cref="AccessPoint"/>s for a specific <see cref="AppEntry"/>.
 /// </summary>
 /// <param name="appEntry">The application entry to repair.</param>
 /// <param name="feed">The feed providing additional metadata, capabilities, etc. for the application.</param>
 /// <exception cref="OperationCanceledException">The user canceled the task.</exception>
 /// <exception cref="ConflictException"><paramref name="appEntry"/> conflicts with the rest of the <see cref="AppList"/>.</exception>
 /// <exception cref="InvalidDataException">One of the <see cref="AccessPoint"/>s or <see cref="Capability"/>s is invalid.</exception>
 /// <exception cref="WebException">A problem occurred while downloading additional data (such as icons).</exception>
 /// <exception cref="IOException">A problem occurred while writing to the filesystem or registry.</exception>
 /// <exception cref="UnauthorizedAccessException">Write access to the filesystem or registry is not permitted.</exception>
 protected abstract void RepairAppInternal(AppEntry appEntry, Feed feed);
示例#25
0
 /// <summary>
 /// Removes already applied <see cref="AccessPoint"/>s for an application.
 /// </summary>
 /// <param name="appEntry">The <see cref="AppEntry"/> containing the <paramref name="accessPoints"/>.</param>
 /// <param name="accessPoints">The access points to unapply.</param>
 /// <exception cref="KeyNotFoundException">An <see cref="AccessPoint"/> reference to a <see cref="Capability"/> is invalid.</exception>
 /// <exception cref="InvalidDataException">One of the <see cref="AccessPoint"/>s or <see cref="Capability"/>s is invalid.</exception>
 /// <exception cref="IOException">A problem occurred while writing to the filesystem or registry.</exception>
 /// <exception cref="UnauthorizedAccessException">Write access to the filesystem or registry is not permitted.</exception>
 protected abstract void RemoveAccessPointsInternal(AppEntry appEntry, IEnumerable <AccessPoint> accessPoints);
示例#26
0
 /// <summary>
 /// Applies <see cref="AccessPoint"/>s for an application.
 /// </summary>
 /// <param name="appEntry">The application being integrated.</param>
 /// <param name="feed">The feed providing additional metadata, icons, etc. for the application.</param>
 /// <param name="accessPoints">The access points to apply.</param>
 /// <exception cref="ArgumentException"><see cref="AccessPointList.Entries"/> from <paramref name="appEntry"/> is the same reference as <paramref name="accessPoints"/>.</exception>
 /// <exception cref="OperationCanceledException">The user canceled the task.</exception>
 /// <exception cref="KeyNotFoundException">An <see cref="AccessPoint"/> reference to a <see cref="Capability"/> is invalid.</exception>
 /// <exception cref="ConflictException">One or more of the <paramref name="accessPoints"/> would cause a conflict with the existing <see cref="AccessPoint"/>s in <see cref="IIntegrationManager.AppList"/>.</exception>
 /// <exception cref="InvalidDataException">One of the <see cref="AccessPoint"/>s or <see cref="Capability"/>s is invalid.</exception>
 /// <exception cref="WebException">A problem occurred while downloading additional data (such as icons).</exception>
 /// <exception cref="IOException">A problem occurred while writing to the filesystem or registry.</exception>
 /// <exception cref="UnauthorizedAccessException">Write access to the filesystem or registry is not permitted.</exception>
 protected abstract void AddAccessPointsInternal(AppEntry appEntry, Feed feed, IEnumerable <AccessPoint> accessPoints);
示例#27
0
 /// <summary>
 /// Updates an <see cref="AppEntry"/> with new metadata and capabilities from a <see cref="Feed"/>. This may unapply and remove some existing <see cref="AccessPoint"/>s.
 /// </summary>
 /// <exception cref="KeyNotFoundException">An <see cref="AccessPoint"/> reference to a <see cref="Capability"/> is invalid.</exception>
 /// <exception cref="InvalidDataException">One of the <see cref="AccessPoint"/>s or <see cref="Capability"/>s is invalid.</exception>
 /// <param name="appEntry">The application entry to update.</param>
 /// <param name="feed">The feed providing additional metadata, capabilities, etc. for the application.</param>
 protected abstract void UpdateAppInternal(AppEntry appEntry, Feed feed);
示例#28
0
 /// <summary>
 /// Removes an <see cref="AppEntry"/> from the <see cref="AppList"/> while unapplying any remaining <see cref="AccessPoint"/>s.
 /// </summary>
 /// <param name="appEntry">The application to remove.</param>
 /// <exception cref="KeyNotFoundException">An <see cref="AccessPoint"/> reference to a <see cref="Capability"/> is invalid.</exception>
 /// <exception cref="InvalidDataException">One of the <see cref="AccessPoint"/>s or <see cref="Capability"/>s is invalid.</exception>
 /// <exception cref="IOException">A problem occurred while writing to the filesystem or registry.</exception>
 /// <exception cref="UnauthorizedAccessException">Write access to the filesystem or registry is not permitted.</exception>
 protected abstract void RemoveAppInternal(AppEntry appEntry);
示例#29
0
 /// <summary>
 /// Creates a new <see cref="AppEntry"/> based on an existing prototype (applying any <see cref="AccessPoint"/>s) and adds it to the <see cref="AppList"/>.
 /// </summary>
 /// <param name="prototype">An existing <see cref="AppEntry"/> to use as a prototype.</param>
 /// <param name="feedRetriever">Callback method used to retrieve additional <see cref="Feed"/>s on demand.</param>
 protected abstract void AddAppInternal(AppEntry prototype, Converter <FeedUri, Feed> feedRetriever);
示例#30
0
 /// <summary>
 /// Reapplies all <see cref="AccessPoint"/>s for a specific <see cref="AppEntry"/>.
 /// </summary>
 /// <param name="appEntry">The application entry to repair.</param>
 /// <param name="feed">The feed providing additional metadata, capabilities, etc. for the application.</param>
 /// <exception cref="OperationCanceledException">The user canceled the task.</exception>
 /// <exception cref="ConflictException"><paramref name="appEntry"/> conflicts with the rest of the <see cref="AppList"/>.</exception>
 /// <exception cref="InvalidDataException">One of the <see cref="AccessPoint"/>s or <see cref="Store.Model.Capabilities.Capability"/>s is invalid.</exception>
 /// <exception cref="WebException">A problem occured while downloading additional data (such as icons).</exception>
 /// <exception cref="IOException">A problem occurs while writing to the filesystem or registry.</exception>
 /// <exception cref="UnauthorizedAccessException">Write access to the filesystem or registry is not permitted.</exception>
 protected abstract void RepairAppInternal([NotNull] AppEntry appEntry, [NotNull] Feed feed);