Added custom action project, more refactoring, and tracing code added

This commit is contained in:
S T Chan 2013-12-19 20:04:08 -05:00
parent bb89078901
commit e8d202746a
12 changed files with 386 additions and 36 deletions

View File

@ -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

View File

@ -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;
/// <summary>
///
/// </summary>
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();
}
}
/// <summary>
/// Shuts down the thread showing
/// the ActivityNotification WPF window
/// </summary>
public void CloseActivityNotificationWindow()
{
if (activityWindow != null)
activityWindow.Dispatcher.InvokeShutdown();
}
}
}

View File

@ -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
/// <summary>
/// Default constructor
/// </summary>
public ErrorDialogPresenter()
{}
/// <summary>
/// Ctor overload that shows the
/// task dialog immediately
/// </summary>
/// <param name="captionText"></param>
/// <param name="instructionText"></param>
/// <param name="messageText"></param>
public ErrorDialogPresenter(String captionText,
String instructionText,
String messageText)
{
ShowSimple(captionText, instructionText, messageText);
}
#endregion
/// <summary>
/// Pops up a simple TaskDialog box
/// with a standard error icon, and
/// just a Close button
/// </summary>
/// <param name="captionText"></param>
/// <param name="instructionText"></param>
/// <param name="messageText"></param>
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;
}
}
}

View File

@ -71,6 +71,9 @@
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.WindowsAPICodePack">
<HintPath>..\Lib\Microsoft.WindowsAPICodePack.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
@ -89,6 +92,8 @@
<Compile Include="ActivityNotification.xaml.cs">
<DependentUpon>ActivityNotification.xaml</DependentUpon>
</Compile>
<Compile Include="ActivityNotificationPresenter.cs" />
<Compile Include="ErrorDialogPresenter.cs" />
<Compile Include="GhostScript64.cs" />
<Compile Include="NativeMethods.cs" />
<Compile Include="Program.cs" />

View File

@ -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
/// <param name="e"></param>
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();
}
}
}

View File

@ -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

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<!--
Use supportedRuntime tags to explicitly specify the version(s) of the .NET Framework runtime that
the custom action should run on. If no versions are specified, the chosen version of the runtime
will be the "best" match to what Microsoft.Deployment.WindowsInstaller.dll was built against.
WARNING: leaving the version unspecified is dangerous as it introduces a risk of compatibility
problems with future versions of the .NET Framework runtime. It is highly recommended that you specify
only the version(s) of the .NET Framework runtime that you have tested against.
Note for .NET Framework v3.0 and v3.5, the runtime version is still v2.0.
In order to enable .NET Framework version 2.0 runtime activation policy, which is to load all assemblies
by using the latest supported runtime, @useLegacyV2RuntimeActivationPolicy="true".
For more information, see http://msdn.microsoft.com/en-us/library/bbx34a2h.aspx
-->
<supportedRuntime version="v4.0" />
<supportedRuntime version="v2.0.50727"/>
</startup>
<!--
Add additional configuration settings here. For more information on application config files,
see http://msdn.microsoft.com/en-us/library/kza1yk3a.aspx
-->
</configuration>

View File

@ -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;
}
}
}

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{E8679E1B-8C89-4201-97D5-7E43C5A486C9}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PdfScribeInstallCustomAction</RootNamespace>
<AssemblyName>PdfScribeInstallCustomAction</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<WixCATargetsPath Condition=" '$(WixCATargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.CA.targets</WixCATargetsPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
<CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
<CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.Deployment.WindowsInstaller" />
</ItemGroup>
<ItemGroup>
<Compile Include="CustomAction.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Content Include="CustomAction.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PdfScribeCore\PdfScribeCore.csproj">
<Project>{1EAD8E9A-A123-4C37-B31E-AEE1354DF003}</Project>
<Name>PdfScribeCore</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(WixCATargetsPath)" />
</Project>

View File

@ -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")]

View File

@ -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");
}
}
}

View File

@ -31,9 +31,11 @@
</application>
</compatibility>
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
<!-- <dependency>
<dependency>
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
<dependentAssembly>
<!-- Uncommented this so Visual Studio will show TaskDialogs properly while in debug mode -->
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
@ -43,6 +45,5 @@
language="*"
/>
</dependentAssembly>
</dependency>-->
</dependency>
</asmv1:assembly>