/// <summary> /// Downloads a file to <see cref="downloadFileName"/> and extracts contents using <see cref="extractor"/>. /// If the file being downloaded already exists, it won't be redownloaded. /// </summary> /// <param name="url">Url to download the file from.</param> /// <param name="downloadFileName">Path to download the file to.</param> /// <param name="extractor">Action to extract file with.</param> /// <param name="keepDownloaded">Keep downloaded file. If false, file is removed after exctraction.</param> /// <returns>True if suceeded, false otherwise.</returns> public bool DownloadAndExtract(string url, string downloadFileName, Action <ZipFile> extractor, bool keepDownloaded = false) { string fileName = Path.GetFileName(downloadFileName); if (!File.Exists(downloadFileName)) { bool complete = false; var client = new WebClient(); client.DownloadProgressChanged += (sender, args) => { if (!complete) { _progressWriter?.SetItemProgress(args.BytesReceived, args.TotalBytesToReceive, $"Downloading {fileName}"); } }; try { client.DownloadFileTaskAsync(url, downloadFileName).Wait(); } catch (Exception e) { _progressWriter?.Message($"Failed to download {fileName}: {e.Message}"); return(false); } complete = true; _progressWriter?.ItemComplete(); } try { using (var zip = ZipFile.Read(downloadFileName)) { extractor(zip); } _progressWriter?.Message($"Extracted {fileName}."); } catch (Exception e) { _progressWriter?.Message($"Failed to extract {fileName}: {e.Message}"); return(false); } finally { if (!keepDownloaded) { File.Delete(downloadFileName); } } return(true); }
/// <summary> /// Tries to enable Math.NET native MKL provider. If not found and download is enabled, downloads /// and exctracts MKL into [Retia.dll location]\x64. /// </summary> /// <param name="tryDownload">Whether MKL download is enabled.</param> /// <param name="progressWriter">Progress writer.</param> /// <returns>True if could use MKL provider, false otherwise.</returns> public static bool TryUseMkl(bool tryDownload = true, IProgressWriter progressWriter = null) { if (Control.TryUseNativeMKL()) { progressWriter?.Message("Using MKL."); return(true); } if (!tryDownload) { progressWriter?.Message("Couldn't use MKL and download is disabled. Using slow math provider."); return(false); } progressWriter?.Message("Couldn't use MKL right away, trying to download..."); string tempPath = Path.Combine(Path.GetTempPath(), FileName); string extractDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "x64"); var downloader = new FileDownloader(progressWriter); if (!Directory.Exists(extractDir)) { Directory.CreateDirectory(extractDir); } if (!downloader.DownloadAndExtract(MKLPackage, tempPath, file => { var files = file.SelectEntries("*.*", @"build/x64"); foreach (var entry in files) { using (var stream = new FileStream(Path.Combine(extractDir, Path.GetFileName(entry.FileName)), FileMode.Create, FileAccess.Write)) { entry.Extract(stream); } } }, true)) { return(false); } if (!Control.TryUseNativeMKL()) { progressWriter?.Message("Still can't use MKL, giving up."); return(false); } return(true); }