public object?Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (!(value is string path)) { return(value); } if (!Path_.IsValidFilepath(path, false)) { return(value); } return(Path_.FileName(path)); }
/// <summary>Handle unhandled exceptions</summary> private static void HandleTheUnhandled(Exception ex) { var res = MsgBox.Show(null, $"{Application.ProductName} has shutdown with the following error.\r\n"+ $"Error: {ex.GetType().Name}\r\n"+ $"\r\n"+ $"Deleting the applications settings file, '{StartupOptions?.SettingsPath ?? Path_.FileName(Settings.Default.Filepath)}', might prevent this problem.\r\n"+ $"\r\n"+ $"Generating a report and sending it to {Util.GetAssemblyAttribute<AssemblyCompanyAttribute>().Company} will aid in the resolution of this issue. "+ $"The generated report is a plain text file that you can review before sending.\r\n"+ $"\r\n"+ $"Would you like to generate the report?\r\n"+ $"\r\n"+ $"Alternatively, please contact {Constants.SupportEmail} with information about this error so that it can be fixed.\r\n"+ $"\r\n"+ $"Apologies for any inconvenience caused.\r\n", "Unexpected Termination", MessageBoxButtons.YesNo, MessageBoxIcon.Error); if (res == DialogResult.Yes) { var dg = new SaveFileDialog{Title = "Save Crash Report", FileName = Application.ProductName+"CrashReport", Filter = Util.FileDialogFilter("Crash Report Files","*.txt", "All files","*.*"), DefaultExt = "txt", CheckPathExists = true}; if (dg.ShowDialog() == DialogResult.OK) { var settings = "Settings filepath unknown"; if (StartupOptions != null && Path_.FileExists(StartupOptions.SettingsPath)) settings = File.ReadAllText(StartupOptions.SettingsPath); var sb = new StringBuilder() .Append(Application.ProductName).Append(" - Crash Report - ").Append(DateTime.UtcNow).AppendLine() .AppendLine("---------------------------------------------------------------") .AppendLine("[Unhandled Exception Type]") .AppendLine(ex.MessageFull()) .AppendLine() .AppendLine("[Settings File Contents]") .AppendLine(settings) .AppendLine() .AppendLine("[General]") .AppendLine($"Application Version: {Util.AssemblyVersion()}") .AppendLine(Environment.OSVersion.VersionString) .AppendLine(StartupOptions?.Dump() ?? string.Empty) .AppendLine() .AppendLine("[Additional Comments]") .AppendLine("Any additional information about what you were doing when this crash occurred would be extremely helpful and appreciated"); File.WriteAllText(dg.FileName, sb.ToString()); try { if (MsgBox.Show(null, "Preview the report before sending?", "Review Report", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) Process.Start(dg.FileName); } catch {} try { // Try to create an email with the attachment ready to go var email = new MailMessage(); email.From = new MailAddress(Constants.SupportEmail); email.To.Add(Constants.SupportEmail); email.Subject = $"{Util.AppProductName} crash report"; email.Priority = MailPriority.Normal; email.IsBodyHtml = false; email.Body = $"To {Util.AppCompany},\r\n" + $"\r\n" + $"Attached is a crash report generated on {DateTime.Now}.\r\n" + $"A brief description of how the application was being used at the time follows:\r\n" + $"\r\n\r\n\r\n\r\n" + $"Regards,\r\n" + $"A Helpful User"; email.Attachments.Add(new Attachment(dg.FileName)); // Try to send it var smtp = new SmtpClient(); smtp.Send(email); } catch {} } } Environment.ExitCode = 1; }
/// <summary>Pull 'filename' from EDDB. Returns true if the file was downloaded, and the output filepath</summary> public async Task <DownloadFileResult> DownloadFile(string file_url, string output_dir, TimeSpan?maximum_age = null) { var filename = Path_.FileName(file_url); var output_path = Path_.CombinePath(Path_.CreateDirs(output_dir), filename); using (StatusStack.NewStatusMessage($"Downloading '{filename}'...")) { try { HttpRequestMessage req; HttpResponseMessage resp; // Request the head information about the target file Log.Write(ELogLevel.Info, $"Checking size and timestamp of '{filename}'"); req = new HttpRequestMessage(HttpMethod.Head, file_url); resp = await Client.SendAsync(req, Shutdown); if (!resp.IsSuccessStatusCode) { Log.Write(ELogLevel.Error, $"Downloading information for '{filename}' failed: {resp.StatusCode} {resp.ReasonPhrase}"); throw new HttpRequestException($"{resp.ReasonPhrase} ({resp.StatusCode})"); } // Only download if the server version is newer. if (maximum_age != null && Path_.FileExists(output_path)) { var time_diff = new FileInfo(output_path).LastWriteTime - resp.Content.Headers.LastModified; if (time_diff > -maximum_age.Value) { Log.Write(ELogLevel.Info, $"Local copy of '{filename}' is less than {Settings.Instance.DataAge.ToPrettyString(trailing_zeros:false)} older than the latest version"); return(new DownloadFileResult(file_url, output_path, false)); } } // Get the download size (remember it might be compressed) var length = resp.Content.Headers.ContentLength; // The server version is newer, download the whole file Log.Write(ELogLevel.Info, $"Downloading '{filename}' ({length} bytes)"); using (Scope.Create(() => Downloading = true, () => Downloading = false)) { // Make the web request req = new HttpRequestMessage(HttpMethod.Get, file_url); resp = await Client.SendAsync(req, Shutdown); if (!resp.IsSuccessStatusCode) { Log.Write(ELogLevel.Error, $"Downloading '{filename}' failed: {resp.StatusCode} {resp.ReasonPhrase}"); throw new HttpRequestException($"{resp.ReasonPhrase} ({resp.StatusCode})"); } // Read the response content into a file using (var file = new FileStream(output_path, FileMode.Create, FileAccess.Write, FileShare.Read)) { // Decompress if the content is compressed if (resp.Content.Headers.ContentEncoding.Any(x => x == "gzip")) { using (var content = await resp.Content.ReadAsStreamAsync()) using (var gzip = new GZipStream(content, CompressionMode.Decompress)) await gzip.CopyToAsync(file); } else { await resp.Content.CopyToAsync(file); } Log.Write(ELogLevel.Info, $"Download complete '{filename}'"); return(new DownloadFileResult(file_url, output_path, true)); } } } catch { Log.Write(ELogLevel.Error, $"Data file '{filename}' was not available from {file_url}."); return(new DownloadFileResult(file_url, output_path, false)); } } }
/// <summary> /// Smart copy from 'src' to 'dst'. Loosely like XCopy. /// 'src' can be a single file, a comma separated list of files, or a directory<para/> /// 'dst' can be a /// if 'src' is a directory, </summary> public static void Copy(string src, string dst, bool overwrite = false, bool only_if_modified = false, bool ignore_non_existing = false, Action <string>?feedback = null, bool show_unchanged = false) { var src_is_dir = Path_.IsDirectory(src); var dst_is_dir = Path_.IsDirectory(dst) || dst.EndsWith("/") || dst.EndsWith("\\") || src_is_dir; // Find the names of the source files to copy var files = new List <string>(); if (src_is_dir) { files = Path_.EnumFileSystem(src, SearchOption.AllDirectories).Select(x => x.FullName).ToList(); } else if (Path_.FileExists(src)) { files = new List <string>() { src } } ; else if (src.Contains('*') || src.Contains('?')) { files = Path_.EnumFileSystem(src, SearchOption.AllDirectories, new Pattern(EPattern.Wildcard, src).RegexString).Select(x => x.FullName).ToList(); } else if (!ignore_non_existing) { throw new FileNotFoundException($"'{src}' does not exist"); } // If the 'src' represents multiple files, 'dst' must be a directory if (src_is_dir || files.Count > 1) { // if 'dst' doesn't exist, assume it's a directory if (!Path_.DirExists(dst)) { dst_is_dir = true; } // or if it does exist, check that it is actually a directory else if (!dst_is_dir) { throw new FileNotFoundException($"'{dst}' is not a valid directory"); } } // Ensure that 'dstdir' exists. (Canonicalise fixes the case where 'dst' is a drive, e.g. 'C:\') var dstdir = Path_.Canonicalise((dst_is_dir ? dst : Path_.Directory(dst)).TrimEnd('/', '\\')); if (!Path_.DirExists(dstdir)) { Directory.CreateDirectory(dstdir); } // Copy the file(s) to 'dst' foreach (var srcfile in files) { // If 'dst' is a directory, use the same filename from 'srcfile' var dstfile = string.Empty; if (dst_is_dir) { var spath = src_is_dir ? Path_.RelativePath(src, srcfile) : Path_.FileName(srcfile); dstfile = Path_.CombinePath(dstdir, spath); } else { dstfile = dst; } // If 'srcfile' is a directory, ensure the directory exists at the destination if (Path_.IsDirectory(srcfile)) { if (!dst_is_dir) { throw new Exception($"ERROR: {dst} is not a directory"); } // Create the directory at the destination if (!Path_.DirExists(dstfile)) { System.IO.Directory.CreateDirectory(dstfile); } if (feedback != null) { feedback(srcfile + " --> " + dstfile); } } else { // Copy if modified or always based on the flag if (only_if_modified && !Path_.DiffContent(srcfile, dstfile)) { if (feedback != null && show_unchanged) { feedback(srcfile + " --> unchanged"); } continue; } // Ensure the directory path exists var d = Path_.Directory(dstfile); var f = Path_.FileName(dstfile); if (!Path_.DirExists(d)) { System.IO.Directory.CreateDirectory(d); } if (feedback != null) { feedback(srcfile + " --> " + dstfile); } File.Copy(srcfile, dstfile, overwrite); } } }