diff --git a/PdfScribe.sln b/PdfScribe.sln index 924ef53..ee310c6 100644 --- a/PdfScribe.sln +++ b/PdfScribe.sln @@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PdfScribeCore", "PdfScribeC EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PdfScribe", "PdfScribe\PdfScribe.csproj", "{09BB3AA3-96D3-4BA1-BCB3-4E17067F42B2}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PdfScribeInstallCustomAction", "PdfScribeInstallCustomAction\PdfScribeInstallCustomAction.csproj", "{E8679E1B-8C89-4201-97D5-7E43C5A486C9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -49,6 +51,16 @@ Global {09BB3AA3-96D3-4BA1-BCB3-4E17067F42B2}.Release|x64.ActiveCfg = Release|x86 {09BB3AA3-96D3-4BA1-BCB3-4E17067F42B2}.Release|x86.ActiveCfg = Release|x86 {09BB3AA3-96D3-4BA1-BCB3-4E17067F42B2}.Release|x86.Build.0 = Release|x86 + {E8679E1B-8C89-4201-97D5-7E43C5A486C9}.Debug|Any CPU.ActiveCfg = Debug|x64 + {E8679E1B-8C89-4201-97D5-7E43C5A486C9}.Debug|x64.ActiveCfg = Debug|x64 + {E8679E1B-8C89-4201-97D5-7E43C5A486C9}.Debug|x64.Build.0 = Debug|x64 + {E8679E1B-8C89-4201-97D5-7E43C5A486C9}.Debug|x86.ActiveCfg = Debug|x86 + {E8679E1B-8C89-4201-97D5-7E43C5A486C9}.Debug|x86.Build.0 = Debug|x86 + {E8679E1B-8C89-4201-97D5-7E43C5A486C9}.Release|Any CPU.ActiveCfg = Release|x64 + {E8679E1B-8C89-4201-97D5-7E43C5A486C9}.Release|x64.ActiveCfg = Release|x64 + {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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/PdfScribe/ActivityNotificationPresenter.cs b/PdfScribe/ActivityNotificationPresenter.cs new file mode 100644 index 0000000..56dd505 --- /dev/null +++ b/PdfScribe/ActivityNotificationPresenter.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Windows; + + +namespace PdfScribe +{ + public class ActivityNotificationPresenter + { + public ActivityNotificationPresenter() + { + + } + + + private Application activityWindow = null; + + /// + /// + /// + public void ShowActivityNotificationWindow() + { + if (activityWindow == null) + { + this.activityWindow = new Application(); + var activityWindowThread = new Thread(new ThreadStart(() => + { + activityWindow = new Application(); + activityWindow.ShutdownMode = ShutdownMode.OnExplicitShutdown; + activityWindow.Run(new ActivityNotification()); + } + )); + activityWindowThread.SetApartmentState(ApartmentState.STA); + activityWindowThread.Start(); + } + } + + /// + /// Shuts down the thread showing + /// the ActivityNotification WPF window + /// + public void CloseActivityNotificationWindow() + { + if (activityWindow != null) + activityWindow.Dispatcher.InvokeShutdown(); + } + + } +} diff --git a/PdfScribe/ErrorDialogPresenter.cs b/PdfScribe/ErrorDialogPresenter.cs new file mode 100644 index 0000000..308c0b4 --- /dev/null +++ b/PdfScribe/ErrorDialogPresenter.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows; + +using APICodePack = Microsoft.WindowsAPICodePack.Dialogs; + +namespace PdfScribe +{ + public class ErrorDialogPresenter + { + #region Ctor + /// + /// Default constructor + /// + public ErrorDialogPresenter() + {} + + /// + /// Ctor overload that shows the + /// task dialog immediately + /// + /// + /// + /// + public ErrorDialogPresenter(String captionText, + String instructionText, + String messageText) + { + ShowSimple(captionText, instructionText, messageText); + } + + #endregion + + /// + /// Pops up a simple TaskDialog box + /// with a standard error icon, and + /// just a Close button + /// + /// + /// + /// + public void ShowSimple(String captionText, + String instructionText, + String messageText) + { + using (APICodePack.TaskDialog errorDialog = new APICodePack.TaskDialog()) + { + errorDialog.Caption = captionText; + errorDialog.InstructionText = instructionText; + errorDialog.Text = messageText; + errorDialog.Icon = APICodePack.TaskDialogStandardIcon.Error; + errorDialog.StandardButtons = APICodePack.TaskDialogStandardButtons.Close; + errorDialog.Opened += new EventHandler(errorDialog_Opened); + errorDialog.Show(); + } + } + + private void errorDialog_Opened(object sender, EventArgs e) + { + // Really fucking annoying - + // There's a bug somewhere in the API Code Pack that + // causes the icon not to show + // unless you set it on the Opened event + // See: http://stackoverflow.com/questions/15645592/taskdialogstandardicon-not-working-on-task-dialog + // One of these days I'll try to find and fix it (honestly I hope + // someone else fixes first - also why isn't the API Code pack on codeplex + // or github so people can push patches), but until then... + ((APICodePack.TaskDialog)sender).Icon = APICodePack.TaskDialogStandardIcon.Error; + } + + } +} diff --git a/PdfScribe/PdfScribe.csproj b/PdfScribe/PdfScribe.csproj index 2c8e78c..2c97ecf 100644 --- a/PdfScribe/PdfScribe.csproj +++ b/PdfScribe/PdfScribe.csproj @@ -71,6 +71,9 @@ prompt + + ..\Lib\Microsoft.WindowsAPICodePack.dll + @@ -89,6 +92,8 @@ ActivityNotification.xaml + + diff --git a/PdfScribe/Program.cs b/PdfScribe/Program.cs index c3578ab..072da01 100644 --- a/PdfScribe/Program.cs +++ b/PdfScribe/Program.cs @@ -1,31 +1,50 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading; -using System.Windows; namespace PdfScribe { public class Program { - static Application activityWindow; + + #region Error messages + 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 unexpected, and unhandled error in PDF Scribe."; + + const string errorDialogTextFileInUse = "{0} is being used by another process."; + const string errorDialogTextGhostScriptConversion = "Ghostscript error code {0}."; + + #endregion + + #region Other constants + const string traceSourceName = "PdfScribe"; + + const string defaultOutputFilename = "OAISISSOFTSCAN.PDF"; + + #endregion + + static ActivityNotificationPresenter userDisplay = new ActivityNotificationPresenter(); + static TraceSource logEventSource = new TraceSource(traceSourceName); [STAThread] static void Main(string[] args) { // Install the global exception handler AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(Application_UnhandledException); - - ShowActivitityNotificationWindow(); + userDisplay.ShowActivityNotificationWindow(); Thread.Sleep(3000); String standardInputFilename = Path.GetTempFileName(); - String outputFilename = Path.Combine(Path.GetTempPath(), "OAISISSOFTSCAN.PDF"); + String outputFilename = Path.Combine(Path.GetTempPath(), defaultOutputFilename); // Only set absolute minimum parameters, let the postscript input // dictate as much as possible @@ -46,10 +65,13 @@ namespace PdfScribe } GhostScript64.CallAPI(ghostScriptArguments); } - catch (IOException) + catch (IOException ioEx) { // We couldn't delete, or create a file // because it was in use + ErrorDialogPresenter errorDialog = new ErrorDialogPresenter(errorDialogCaption, + errorDialogInstructionCouldNotWrite, + String.Empty); } catch (UnauthorizedAccessException) { @@ -57,16 +79,26 @@ namespace PdfScribe // because it was set to readonly // or couldn't create a file // because of permissions issues + ErrorDialogPresenter errorDialog = new ErrorDialogPresenter(errorDialogCaption, + errorDialogInstructionCouldNotWrite, + String.Empty); } - catch (ExternalException) + catch (ExternalException ghostscriptEx) { // Ghostscript error + ErrorDialogPresenter errorDialog = new ErrorDialogPresenter(errorDialogCaption, + errorDialogInstructionPDFGeneration, + String.Format(errorDialogTextGhostScriptConversion, ghostscriptEx.ErrorCode.ToString())); } finally { - File.Delete(standardInputFilename); - CloseActivityNotificationWindow(); + try + { + File.Delete(standardInputFilename); + } + catch {} + userDisplay.CloseActivityNotificationWindow(); } } @@ -77,26 +109,11 @@ namespace PdfScribe /// static void Application_UnhandledException(object sender, UnhandledExceptionEventArgs e) { - throw new NotImplementedException(); + ErrorDialogPresenter errorDialog = new ErrorDialogPresenter(errorDialogCaption, + errorDialogInstructionUnexpectedError, + String.Empty); } - public static void ShowActivitityNotificationWindow() - { - var activityWindowThread = new Thread(new ThreadStart(() => - { - activityWindow = new Application(); - activityWindow.ShutdownMode = ShutdownMode.OnExplicitShutdown; - activityWindow.Run(new ActivityNotification()); - } - )); - activityWindowThread.SetApartmentState(ApartmentState.STA); - activityWindowThread.Start(); - } - - public static void CloseActivityNotificationWindow() - { - activityWindow.Dispatcher.InvokeShutdown(); - } } } diff --git a/PdfScribeCore/PdfScribeInstaller.cs b/PdfScribeCore/PdfScribeInstaller.cs index 85a5727..65155b1 100644 --- a/PdfScribeCore/PdfScribeInstaller.cs +++ b/PdfScribeCore/PdfScribeInstaller.cs @@ -32,7 +32,9 @@ namespace PdfScribeCore #endregion - private static readonly TraceSource logEventSource = new TraceSource("PdfScribeCore"); + //private static readonly TraceSource logEventSource = new TraceSource("PdfScribeCore"); + private readonly TraceSource logEventSource; + private readonly String logEventSourceNameDefault = "PdfScribeCore"; const string ENVIRONMENT_64 = "Windows x64"; const string PRINTERNAME = "PDF Scribe"; @@ -75,6 +77,28 @@ namespace PdfScribeCore #endregion + + #region Constructors + + public PdfScribeInstaller() + { + this.logEventSource = new TraceSource(logEventSourceNameDefault); + } + + public PdfScribeInstaller(String eventSourceName) + { + if (!String.IsNullOrEmpty(eventSourceName)) + { + this.logEventSource = new TraceSource(eventSourceName); + } + else + { + throw new ArgumentNullException("eventSourceName"); + } + } + + #endregion + #region Port operations #if DEBUG diff --git a/PdfScribeInstallCustomAction/CustomAction.config b/PdfScribeInstallCustomAction/CustomAction.config new file mode 100644 index 0000000..de951b7 --- /dev/null +++ b/PdfScribeInstallCustomAction/CustomAction.config @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + diff --git a/PdfScribeInstallCustomAction/CustomAction.cs b/PdfScribeInstallCustomAction/CustomAction.cs new file mode 100644 index 0000000..35657fe --- /dev/null +++ b/PdfScribeInstallCustomAction/CustomAction.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.Deployment.WindowsInstaller; + +namespace PdfScribeInstallCustomAction +{ + public class CustomActions + { + [CustomAction] + public static ActionResult CustomAction1(Session session) + { + session.Log("Begin CustomAction1"); + + return ActionResult.Success; + } + } +} diff --git a/PdfScribeInstallCustomAction/PdfScribeInstallCustomAction.csproj b/PdfScribeInstallCustomAction/PdfScribeInstallCustomAction.csproj new file mode 100644 index 0000000..3c3c308 --- /dev/null +++ b/PdfScribeInstallCustomAction/PdfScribeInstallCustomAction.csproj @@ -0,0 +1,75 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {E8679E1B-8C89-4201-97D5-7E43C5A486C9} + Library + Properties + PdfScribeInstallCustomAction + PdfScribeInstallCustomAction + v4.0 + 512 + $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.CA.targets + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + prompt + true + true + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + prompt + true + true + + + + + + + + + + + + + + + + + {1EAD8E9A-A123-4C37-B31E-AEE1354DF003} + PdfScribeCore + + + + + \ No newline at end of file diff --git a/PdfScribeInstallCustomAction/Properties/AssemblyInfo.cs b/PdfScribeInstallCustomAction/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..9aec689 --- /dev/null +++ b/PdfScribeInstallCustomAction/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("PdfScribeInstallCustomAction")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("PdfScribeInstallCustomAction")] +[assembly: AssemblyCopyright("Copyright © 2013")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("22a83aa8-5074-4636-8fb1-95939670fd8a")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/PdfScribeUnitTests/UnitTests.cs b/PdfScribeUnitTests/UnitTests.cs index cf63e7a..c5256eb 100644 --- a/PdfScribeUnitTests/UnitTests.cs +++ b/PdfScribeUnitTests/UnitTests.cs @@ -40,7 +40,7 @@ namespace PdfScribeUnitTests scribeInstaller.InstallSoftscanPrinter_Test(); } - [Test] + //[Test] public void Test_UninstallPdfScribePrinter() { var scribeInstaller = new PdfScribeInstaller(); @@ -59,9 +59,13 @@ namespace PdfScribeUnitTests //[Test] public void Test_ShowActivityWindows() { - PdfScribe.Program.ShowActivitityNotificationWindow(); - Thread.Sleep(3000); - PdfScribe.Program.CloseActivityNotificationWindow(); + + } + + [Test] + public void Test_ShowSimpleError() + { + var errorDialog = new PdfScribe.ErrorDialogPresenter("Error Caption", "Error Instructions", "Message text"); } } } diff --git a/PdfScribeUnitTests/app.manifest b/PdfScribeUnitTests/app.manifest index 9e0556d..95b5839 100644 --- a/PdfScribeUnitTests/app.manifest +++ b/PdfScribeUnitTests/app.manifest @@ -31,9 +31,11 @@ - - + - --> - +