diff --git a/PdfScribe.sln b/PdfScribe.sln index 46bb462..219090c 100644 --- a/PdfScribe.sln +++ b/PdfScribe.sln @@ -59,9 +59,8 @@ Global {E8679E1B-8C89-4201-97D5-7E43C5A486C9}.Release|x64.Build.0 = Release|x64 {E8679E1B-8C89-4201-97D5-7E43C5A486C9}.Release|x86.ActiveCfg = Release|x86 {E8679E1B-8C89-4201-97D5-7E43C5A486C9}.Release|x86.Build.0 = Release|x86 - {3C255536-A7F1-4913-9C7F-966DFFEE01BC}.Debug|Any CPU.ActiveCfg = Debug|x86 + {3C255536-A7F1-4913-9C7F-966DFFEE01BC}.Debug|Any CPU.ActiveCfg = Debug|x64 {3C255536-A7F1-4913-9C7F-966DFFEE01BC}.Debug|x64.ActiveCfg = Debug|x64 - {3C255536-A7F1-4913-9C7F-966DFFEE01BC}.Debug|x64.Build.0 = Debug|x64 {3C255536-A7F1-4913-9C7F-966DFFEE01BC}.Debug|x86.ActiveCfg = Debug|x86 {3C255536-A7F1-4913-9C7F-966DFFEE01BC}.Debug|x86.Build.0 = Debug|x86 {3C255536-A7F1-4913-9C7F-966DFFEE01BC}.Release|Any CPU.ActiveCfg = Release|x64 @@ -78,7 +77,6 @@ Global {8562A5BC-A70E-40DD-A7E7-5611D332A983}.Debug|x86.Build.0 = Debug|Any CPU {8562A5BC-A70E-40DD-A7E7-5611D332A983}.Release|Any CPU.ActiveCfg = Release|Any CPU {8562A5BC-A70E-40DD-A7E7-5611D332A983}.Release|x64.ActiveCfg = Release|Any CPU - {8562A5BC-A70E-40DD-A7E7-5611D332A983}.Release|x64.Build.0 = Release|Any CPU {8562A5BC-A70E-40DD-A7E7-5611D332A983}.Release|x86.ActiveCfg = Release|Any CPU {8562A5BC-A70E-40DD-A7E7-5611D332A983}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection diff --git a/PdfScribe/Program.cs b/PdfScribe/Program.cs index 47a3aae..c0e7829 100644 --- a/PdfScribe/Program.cs +++ b/PdfScribe/Program.cs @@ -1,253 +1,253 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Drawing; -using System.IO; -using System.Runtime.InteropServices; -using System.Text; -using System.Text.RegularExpressions; -using System.Windows.Forms; - - -namespace PdfScribe -{ - public class Program - { - - - #region Message constants - - const string errorDialogCaption = "PDF Scribe"; // Error taskdialog caption text - - const string errorDialogInstructionPDFGeneration = "There was a PDF generation error."; - const string errorDialogInstructionCouldNotWrite = "Could not create the output file."; - const string errorDialogInstructionUnexpectedError = "There was an internal error. Enable tracing for details."; - - const string errorDialogTextFileInUse = "{0} is being used by another process."; - const string errorDialogTextGhostScriptConversion = "Ghostscript error code {0}."; - - const string warnFileNotDeleted = "{0} could not be deleted."; - - #endregion - - #region Other constants - const string traceSourceName = "PdfScribe"; - - const string defaultOutputFilename = "PDFSCRIBE.PDF"; - - #endregion - - static TraceSource logEventSource = new TraceSource(traceSourceName); - - [STAThread] - static void Main(string[] args) - { - // Install the global exception handler - AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(Application_UnhandledException); - - - String standardInputFilename = Path.GetTempFileName(); - String outputFilename = String.Empty; - - try - { - using (BinaryReader standardInputReader = new BinaryReader(Console.OpenStandardInput())) - { - using (FileStream standardInputFile = new FileStream(standardInputFilename, FileMode.Create, FileAccess.ReadWrite)) - { - standardInputReader.BaseStream.CopyTo(standardInputFile); - } - } - - if (GetPdfOutputFilename(ref outputFilename)) - { - // Remove the existing PDF file if present - File.Delete(outputFilename); - // Only set absolute minimum parameters, let the postscript input - // dictate as much as possible - String[] ghostScriptArguments = { "-dBATCH", "-dNOPAUSE", "-dSAFER", "-sDEVICE=pdfwrite", - String.Format("-sOutputFile={0}", outputFilename), standardInputFilename }; - - GhostScript64.CallAPI(ghostScriptArguments); - DisplayPdf(outputFilename); - } - } - catch (IOException ioEx) - { - // We couldn't delete, or create a file - // because it was in use - logEventSource.TraceEvent(TraceEventType.Error, - (int)TraceEventType.Error, - errorDialogInstructionCouldNotWrite + - Environment.NewLine + - "Exception message: " + ioEx.Message); - DisplayErrorMessage(errorDialogCaption, - errorDialogInstructionCouldNotWrite + Environment.NewLine + - String.Format("{0} is in use.", outputFilename)); - } - catch (UnauthorizedAccessException unauthorizedEx) - { - // Couldn't delete a file - // because it was set to readonly - // or couldn't create a file - // because of permissions issues - logEventSource.TraceEvent(TraceEventType.Error, - (int)TraceEventType.Error, - errorDialogInstructionCouldNotWrite + - Environment.NewLine + - "Exception message: " + unauthorizedEx.Message); - DisplayErrorMessage(errorDialogCaption, - errorDialogInstructionCouldNotWrite + Environment.NewLine + - String.Format("Insufficient privileges to either create or delete {0}", outputFilename)); - - - } - catch (ExternalException ghostscriptEx) - { - // Ghostscript error - logEventSource.TraceEvent(TraceEventType.Error, - (int)TraceEventType.Error, - String.Format(errorDialogTextGhostScriptConversion, ghostscriptEx.ErrorCode.ToString()) + - Environment.NewLine + - "Exception message: " + ghostscriptEx.Message); - DisplayErrorMessage(errorDialogCaption, - errorDialogInstructionPDFGeneration + Environment.NewLine + - String.Format(errorDialogTextGhostScriptConversion, ghostscriptEx.ErrorCode.ToString())); - - } - finally - { - try - { - File.Delete(standardInputFilename); - } - catch - { - logEventSource.TraceEvent(TraceEventType.Warning, - (int)TraceEventType.Warning, - String.Format(warnFileNotDeleted, standardInputFilename)); - } - logEventSource.Flush(); - } - } - - /// - /// All unhandled exceptions will bubble their way up here - - /// a final error dialog will be displayed before the crash and burn - /// - /// - /// - static void Application_UnhandledException(object sender, UnhandledExceptionEventArgs e) - { - logEventSource.TraceEvent(TraceEventType.Critical, - (int)TraceEventType.Critical, - ((Exception)e.ExceptionObject).Message + Environment.NewLine + - ((Exception)e.ExceptionObject).StackTrace); - DisplayErrorMessage(errorDialogCaption, - errorDialogInstructionUnexpectedError); - } - - static bool GetPdfOutputFilename(ref String outputFile) - { - bool filenameRetrieved = false; - switch (Properties.Settings.Default.AskUserForOutputFilename) - { - case (true) : - using (SetOutputFilename dialogOwner = new SetOutputFilename()) - { - dialogOwner.TopMost = true; - dialogOwner.TopLevel = true; - dialogOwner.Show(); // Form won't actually show - Application.Run() never called - // but having a topmost/toplevel owner lets us bring the SaveFileDialog to the front - dialogOwner.BringToFront(); - using (SaveFileDialog pdfFilenameDialog = new SaveFileDialog()) - { - pdfFilenameDialog.AddExtension = true; - pdfFilenameDialog.AutoUpgradeEnabled = true; - pdfFilenameDialog.CheckPathExists = true; - pdfFilenameDialog.Filter = "pdf files (*.pdf)|*.pdf"; - pdfFilenameDialog.ShowHelp = false; - pdfFilenameDialog.Title = "PDF Scribe - Set output filename"; - pdfFilenameDialog.ValidateNames = true; - if (pdfFilenameDialog.ShowDialog(dialogOwner) == DialogResult.OK) - { - outputFile = pdfFilenameDialog.FileName; - filenameRetrieved = true; - } - } - dialogOwner.Close(); - } - break; - default: - outputFile = GetOutputFilename(); - filenameRetrieved = true; - break; - } - return filenameRetrieved; - - } - - private static String GetOutputFilename() - { - - String outputFilename = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), defaultOutputFilename); - if (!String.IsNullOrEmpty(Properties.Settings.Default.OutputFile) && - !String.IsNullOrWhiteSpace(Properties.Settings.Default.OutputFile)) - { - if (IsFilePathValid(Properties.Settings.Default.OutputFile)) - { - outputFilename = Properties.Settings.Default.OutputFile; - } - else - { - if (IsFilePathValid(Environment.ExpandEnvironmentVariables(Properties.Settings.Default.OutputFile))) - { - outputFilename = Environment.ExpandEnvironmentVariables(Properties.Settings.Default.OutputFile); - } - } - } - else - { - logEventSource.TraceEvent(TraceEventType.Warning, - (int)TraceEventType.Warning, - String.Format("Using default output filename {0}", - outputFilename)); - } - return outputFilename; - } - - static bool IsFilePathValid(String filePath) - { - bool pathIsValid = false; - - if (!String.IsNullOrEmpty(filePath) && filePath.Length <= 260) - { - String directoryName = Path.GetDirectoryName(filePath); - String filename = Path.GetFileName(filePath); - - if (Directory.Exists(directoryName)) - { - // Check for invalid filename chars - Regex containsABadCharacter = new Regex("[" - + Regex.Escape(new String(System.IO.Path.GetInvalidPathChars())) + "]"); - pathIsValid = !containsABadCharacter.IsMatch(filename); - } - } - else - { - logEventSource.TraceEvent(TraceEventType.Warning, - (int)TraceEventType.Warning, - "Output filename is longer than 260 characters, or blank."); - } - return pathIsValid; - } - +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Runtime.InteropServices; +using System.Text; +using System.Text.RegularExpressions; +using System.Windows.Forms; + + +namespace PdfScribe +{ + public class Program + { + + + #region Message constants + + const string errorDialogCaption = "PDF Scribe"; // Error taskdialog caption text + + const string errorDialogInstructionPDFGeneration = "There was a PDF generation error."; + const string errorDialogInstructionCouldNotWrite = "Could not create the output file."; + const string errorDialogInstructionUnexpectedError = "There was an internal error. Enable tracing for details."; + + const string errorDialogTextFileInUse = "{0} is being used by another process."; + const string errorDialogTextGhostScriptConversion = "Ghostscript error code {0}."; + + const string warnFileNotDeleted = "{0} could not be deleted."; + + #endregion + + #region Other constants + const string traceSourceName = "PdfScribe"; + + const string defaultOutputFilename = "PDFSCRIBE.PDF"; + + #endregion + + static TraceSource logEventSource = new TraceSource(traceSourceName); + + [STAThread] + static void Main(string[] args) + { + // Install the global exception handler + AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(Application_UnhandledException); + + + String standardInputFilename = Path.GetTempFileName(); + String outputFilename = String.Empty; + + try + { + using (BinaryReader standardInputReader = new BinaryReader(Console.OpenStandardInput())) + { + using (FileStream standardInputFile = new FileStream(standardInputFilename, FileMode.Create, FileAccess.ReadWrite)) + { + standardInputReader.BaseStream.CopyTo(standardInputFile); + } + } + + if (GetPdfOutputFilename(ref outputFilename)) + { + // Remove the existing PDF file if present + File.Delete(outputFilename); + // Only set absolute minimum parameters, let the postscript input + // dictate as much as possible + String[] ghostScriptArguments = { "-dBATCH", "-dNOPAUSE", "-dSAFER", "-sDEVICE=pdfwrite", + String.Format("-sOutputFile={0}", outputFilename), standardInputFilename }; + + GhostScript64.CallAPI(ghostScriptArguments); + DisplayPdf(outputFilename); + } + } + catch (IOException ioEx) + { + // We couldn't delete, or create a file + // because it was in use + logEventSource.TraceEvent(TraceEventType.Error, + (int)TraceEventType.Error, + errorDialogInstructionCouldNotWrite + + Environment.NewLine + + "Exception message: " + ioEx.Message); + DisplayErrorMessage(errorDialogCaption, + errorDialogInstructionCouldNotWrite + Environment.NewLine + + String.Format("{0} is in use.", outputFilename)); + } + catch (UnauthorizedAccessException unauthorizedEx) + { + // Couldn't delete a file + // because it was set to readonly + // or couldn't create a file + // because of permissions issues + logEventSource.TraceEvent(TraceEventType.Error, + (int)TraceEventType.Error, + errorDialogInstructionCouldNotWrite + + Environment.NewLine + + "Exception message: " + unauthorizedEx.Message); + DisplayErrorMessage(errorDialogCaption, + errorDialogInstructionCouldNotWrite + Environment.NewLine + + String.Format("Insufficient privileges to either create or delete {0}", outputFilename)); + + + } + catch (ExternalException ghostscriptEx) + { + // Ghostscript error + logEventSource.TraceEvent(TraceEventType.Error, + (int)TraceEventType.Error, + String.Format(errorDialogTextGhostScriptConversion, ghostscriptEx.ErrorCode.ToString()) + + Environment.NewLine + + "Exception message: " + ghostscriptEx.Message); + DisplayErrorMessage(errorDialogCaption, + errorDialogInstructionPDFGeneration + Environment.NewLine + + String.Format(errorDialogTextGhostScriptConversion, ghostscriptEx.ErrorCode.ToString())); + + } + finally + { + try + { + File.Delete(standardInputFilename); + } + catch + { + logEventSource.TraceEvent(TraceEventType.Warning, + (int)TraceEventType.Warning, + String.Format(warnFileNotDeleted, standardInputFilename)); + } + logEventSource.Flush(); + } + } + + /// + /// All unhandled exceptions will bubble their way up here - + /// a final error dialog will be displayed before the crash and burn + /// + /// + /// + static void Application_UnhandledException(object sender, UnhandledExceptionEventArgs e) + { + logEventSource.TraceEvent(TraceEventType.Critical, + (int)TraceEventType.Critical, + ((Exception)e.ExceptionObject).Message + Environment.NewLine + + ((Exception)e.ExceptionObject).StackTrace); + DisplayErrorMessage(errorDialogCaption, + errorDialogInstructionUnexpectedError); + } + + static bool GetPdfOutputFilename(ref String outputFile) + { + bool filenameRetrieved = false; + switch (Properties.Settings.Default.AskUserForOutputFilename) + { + case (true) : + using (SetOutputFilename dialogOwner = new SetOutputFilename()) + { + dialogOwner.TopMost = true; + dialogOwner.TopLevel = true; + dialogOwner.Show(); // Form won't actually show - Application.Run() never called + // but having a topmost/toplevel owner lets us bring the SaveFileDialog to the front + dialogOwner.BringToFront(); + using (SaveFileDialog pdfFilenameDialog = new SaveFileDialog()) + { + pdfFilenameDialog.AddExtension = true; + pdfFilenameDialog.AutoUpgradeEnabled = true; + pdfFilenameDialog.CheckPathExists = true; + pdfFilenameDialog.Filter = "pdf files (*.pdf)|*.pdf"; + pdfFilenameDialog.ShowHelp = false; + pdfFilenameDialog.Title = "PDF Scribe - Set output filename"; + pdfFilenameDialog.ValidateNames = true; + if (pdfFilenameDialog.ShowDialog(dialogOwner) == DialogResult.OK) + { + outputFile = pdfFilenameDialog.FileName; + filenameRetrieved = true; + } + } + dialogOwner.Close(); + } + break; + default: + outputFile = GetOutputFilename(); + filenameRetrieved = true; + break; + } + return filenameRetrieved; + + } + + private static String GetOutputFilename() + { + + String outputFilename = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), defaultOutputFilename); + if (!String.IsNullOrEmpty(Properties.Settings.Default.OutputFile) && + !String.IsNullOrWhiteSpace(Properties.Settings.Default.OutputFile)) + { + if (IsFilePathValid(Properties.Settings.Default.OutputFile)) + { + outputFilename = Properties.Settings.Default.OutputFile; + } + else + { + if (IsFilePathValid(Environment.ExpandEnvironmentVariables(Properties.Settings.Default.OutputFile))) + { + outputFilename = Environment.ExpandEnvironmentVariables(Properties.Settings.Default.OutputFile); + } + } + } + else + { + logEventSource.TraceEvent(TraceEventType.Warning, + (int)TraceEventType.Warning, + String.Format("Using default output filename {0}", + outputFilename)); + } + return outputFilename; + } + + static bool IsFilePathValid(String filePath) + { + bool pathIsValid = false; + + if (!String.IsNullOrEmpty(filePath) && filePath.Length <= 260) + { + String directoryName = Path.GetDirectoryName(filePath); + String filename = Path.GetFileName(filePath); + + if (Directory.Exists(directoryName)) + { + // Check for invalid filename chars + Regex containsABadCharacter = new Regex("[" + + Regex.Escape(new String(System.IO.Path.GetInvalidPathChars())) + "]"); + pathIsValid = !containsABadCharacter.IsMatch(filename); + } + } + else + { + logEventSource.TraceEvent(TraceEventType.Warning, + (int)TraceEventType.Warning, + "Output filename is longer than 260 characters, or blank."); + } + return pathIsValid; + } + /// /// Opens the PDF in the default viewer /// if the OpenAfterCreating app setting is "True" /// and the file extension is .PDF /// - /// + /// static void DisplayPdf(String pdfFilename) { if (Properties.Settings.Default.OpenAfterCreating && @@ -255,25 +255,25 @@ namespace PdfScribe (Path.GetExtension(pdfFilename).ToUpper() == ".PDF")) { Process.Start(pdfFilename); - } - } - - /// - /// Displays up a topmost, OK-only message box for the error message - /// - /// The box's caption - /// The box's message - static void DisplayErrorMessage(String boxCaption, - String boxMessage) - { - - MessageBox.Show(boxMessage, - boxCaption, - MessageBoxButtons.OK, - MessageBoxIcon.Error, - MessageBoxDefaultButton.Button1, - MessageBoxOptions.DefaultDesktopOnly); - - } - } -} + } + } + + /// + /// Displays up a topmost, OK-only message box for the error message + /// + /// The box's caption + /// The box's message + static void DisplayErrorMessage(String boxCaption, + String boxMessage) + { + + MessageBox.Show(boxMessage, + boxCaption, + MessageBoxButtons.OK, + MessageBoxIcon.Error, + MessageBoxDefaultButton.Button1, + MessageBoxOptions.DefaultDesktopOnly); + + } + } +}