private async void AddApp() { labelStatus.Text = SharedResources.Working; var exitCode = await Program.RunCommandAsync(_machineWide, Commands.Desktop.AddApp.Name, "--background", _interfaceUri.ToStringRfc()); if (exitCode == ExitCode.OK) { SetStatus(AppStatus.Added); } else { Close(); } }
/// <inheritdoc/> public void ImportFeed(string path, FeedUri uri, FeedUri mirrorUrl = null) { #region Sanity checks if (uri == null) { throw new ArgumentNullException("uri"); } if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } #endregion if (uri.IsFile) { throw new UriFormatException(Resources.FeedUriLocal); } Log.Debug("Importing feed " + uri.ToStringRfc() + " from: " + path); var data = File.ReadAllBytes(path); var newSignature = _trustManager.CheckTrust(data, uri, mirrorUrl); DetectAttacks(data, uri, newSignature); // Add to cache and remember time _feedCache.Add(uri, data); var preferences = FeedPreferences.LoadForSafe(uri); preferences.LastChecked = DateTime.UtcNow; preferences.Normalize(); preferences.SaveFor(uri); }
/// <inheritdoc/> public async Task IntegrateAsync(FeedUri uri, IEnumerable <string>?add = null, IEnumerable <string>?remove = null, bool machineWide = false) { var args = new List <string> { "integrate", "--batch", uri.ToStringRfc() }; if (machineWide) { args.Add("--machine"); } void AddToArgs(string option, IEnumerable <string>?elements) { if (elements == null) { return; } foreach (string category in elements) { args.Add(option); args.Add(category); } } AddToArgs("--add", add); AddToArgs("--remove", remove); await Task.Run(() => _launcher.RunAndCapture(args.ToArray())); }
/// <summary> /// Asks the user whether they trust a given key for a specific domain. May automatically accept based on policy. /// </summary> /// <param name="uri">The URI the signed file originally came from.</param> /// <param name="fingerprint">The fingerprint of the key to trust.</param> /// <param name="domain">The domain to trust the key for.</param> /// <returns><c>true</c> if the user decided to trust the key, <c>false</c> if they decided not to trust the key.</returns> /// <exception cref="OperationCanceledException">The user canceled the task.</exception> private bool AskKeyApproval(FeedUri uri, string fingerprint, Domain domain) { (bool goodVote, string?keyInformation) = GetKeyInformation(fingerprint); // Automatically trust key for _new_ feeds if voted good by key server if (_config.AutoApproveKeys && goodVote && !_feedCache.Contains(uri)) { Log.Info("Auto-approving key for " + uri.ToStringRfc()); return(true); } // Otherwise ask user return(_handler.Ask( string.Format(Resources.AskKeyTrust, uri.ToStringRfc(), fingerprint, keyInformation ?? Resources.NoKeyInfoServerData, domain), defaultAnswer: false, alternateMessage: Resources.UntrustedKeys)); }
/// <inheritdoc/> public void Add(FeedUri feedUri, byte[] data) { #region Sanity checks if (feedUri == null) { throw new ArgumentNullException(nameof(feedUri)); } if (data == null) { throw new ArgumentNullException(nameof(data)); } #endregion if (!Directory.Exists(Path)) { Directory.CreateDirectory(Path); } try { string path = System.IO.Path.Combine(Path, feedUri.Escape()); Log.Debug($"Adding feed {feedUri.ToStringRfc()} to disk cache: {path}"); WriteToFile(data, path); } catch (PathTooLongException) { Log.Info("File path in feed cache too long. Using hash of feed URI to shorten path."); WriteToFile(data, System.IO.Path.Combine(Path, feedUri.AbsoluteUri.Hash(SHA256.Create()))); } }
/// <summary> /// Pre-download application in a background proccess for later use. /// </summary> private void BackgroundDownload([NotNull] FeedUri interfaceUri) { if (!NoDownload && Config.NetworkUse == NetworkLevel.Full) { Log.Info("Starting background download for later use"); StartCommandBackground(Download.Name, "--batch", interfaceUri.ToStringRfc()); } }
private string DoConfirmKeys(FeedUri feedUri, Dictionary <string, string[][]> keys) { var key = keys.First(); var hint = key.Value[0]; string message = string.Format(Resources.AskKeyTrust, feedUri.ToStringRfc(), key.Key, hint[1], feedUri.Host); return(_handler.Ask(message) ? "ok" : "cancel"); }
public void RemovePackageSource(string uri) { var feedUri = new FeedUri(uri); if (!CatalogManager.RemoveSource(feedUri)) { Log.Warn(string.Format(Resources.CatalogNotRegistered, feedUri.ToStringRfc())); } }
public void AddPackageSource(string uri) { var feedUri = new FeedUri(uri); CatalogManager.DownloadCatalog(feedUri); if (CatalogManager.AddSource(feedUri)) CatalogManager.GetOnlineSafe(); else Log.Warn(string.Format(Resources.CatalogAlreadyRegistered, feedUri.ToStringRfc())); }
public override ExitCode Execute() { var uri = new FeedUri(AdditionalArgs[0]); if (CatalogManager.RemoveSource(uri)) return ExitCode.OK; else { Handler.OutputLow(Resources.CatalogSources, string.Format(Resources.CatalogNotRegistered, uri.ToStringRfc())); return ExitCode.NoChanges; } }
/// <inheritdoc/> public void Remove(FeedUri feedUri) { #region Sanity checks if (feedUri == null) { throw new ArgumentNullException("feedUri"); } #endregion string path = GetPath(feedUri); Log.Debug("Removing feed " + feedUri.ToStringRfc() + " from disk cache: " + path); File.Delete(path); }
/// <inheritdoc/> public async Task RemoveAsync(FeedUri uri, bool machineWide = false) { var args = new List <string> { "remove", "--batch", uri.ToStringRfc() }; if (machineWide) { args.Add("--machine"); } await Task.Run(() => _launcher.RunAndCapture(args.ToArray())); }
/// <summary> /// Saves these <see cref="InterfacePreferences"/> for a specific interface. /// </summary> /// <param name="interfaceUri">The interface to save the preferences for.</param> /// <exception cref="IOException">A problem occurs while writing the file.</exception> /// <exception cref="UnauthorizedAccessException">Write access to the file is not permitted.</exception> public void SaveFor([NotNull] FeedUri interfaceUri) { #region Sanity checks if (interfaceUri == null) { throw new ArgumentNullException("interfaceUri"); } #endregion var path = Locations.GetSaveConfigPath("0install.net", true, "injector", "interfaces", interfaceUri.PrettyEscape()); Log.Debug("Saving interface preferences for " + interfaceUri.ToStringRfc() + " to: " + path); this.SaveXml(path); }
private Catalog DownloadCatalog([NotNull] FeedUri source) { if (source.IsFile) { return(XmlStorage.LoadXml <Catalog>(source.LocalPath)); } Log.Info("Downloading catalog: " + source.ToStringRfc()); byte[] data; using (var webClient = new WebClientTimeout()) data = webClient.DownloadData(source); _trustManager.CheckTrust(data, source); return(XmlStorage.LoadXml <Catalog>(new MemoryStream(data))); }
public void Prefixes() { var fakeUri = new FeedUri("fake:http://example.com/"); fakeUri.IsFake.Should().BeTrue(); fakeUri.ToString().Should().Be("fake:http://example.com/"); fakeUri.ToStringRfc().Should().Be("fake:http://example.com/"); var fromDistributionUri = new FeedUri("distribution:http://example.com/"); fromDistributionUri.IsFromDistribution.Should().BeTrue(); fromDistributionUri.ToString().Should().Be("distribution:http://example.com/"); fromDistributionUri.ToStringRfc().Should().Be("distribution:http://example.com/"); }
/// <inheritdoc/> public Feed GetFeed(FeedUri feedUri) { #region Sanity checks if (feedUri == null) { throw new ArgumentNullException(nameof(feedUri)); } #endregion string path = GetPath(feedUri); Log.Debug("Loading feed " + feedUri.ToStringRfc() + " from disk cache: " + path); return(XmlStorage.LoadXml <Feed>(path)); }
public void AddPackageSource(string uri) { var feedUri = new FeedUri(uri); CatalogManager.DownloadCatalog(feedUri); if (CatalogManager.AddSource(feedUri)) { CatalogManager.GetOnlineSafe(); } else { Log.Warn(string.Format(Resources.CatalogAlreadyRegistered, feedUri.ToStringRfc())); } }
/// <summary> /// Saves these <see cref="FeedPreferences"/> for a specific feed. /// </summary> /// <param name="feedUri">The feed to save the preferences for.</param> /// <exception cref="IOException">A problem occurs while writing the file.</exception> /// <exception cref="UnauthorizedAccessException">Write access to the file is not permitted.</exception> public void SaveFor([NotNull] FeedUri feedUri) { #region Sanity checks if (feedUri == null) { throw new ArgumentNullException(nameof(feedUri)); } #endregion Normalize(); var path = Locations.GetSaveConfigPath("0install.net", true, "injector", "feeds", feedUri.PrettyEscape()); Log.Debug("Saving feed preferences for " + feedUri.ToStringRfc() + " to: " + path); this.SaveXml(path); }
public override ExitCode Execute() { var uri = new FeedUri(AdditionalArgs[0]); if (!_skipVerify) CatalogManager.DownloadCatalog(uri); if (CatalogManager.AddSource(uri)) { if (!_skipVerify) CatalogManager.GetOnlineSafe(); return ExitCode.OK; } else { Handler.OutputLow(Resources.CatalogSources, string.Format(Resources.CatalogAlreadyRegistered, uri.ToStringRfc())); return ExitCode.NoChanges; } }
private static IEnumerable <string> GetArguments(FeedUri uri, string?command, bool gui) { yield return("run"); if (gui) { yield return("--no-wait"); } if (!string.IsNullOrEmpty(command)) { yield return("--command"); yield return(command); } yield return(uri.ToStringRfc()); }
/// <inheritdoc/> public Feed?GetFeed(FeedUri feedUri) { #region Sanity checks if (feedUri == null) { throw new ArgumentNullException(nameof(feedUri)); } #endregion string?path = GetPath(feedUri); if (path == null) { return(null); } Log.Debug($"Loading feed {feedUri.ToStringRfc()} from disk cache: {path}"); return(XmlStorage.LoadXml <Feed>(path)); }
/// <inheritdoc/> public void Remove(FeedUri feedUri) { #region Sanity checks if (feedUri == null) { throw new ArgumentNullException(nameof(feedUri)); } #endregion string?path = GetPath(feedUri); if (path == null) { return; } Log.Debug($"Removing feed {feedUri.ToStringRfc()} from disk cache: {path}"); File.Delete(path); }
public static InterfacePreferences LoadFor([NotNull] FeedUri interfaceUri) { #region Sanity checks if (interfaceUri == null) { throw new ArgumentNullException("interfaceUri"); } #endregion var path = Locations.GetLoadConfigPaths("0install.net", true, "injector", "interfaces", interfaceUri.PrettyEscape()).FirstOrDefault(); if (string.IsNullOrEmpty(path)) { return(new InterfacePreferences()); } Log.Debug("Loading interface preferences for " + interfaceUri.ToStringRfc() + " from: " + path); return(XmlStorage.LoadXml <InterfacePreferences>(path)); }
public void TestToString() { new FeedUri("http://example.com").ToStringRfc().Should().Be("http://example.com/"); new FeedUri("http://example.com/").ToStringRfc().Should().Be("http://example.com/"); new FeedUri("http://example.com/test1.xml").ToStringRfc().Should().Be("http://example.com/test1.xml"); new FeedUri("https://example.com/test1.xml").ToStringRfc().Should().Be("https://example.com/test1.xml"); new FeedUri("http://example.com/my feed.xml").ToString().Should().Be("http://example.com/my feed.xml"); new FeedUri("http://example.com/my%20feed.xml").ToString().Should().Be("http://example.com/my feed.xml"); new FeedUri("http://example.com/my feed.xml").ToStringRfc().Should().Be("http://example.com/my%20feed.xml"); new FeedUri("http://example.com/my%20feed.xml").ToStringRfc().Should().Be("http://example.com/my%20feed.xml"); var absoluteUri = new FeedUri(WindowsUtils.IsWindows ? @"C:\my feed.xml" : "/root/my feed.xml"); absoluteUri.LocalPath.Should().Be( WindowsUtils.IsWindows ? @"C:\my feed.xml" : "/root/my feed.xml"); absoluteUri.ToString().Should().Be( WindowsUtils.IsWindows ? @"C:\my feed.xml" : "/root/my feed.xml"); absoluteUri.ToStringRfc().Should().Be( WindowsUtils.IsWindows ? @"C:\my feed.xml" : "/root/my feed.xml"); absoluteUri = new FeedUri(WindowsUtils.IsWindows ? "file:///C:/my%20feed.xml" : "file:///root/my%20feed.xml"); absoluteUri.LocalPath.Should().Be( WindowsUtils.IsWindows ? @"C:\my feed.xml" : "/root/my feed.xml"); absoluteUri.ToString().Should().Be( WindowsUtils.IsWindows ? @"C:\my feed.xml" : "/root/my feed.xml"); absoluteUri.ToStringRfc().Should().Be( WindowsUtils.IsWindows ? @"C:\my feed.xml" : "/root/my feed.xml"); if (WindowsUtils.IsWindows) { absoluteUri = new FeedUri(@"\\SERVER\C$\my feed.xml"); absoluteUri.ToString().Should().Be( @"\\server\C$\my feed.xml"); absoluteUri.ToStringRfc().Should().Be( @"\\server\C$\my feed.xml"); absoluteUri = new FeedUri("file://SERVER/C$/my%20feed.xml"); absoluteUri.ToString().Should().Be( @"\\server\C$\my feed.xml"); absoluteUri.ToStringRfc().Should().Be( @"\\server\C$\my feed.xml"); } }
/// <inheritdoc/> public async Task <ISet <string> > GetIntegrationAsync(FeedUri uri, bool machineWide = false) { var args = new List <string> { "list-apps", "--batch", "--xml", uri.ToStringRfc() }; if (machineWide) { args.Add("--machine"); } string output = await Task.Run(() => _launcher.RunAndCapture(args.ToArray())); const string xmlNamespace = "http://0install.de/schema/desktop-integration/app-list"; return(new HashSet <string>( XElement.Parse(output) .Descendants(XName.Get("app", xmlNamespace)).SingleOrDefault() ?.Descendants(XName.Get("access-points", xmlNamespace)).SingleOrDefault() ?.Descendants() .Select(x => x.Name.LocalName) ?? Enumerable.Empty <string>())); }
public void TestToString() { new FeedUri("http://0install.de").ToStringRfc().Should().Be("http://0install.de/"); new FeedUri("http://0install.de/").ToStringRfc().Should().Be("http://0install.de/"); new FeedUri("http://0install.de/feeds/test1.xml").ToStringRfc().Should().Be("http://0install.de/feeds/test1.xml"); new FeedUri("https://0install.de/feeds/test1.xml").ToStringRfc().Should().Be("https://0install.de/feeds/test1.xml"); new FeedUri("http://0install.de/feeds/my feed.xml").ToString().Should().Be("http://0install.de/feeds/my feed.xml"); new FeedUri("http://0install.de/feeds/my%20feed.xml").ToString().Should().Be("http://0install.de/feeds/my feed.xml"); new FeedUri("http://0install.de/feeds/my feed.xml").ToStringRfc().Should().Be("http://0install.de/feeds/my%20feed.xml"); new FeedUri("http://0install.de/feeds/my%20feed.xml").ToStringRfc().Should().Be("http://0install.de/feeds/my%20feed.xml"); var absoluteUri = new FeedUri(WindowsUtils.IsWindows ? @"C:\my feed.xml" : "/root/my feed.xml"); absoluteUri.LocalPath.Should().Be( WindowsUtils.IsWindows ? @"C:\my feed.xml" : "/root/my feed.xml"); absoluteUri.ToString().Should().Be( WindowsUtils.IsWindows ? @"C:\my feed.xml" : "/root/my feed.xml"); absoluteUri.ToStringRfc().Should().Be( WindowsUtils.IsWindows ? @"C:\my feed.xml" : "/root/my feed.xml"); absoluteUri = new FeedUri(WindowsUtils.IsWindows ? "file:///C:/my%20feed.xml" : "file:///root/my%20feed.xml"); absoluteUri.LocalPath.Should().Be( WindowsUtils.IsWindows ? @"C:\my feed.xml" : "/root/my feed.xml"); absoluteUri.ToString().Should().Be( WindowsUtils.IsWindows ? @"C:\my feed.xml" : "/root/my feed.xml"); absoluteUri.ToStringRfc().Should().Be( WindowsUtils.IsWindows ? @"C:\my feed.xml" : "/root/my feed.xml"); if (WindowsUtils.IsWindows) { absoluteUri = new FeedUri(@"\\SERVER\C$\my feed.xml"); absoluteUri.ToString().Should().Be( @"\\server\C$\my feed.xml"); absoluteUri.ToStringRfc().Should().Be( @"\\server\C$\my feed.xml"); absoluteUri = new FeedUri("file://SERVER/C$/my%20feed.xml"); absoluteUri.ToString().Should().Be( @"\\server\C$\my feed.xml"); absoluteUri.ToStringRfc().Should().Be( @"\\server\C$\my feed.xml"); } }
/// <inheritdoc/> public string GetPath(FeedUri feedUri) { #region Sanity checks if (feedUri == null) throw new ArgumentNullException(nameof(feedUri)); #endregion if (feedUri.IsFile) throw new KeyNotFoundException("Feed cache does not handle local files: " + feedUri.ToStringRfc()); string fileName = feedUri.Escape(); string path = Path.Combine(DirectoryPath, fileName); if (FileUtils.ExistsCaseSensitive(path)) return path; else throw new KeyNotFoundException(string.Format(Resources.FeedNotInCache, feedUri, path)); }
public override ExitCode Execute() { var uri = new FeedUri(AdditionalArgs[0]); if (CatalogManager.RemoveSource(uri)) { return(ExitCode.OK); } else { Handler.OutputLow(Resources.CatalogSources, string.Format(Resources.CatalogNotRegistered, uri.ToStringRfc())); return(ExitCode.NoChanges); } }
/// <inheritdoc/> public void Remove(FeedUri feedUri) { #region Sanity checks if (feedUri == null) throw new ArgumentNullException("feedUri"); #endregion string path = GetPath(feedUri); Log.Debug("Removing feed " + feedUri.ToStringRfc() + " from disk cache: " + path); File.Delete(path); }
public void TestToString() { Assert.AreEqual("http://0install.de/", new FeedUri("http://0install.de").ToStringRfc()); Assert.AreEqual("http://0install.de/", new FeedUri("http://0install.de/").ToStringRfc()); Assert.AreEqual("http://0install.de/feeds/test1.xml", new FeedUri("http://0install.de/feeds/test1.xml").ToStringRfc()); Assert.AreEqual("https://0install.de/feeds/test1.xml", new FeedUri("https://0install.de/feeds/test1.xml").ToStringRfc()); Assert.AreEqual("http://0install.de/feeds/my feed.xml", new FeedUri("http://0install.de/feeds/my feed.xml").ToString()); Assert.AreEqual("http://0install.de/feeds/my feed.xml", new FeedUri("http://0install.de/feeds/my%20feed.xml").ToString()); Assert.AreEqual("http://0install.de/feeds/my%20feed.xml", new FeedUri("http://0install.de/feeds/my feed.xml").ToStringRfc()); Assert.AreEqual("http://0install.de/feeds/my%20feed.xml", new FeedUri("http://0install.de/feeds/my%20feed.xml").ToStringRfc()); var absoluteUri = new FeedUri(WindowsUtils.IsWindows ? @"C:\my feed.xml" : "/root/my feed.xml"); Assert.AreEqual( expected: WindowsUtils.IsWindows ? @"C:\my feed.xml" : "/root/my feed.xml", actual: absoluteUri.LocalPath); Assert.AreEqual( expected: WindowsUtils.IsWindows ? @"C:\my feed.xml" : "/root/my feed.xml", actual: absoluteUri.ToString()); Assert.AreEqual( expected: WindowsUtils.IsWindows ? @"C:\my feed.xml" : "/root/my feed.xml", actual: absoluteUri.ToStringRfc()); absoluteUri = new FeedUri(WindowsUtils.IsWindows ? "file:///C:/my%20feed.xml" : "file:///root/my%20feed.xml"); Assert.AreEqual( expected: WindowsUtils.IsWindows ? @"C:\my feed.xml" : "/root/my feed.xml", actual: absoluteUri.LocalPath); Assert.AreEqual( expected: WindowsUtils.IsWindows ? @"C:\my feed.xml" : "/root/my feed.xml", actual: absoluteUri.ToString()); Assert.AreEqual( expected: WindowsUtils.IsWindows ? @"C:\my feed.xml" : "/root/my feed.xml", actual: absoluteUri.ToStringRfc()); if (WindowsUtils.IsWindows) { absoluteUri = new FeedUri(@"\\SERVER\C$\my feed.xml"); Assert.AreEqual( expected: @"\\server\C$\my feed.xml", actual: absoluteUri.ToString()); Assert.AreEqual( expected: @"\\server\C$\my feed.xml", actual: absoluteUri.ToStringRfc()); absoluteUri = new FeedUri("file://SERVER/C$/my%20feed.xml"); Assert.AreEqual( expected: @"\\server\C$\my feed.xml", actual: absoluteUri.ToString()); Assert.AreEqual( expected: @"\\server\C$\my feed.xml", actual: absoluteUri.ToStringRfc()); } }
/// <inheritdoc/> public void Add(FeedUri feedUri, byte[] data) { #region Sanity checks if (feedUri == null) throw new ArgumentNullException("feedUri"); if (data == null) throw new ArgumentNullException("data"); #endregion if (!Directory.Exists(DirectoryPath)) Directory.CreateDirectory(DirectoryPath); try { string path = Path.Combine(DirectoryPath, feedUri.Escape()); Log.Debug("Adding feed " + feedUri.ToStringRfc() + " to disk cache: " + path); WriteToFile(data, path); } catch (PathTooLongException) { Log.Info("File path in feed cache too long. Using hash of feed URI to shorten path."); WriteToFile(data, Path.Combine(DirectoryPath, feedUri.AbsoluteUri.Hash(SHA256.Create()))); } }
private string DoConfirmKeys(FeedUri feedUri, Dictionary<string, string[][]> keys) { var key = keys.First(); var hint = key.Value[0]; string message = string.Format(Resources.AskKeyTrust, feedUri.ToStringRfc(), key.Key, hint[1], feedUri.Host); return _handler.Ask(message) ? "ok" : "cancel"; }
public override ExitCode Execute() { var uri = new FeedUri(AdditionalArgs[0]); if (!_skipVerify) { CatalogManager.DownloadCatalog(uri); } if (CatalogManager.AddSource(uri)) { if (!_skipVerify) { CatalogManager.GetOnlineSafe(); } return(ExitCode.OK); } else { Handler.OutputLow(Resources.CatalogSources, string.Format(Resources.CatalogAlreadyRegistered, uri.ToStringRfc())); return(ExitCode.NoChanges); } }
/// <inheritdoc/> public Feed GetFeed(FeedUri feedUri) { #region Sanity checks if (feedUri == null) throw new ArgumentNullException("feedUri"); #endregion string path = GetPath(feedUri); Log.Debug("Loading feed " + feedUri.ToStringRfc() + " from disk cache: " + path); var feed = XmlStorage.LoadXml<Feed>(path); feed.Normalize(feedUri); return feed; }
public void RemovePackageSource(string uri) { var feedUri = new FeedUri(uri); if (!CatalogManager.RemoveSource(feedUri)) Log.Warn(string.Format(Resources.CatalogNotRegistered, feedUri.ToStringRfc())); }
/// <inheritdoc/> public async Task RemoveAsync(FeedUri uri) => await Task.Run(() => _launcher.RunAndCapture("remove", "--batch", uri.ToStringRfc()));
public void TestPrefixes() { var fakeUri = new FeedUri("fake:http://example.com/"); fakeUri.IsFake.Should().BeTrue(); fakeUri.ToString().Should().Be("fake:http://example.com/"); fakeUri.ToStringRfc().Should().Be("fake:http://example.com/"); var fromDistributionUri = new FeedUri("distribution:http://example.com/"); fromDistributionUri.IsFromDistribution.Should().BeTrue(); fromDistributionUri.ToString().Should().Be("distribution:http://example.com/"); fromDistributionUri.ToStringRfc().Should().Be("distribution:http://example.com/"); }
/// <inheritdoc/> public string GetPath(FeedUri feedUri) { #region Sanity checks if (feedUri == null) { throw new ArgumentNullException(nameof(feedUri)); } #endregion if (feedUri.IsFile) { throw new KeyNotFoundException("Feed cache does not handle local files: " + feedUri.ToStringRfc()); } string fileName = feedUri.Escape(); string path = Path.Combine(DirectoryPath, fileName); if (FileUtils.ExistsCaseSensitive(path)) { return(path); } else { throw new KeyNotFoundException(string.Format(Resources.FeedNotInCache, feedUri, path)); } }