예제 #1
0
        static void Main(string[] args)
        {
            string[]           files                  = new string[2];
            int                filesSeen              = 0;
            Boolean            postProcessPDF         = false;
            Boolean            postProcessPDFSecurity = false;
            Hashtable          options                = new Hashtable();
            List <PDFBookmark> documentBookmarks      = new List <PDFBookmark>();

            // Loop through the input, grabbing switches off the command line
            options["hidden"]                                = false;
            options["markup"]                                = false;
            options["readonly"]                              = false;
            options["bookmarks"]                             = false;
            options["print"]                                 = true;
            options["screen"]                                = false;
            options["pdfa"]                                  = false;
            options["verbose"]                               = false;
            options["excludeprops"]                          = false;
            options["excludetags"]                           = false;
            options["noquit"]                                = false;
            options["merge"]                                 = false;
            options["template"]                              = "";
            options["password"]                              = "";
            options["excel_show_formulas"]                   = false;
            options["excel_show_headings"]                   = false;
            options["excel_auto_macros"]                     = false;
            options["excel_template_macros"]                 = false;
            options["excel_active_sheet"]                    = false;
            options["excel_no_link_update"]                  = false;
            options["excel_no_recalculate"]                  = false;
            options["excel_max_rows"]                        = (int)0;
            options["excel_worksheet"]                       = (int)0;
            options["word_field_quick_update"]               = false;
            options["word_field_quick_update_safe"]          = false;
            options["word_no_field_update"]                  = false;
            options["word_header_dist"]                      = (float)-1;
            options["word_footer_dist"]                      = (float)-1;
            options["word_max_pages"]                        = (int)0;
            options["word_ref_fonts"]                        = false;
            options["word_keep_history"]                     = false;
            options["original_filename"]                     = "";
            options["original_basename"]                     = "";
            options["pdf_page_mode"]                         = null;
            options["pdf_layout"]                            = null;
            options["pdf_merge"]                             = (int)MergeMode.None;
            options["pdf_clean_meta"]                        = (int)MetaClean.None;
            options["pdf_owner_pass"]                        = "";
            options["pdf_user_pass"]                         = "";
            options["pdf_restrict_annotation"]               = false;
            options["pdf_restrict_extraction"]               = false;
            options["pdf_restrict_assembly"]                 = false;
            options["pdf_restrict_forms"]                    = false;
            options["pdf_restrict_modify"]                   = false;
            options["pdf_restrict_print"]                    = false;
            options["pdf_restrict_annotation"]               = false;
            options["pdf_restrict_accessibility_extraction"] = false;
            options["pdf_restrict_full_quality"]             = false;

            Regex switches = new Regex(@"^/(version|hidden|markup|readonly|bookmarks|merge|noquit|print|screen|pdfa|template|writepassword|password|help|verbose|exclude(props|tags)|excel_(max_rows|show_formulas|show_headings|auto_macros|template_macros|active_sheet|worksheet|no_recalculate|no_link_update)|word_(header_dist|footer_dist|ref_fonts|no_field_update|field_quick_update(_safe)?|max_pages|keep_history)|pdf_(page_mode|append|prepend|layout|clean_meta|owner_pass|user_pass|restrict_(annotation|extraction|assembly|forms|modify|print|accessibility_extraction|full_quality))|\?)$", RegexOptions.IgnoreCase);

            for (int argIdx = 0; argIdx < args.Length; argIdx++)
            {
                string item = args[argIdx];
                // see if this starts with a /
                Match m = Regex.Match(item, @"^/");
                if (m.Success)
                {
                    // This is an option
                    Match itemMatch = switches.Match(item);
                    if (itemMatch.Success)
                    {
                        if (itemMatch.Groups[1].Value.ToLower().Equals("help") ||
                            itemMatch.Groups[1].Value.Equals("?"))
                        {
                            showHelp();
                        }
                        switch (itemMatch.Groups[1].Value.ToLower())
                        {
                        case "pdf_page_mode":
                            if (argIdx + 2 < args.Length)
                            {
                                postProcessPDF = true;
                                var pageMode = args[argIdx + 1];
                                pageMode = pageMode.ToLower();
                                switch (pageMode)
                                {
                                case "full":
                                    options["pdf_page_mode"] = PdfPageMode.FullScreen;
                                    break;

                                case "none":
                                    options["pdf_page_mode"] = PdfPageMode.UseNone;
                                    break;

                                case "bookmarks":
                                    options["pdf_page_mode"] = PdfPageMode.UseOutlines;
                                    break;

                                case "thumbs":
                                    options["pdf_page_mode"] = PdfPageMode.UseThumbs;
                                    break;

                                default:
                                    Console.WriteLine("Invalid PDF page mode ({0}). It must be one of full, none, outline or thumbs", args[argIdx + 1]);
                                    Environment.Exit((int)(ExitCode.Failed | ExitCode.InvalidArguments));
                                    break;
                                }
                                argIdx++;
                            }
                            break;

                        case "pdf_clean_meta":
                            if (argIdx + 2 < args.Length)
                            {
                                postProcessPDF = true;
                                var cleanType = args[argIdx + 1];
                                cleanType = cleanType.ToLower();
                                switch (cleanType)
                                {
                                case "basic":
                                    options["pdf_clean_meta"] = MetaClean.Basic;
                                    break;

                                case "full":
                                    options["pdf_clean_meta"] = MetaClean.Full;
                                    break;

                                default:
                                    Console.WriteLine("Invalid PDF meta-data clean value ({0}). It must be one of full or basic", args[argIdx + 1]);
                                    Environment.Exit((int)(ExitCode.Failed | ExitCode.InvalidArguments));
                                    break;
                                }
                                argIdx++;
                            }
                            break;

                        case "pdf_layout":
                            if (argIdx + 2 < args.Length)
                            {
                                postProcessPDF = true;
                                var pdfLayout = args[argIdx + 1];
                                pdfLayout = pdfLayout.ToLower();
                                switch (pdfLayout)
                                {
                                case "onecol":
                                    options["pdf_layout"] = PdfPageLayout.OneColumn;
                                    break;

                                case "single":
                                    options["pdf_layout"] = PdfPageLayout.SinglePage;
                                    break;

                                case "twocolleft":
                                    options["pdf_layout"] = PdfPageLayout.TwoColumnLeft;
                                    break;

                                case "twocolright":
                                    options["pdf_layout"] = PdfPageLayout.TwoColumnRight;
                                    break;

                                case "twopageleft":
                                    options["pdf_layout"] = PdfPageLayout.TwoPageLeft;
                                    break;

                                case "twopageright":
                                    options["pdf_layout"] = PdfPageLayout.TwoPageRight;
                                    break;

                                default:
                                    Console.WriteLine("Invalid PDF layout ({0}). It must be one of onecol, single, twocolleft, twocolright, twopageleft or twopageright", args[argIdx + 1]);
                                    Environment.Exit((int)(ExitCode.Failed | ExitCode.InvalidArguments));
                                    break;
                                }
                                argIdx++;
                            }
                            break;

                        case "pdf_owner_pass":
                        case "pdf_user_pass":
                            if (argIdx + 2 < args.Length)
                            {
                                postProcessPDF         = true;
                                postProcessPDFSecurity = true;
                                var pass = args[argIdx + 1];
                                // Set the password
                                options[itemMatch.Groups[1].Value.ToLower()] = pass;
                                argIdx++;
                            }
                            break;

                        case "template":
                            // Only accept the next option if there are enough options
                            if (argIdx + 2 < args.Length)
                            {
                                if (File.Exists(args[argIdx + 1]))
                                {
                                    FileInfo templateInfo = new FileInfo(args[argIdx + 1]);
                                    options[itemMatch.Groups[1].Value.ToLower()] = templateInfo.FullName;
                                }
                                else
                                {
                                    Console.WriteLine("Unable to find {0} {1}", itemMatch.Groups[1].Value.ToLower(), args[argIdx + 1]);
                                }
                                argIdx++;
                            }
                            break;

                        case "excel_max_rows":
                            // Only accept the next option if there are enough options
                            if (argIdx + 2 < args.Length)
                            {
                                if (Regex.IsMatch(args[argIdx + 1], @"^\d+$"))
                                {
                                    options[itemMatch.Groups[1].Value.ToLower()] = (int)Convert.ToInt32(args[argIdx + 1]);
                                }
                                else
                                {
                                    Console.WriteLine("Maximum number of rows ({0}) is invalid", args[argIdx + 1]);
                                    Environment.Exit((int)(ExitCode.Failed | ExitCode.InvalidArguments));
                                }
                                argIdx++;
                            }
                            break;

                        case "excel_worksheet":
                            // Only accept the next option if there are enough options
                            if (argIdx + 2 < args.Length)
                            {
                                if (Regex.IsMatch(args[argIdx + 1], @"^\d+$"))
                                {
                                    options[itemMatch.Groups[1].Value.ToLower()] = (int)Convert.ToInt32(args[argIdx + 1]);
                                }
                                else
                                {
                                    Console.WriteLine("Excel worksheet ({0}) is invalid", args[argIdx + 1]);
                                    Environment.Exit((int)(ExitCode.Failed | ExitCode.InvalidArguments));
                                }
                                argIdx++;
                            }
                            break;

                        case "word_header_dist":
                        case "word_footer_dist":
                            // Only accept the next option if there are enough options
                            if (argIdx + 2 < args.Length)
                            {
                                if (Regex.IsMatch(args[argIdx + 1], @"^[\d\.]+$"))
                                {
                                    try
                                    {
                                        options[itemMatch.Groups[1].Value.ToLower()] = (float)Convert.ToDouble(args[argIdx + 1]);
                                    }
                                    catch (Exception)
                                    {
                                        Console.WriteLine("Header/Footer distance ({0}) is invalid", args[argIdx + 1]);
                                        Environment.Exit((int)(ExitCode.Failed | ExitCode.InvalidArguments));
                                    }
                                }
                                else
                                {
                                    Console.WriteLine("Header/Footer distance ({0}) is invalid", args[argIdx + 1]);
                                    Environment.Exit((int)(ExitCode.Failed | ExitCode.InvalidArguments));
                                }
                                argIdx++;
                            }
                            break;

                        case "word_max_pages":
                            // Only accept the next option if there are enough options
                            if (argIdx + 2 < args.Length)
                            {
                                if (Regex.IsMatch(args[argIdx + 1], @"^\d+$"))
                                {
                                    options[itemMatch.Groups[1].Value.ToLower()] = (int)Convert.ToInt32(args[argIdx + 1]);
                                }
                                else
                                {
                                    Console.WriteLine("Maximum number of pages ({0}) is invalid", args[argIdx + 1]);
                                    Environment.Exit((int)(ExitCode.Failed | ExitCode.InvalidArguments));
                                }
                                argIdx++;
                            }
                            break;

                        case "password":
                        case "writepassword":
                            // Only accept the next option if there are enough options
                            if (argIdx + 2 < args.Length)
                            {
                                options[itemMatch.Groups[1].Value.ToLower()] = args[argIdx + 1];
                                argIdx++;
                            }
                            break;

                        case "screen":
                            options["print"] = false;
                            options[itemMatch.Groups[1].Value.ToLower()] = true;
                            break;

                        case "print":
                            options["screen"] = false;
                            options[itemMatch.Groups[1].Value.ToLower()] = true;
                            break;

                        case "version":
                            Assembly        asm = Assembly.GetExecutingAssembly();
                            FileVersionInfo fv  = System.Diagnostics.FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location);
                            Console.WriteLine(String.Format("{0}", fv.FileVersion));
                            Environment.Exit((int)ExitCode.Success);
                            break;

                        case "pdf_append":
                            if ((MergeMode)options["pdf_merge"] != MergeMode.None)
                            {
                                Console.WriteLine("Only one of /pdf_append or /pdf_prepend can be used");
                                Environment.Exit((int)(ExitCode.Failed | ExitCode.InvalidArguments));
                            }
                            postProcessPDF       = true;
                            options["pdf_merge"] = MergeMode.Append;
                            break;

                        case "pdf_prepend":
                            if ((MergeMode)options["pdf_merge"] != MergeMode.None)
                            {
                                Console.WriteLine("Only one of /pdf_append or /pdf_prepend can be used");
                                Environment.Exit((int)(ExitCode.Failed | ExitCode.InvalidArguments));
                            }
                            postProcessPDF       = true;
                            options["pdf_merge"] = MergeMode.Prepend;
                            break;

                        case "pdf_restrict_annotation":
                        case "pdf_restrict_extraction":
                        case "pdf_restrict_assembly":
                        case "pdf_restrict_forms":
                        case "pdf_restrict_modify":
                        case "pdf_restrict_print":
                        case "pdf_restrict_full_quality":
                        case "pdf_restrict_accessibility_extraction":
                            postProcessPDFSecurity = true;
                            options[itemMatch.Groups[1].Value.ToLower()] = true;
                            break;

                        default:
                            options[itemMatch.Groups[1].Value.ToLower()] = true;
                            break;
                        }
                    }
                    else
                    {
                        Console.WriteLine("Unknown option: {0}", item);
                        Environment.Exit((int)(ExitCode.Failed | ExitCode.InvalidArguments));
                    }
                }
                else if (filesSeen < 2)
                {
                    files[filesSeen++] = item;
                }
            }

            // Need to error here, as we need input and output files as the
            // arguments to this script
            if (filesSeen != 1 && filesSeen != 2)
            {
                showHelp();
            }

            // Make sure we only choose one of /screen or /print options
            if ((Boolean)options["screen"] && (Boolean)options["print"])
            {
                Console.WriteLine("You can only use one of /screen or /print - not both");
                Environment.Exit((int)(ExitCode.Failed | ExitCode.InvalidArguments));
            }

            // Make sure the input file looks like something we can handle (i.e. has an office
            // filename extension)
            Regex fileMatch = new Regex(@"\.(((ppt|pps|pot|do[ct]|xls|xlt)[xm]?)|xlsb|od[spt]|rtf|csv|vsd[xm]?|vd[xw]|em[fz]|dwg|dxf|wmf|pub|msg|vcf|ics|mpp|svg|txt|html?|wpd)$", RegexOptions.IgnoreCase);

            if (fileMatch.Matches(files[0]).Count != 1)
            {
                Console.WriteLine("Input file can not be handled. Must be Word, PowerPoint, Excel, Outlook, Publisher or Visio");
                Environment.Exit((int)(ExitCode.Failed | ExitCode.UnsupportedFileFormat));
            }

            if (filesSeen == 1)
            {
                // If only one file is seen, we just swap the extension
                files[1] = Path.ChangeExtension(files[0], "pdf");
            }
            else
            {
                // If the second file is a directory, then we want to create the PDF
                // with the same name as the original (changing the extension to pdf),
                // but in the directory given by the path
                if (Directory.Exists(files[1]))
                {
                    files[1] = Path.Combine(files[1], Path.GetFileNameWithoutExtension(files[0]) + ".pdf");
                }
            }

            String inputFile       = "";
            String outputFile      = "";
            String finalOutputFile = "";

            // Make sure the input file exists and is readable
            FileInfo info;

            try
            {
                info = new FileInfo(files[0]);

                if (info == null || !info.Exists)
                {
                    Console.WriteLine("Input file doesn't exist");
                    Environment.Exit((int)(ExitCode.Failed | ExitCode.FileNotFound));
                }
                inputFile = info.FullName;
                options["original_filename"] = info.Name;
                options["original_basename"] = info.Name.Substring(0, info.Name.Length - info.Extension.Length);
            }
            catch
            {
                Console.WriteLine("Unable to open input file");
                Environment.Exit((int)(ExitCode.Failed | ExitCode.FileOpenFailure));
            }

            // Make sure the destination location exists
            FileInfo outputInfo = new FileInfo(files[1]);

            // Remove the destination unless we're doing a PDF merge
            if (outputInfo != null)
            {
                outputFile = finalOutputFile = outputInfo.FullName;
                if (outputInfo.Exists)
                {
                    if ((MergeMode)options["pdf_merge"] == MergeMode.None)
                    {
                        // We are not merging, so delete the final destination
                        System.IO.File.Delete(outputInfo.FullName);
                    }
                    else
                    {
                        // We are merging, so make a temporary file
                        outputFile = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".pdf";
                    }
                }
                else
                {
                    // If there is no current output, no need to merge
                    options["pdf_merge"] = MergeMode.None;
                }
            }
            else
            {
                Console.WriteLine("Unable to determine output location");
                Environment.Exit((int)(ExitCode.Failed | ExitCode.DirectoryNotFound));
            }

            if (!System.IO.Directory.Exists(outputInfo.DirectoryName))
            {
                Console.WriteLine("Output directory does not exist");
                Environment.Exit((int)(ExitCode.Failed | ExitCode.DirectoryNotFound));
            }


            // Now, do the cleverness of determining what the extension is, and so, which
            // conversion class to pass it to
            int   converted = (int)ExitCode.UnknownError;
            Match extMatch  = fileMatch.Match(inputFile);

            if (extMatch.Success)
            {
                // Set and environment variable so Office application VBA
                // code can check for un-attended conversion and avoid showing
                // blocking dialogs
                Environment.SetEnvironmentVariable("OFFICE2PDF_AUTO_CONVERT", "1");

                if ((Boolean)options["verbose"])
                {
                    Console.WriteLine("Converting {0} to {1}", inputFile, finalOutputFile);
                }
                switch (extMatch.Groups[1].ToString().ToLower())
                {
                case "rtf":
                case "odt":
                case "doc":
                case "dot":
                case "docx":
                case "dotx":
                case "docm":
                case "dotm":
                case "txt":
                case "html":
                case "htm":
                case "wpd":
                    // Word
                    if ((Boolean)options["verbose"])
                    {
                        Console.WriteLine("Converting with Word converter");
                    }
                    converted = WordConverter.Convert(inputFile, outputFile, options);
                    break;

                case "csv":
                case "ods":
                case "xls":
                case "xlsx":
                case "xlt":
                case "xltx":
                case "xlsm":
                case "xltm":
                case "xlsb":
                    // Excel
                    if ((Boolean)options["verbose"])
                    {
                        Console.WriteLine("Converting with Excel converter");
                    }
                    converted = ExcelConverter.Convert(inputFile, outputFile, options);
                    break;

                case "odp":
                case "ppt":
                case "pptx":
                case "pptm":
                case "pot":
                case "potm":
                case "potx":
                case "pps":
                case "ppsx":
                case "ppsm":
                    // Powerpoint
                    if ((Boolean)options["verbose"])
                    {
                        Console.WriteLine("Converting with Powerpoint converter");
                    }
                    converted = PowerpointConverter.Convert(inputFile, outputFile, options, ref documentBookmarks);
                    break;

                case "vsd":
                case "vsdm":
                case "vsdx":
                case "vdx":
                case "vdw":
                case "svg":
                case "emf":
                case "emz":
                case "dwg":
                case "dxf":
                case "wmf":
                    // Visio
                    if ((Boolean)options["verbose"])
                    {
                        Console.WriteLine("Converting with Visio converter");
                    }
                    converted = VisioConverter.Convert(inputFile, outputFile, options);
                    break;

                case "pub":
                    // Publisher
                    if ((Boolean)options["verbose"])
                    {
                        Console.WriteLine("Converting with Publisher converter");
                    }
                    converted = PublisherConverter.Convert(inputFile, outputFile, options, ref documentBookmarks);
                    break;

                case "msg":
                case "vcf":
                case "ics":
                    // Outlook
                    if ((Boolean)options["verbose"])
                    {
                        Console.WriteLine("Converting with Outlook converter");
                    }
                    converted = OutlookConverter.Convert(inputFile, outputFile, options);
                    break;

                case "mpp":
                    // Project
                    if ((Boolean)options["verbose"])
                    {
                        Console.WriteLine("Converting with Project converter");
                    }
                    converted = ProjectConverter.Convert(inputFile, outputFile, options);
                    break;
                }
            }
            if (converted != (int)ExitCode.Success)
            {
                Console.WriteLine("Did not convert");
                // Return the general failure code and the specific failure code
                Environment.Exit((int)ExitCode.Failed | converted);
            }
            else
            {
                if ((Boolean)options["verbose"])
                {
                    Console.WriteLine("Completed Conversion");
                }

                if (documentBookmarks.Count > 0)
                {
                    addPDFBookmarks(outputFile, documentBookmarks, options, null);
                }

                // Determine if we have to post-process the PDF
                if (postProcessPDF)
                {
                    postProcessPDFFile(outputFile, finalOutputFile, options, postProcessPDFSecurity);
                }
                Environment.Exit((int)ExitCode.Success);
            }
        }
        public static int ConvertOfficeToPDF(string[] args)
        {
            string[]  files     = new string[2];
            int       filesSeen = 0;
            Hashtable options   = new Hashtable
            {
                // Loop through the input, grabbing switches off the command line
                ["hidden"]              = false,
                ["markup"]              = false,
                ["readonly"]            = false,
                ["bookmarks"]           = false,
                ["print"]               = true,
                ["screen"]              = false,
                ["pdfa"]                = false,
                ["verbose"]             = false,
                ["excludeprops"]        = false,
                ["excludetags"]         = false,
                ["noquit"]              = false,
                ["merge"]               = false,
                ["template"]            = "",
                ["password"]            = "",
                ["excel_show_formulas"] = false,
                ["excel_show_headings"] = false,
                ["excel_auto_macros"]   = false,
                ["excel_max_rows"]      = (int)0,
                ["word_header_dist"]    = (float)-1,
                ["word_footer_dist"]    = (float)-1
            };
            Regex switches = new Regex(@"^/(hidden|markup|readonly|bookmarks|merge|noquit|print|screen|pdfa|template|writepassword|password|help|verbose|exclude(props|tags)|excel_max_rows|excel_show_formulas|excel_show_headings|excel_auto_macros|word_header_dist|word_footer_dist|\?)$", RegexOptions.IgnoreCase);

            for (int argIdx = 0; argIdx < args.Length; argIdx++)
            {
                string item = args[argIdx];
                // see if this starts with a /
                Match m = Regex.Match(item, @"^/");
                if (m.Success)
                {
                    // This is an option
                    Match itemMatch = switches.Match(item);
                    if (itemMatch.Success)
                    {
                        if (itemMatch.Groups[1].Value.ToLower().Equals("help") ||
                            itemMatch.Groups[1].Value.Equals("?"))
                        {
                            ShowHelp();
                        }
                        switch (itemMatch.Groups[1].Value.ToLower())
                        {
                        case "template":
                            // Only accept the next option if there are enough options
                            if (argIdx + 2 < args.Length)
                            {
                                if (File.Exists(args[argIdx + 1]))
                                {
                                    FileInfo templateInfo = new FileInfo(args[argIdx + 1]);
                                    options[itemMatch.Groups[1].Value.ToLower()] = templateInfo.FullName;
                                }
                                else
                                {
                                    message = "Unable to find " + itemMatch.Groups[1].Value.ToLower() + " " + args[argIdx + 1];
                                }
                                argIdx++;
                            }
                            break;

                        case "excel_max_rows":
                            // Only accept the next option if there are enough options
                            if (argIdx + 2 < args.Length)
                            {
                                if (Regex.IsMatch(args[argIdx + 1], @"^\d+$"))
                                {
                                    options[itemMatch.Groups[1].Value.ToLower()] = (int)Convert.ToInt32(args[argIdx + 1]);
                                }
                                else
                                {
                                    message = "Maximum number of rows (" + args[argIdx + 1] + ") is invalid";
                                    return((int)(ExitCode.Failed | ExitCode.InvalidArguments));
                                }
                                argIdx++;
                            }
                            break;

                        case "word_header_dist":
                        case "word_footer_dist":
                            // Only accept the next option if there are enough options
                            if (argIdx + 2 < args.Length)
                            {
                                if (Regex.IsMatch(args[argIdx + 1], @"^[\d\.]+$"))
                                {
                                    try
                                    {
                                        options[itemMatch.Groups[1].Value.ToLower()] = (float)Convert.ToDouble(args[argIdx + 1]);
                                    }
                                    catch (Exception)
                                    {
                                        message = "Header/Footer distance (" + args[argIdx + 1] + ") is invalid";
                                        return((int)(ExitCode.Failed | ExitCode.InvalidArguments));
                                    }
                                }
                                else
                                {
                                    message = "Header/Footer distance (" + args[argIdx + 1] + ") is invalid";
                                    return((int)(ExitCode.Failed | ExitCode.InvalidArguments));
                                }
                                argIdx++;
                            }
                            break;

                        case "password":
                        case "writepassword":
                            // Only accept the next option if there are enough options
                            if (argIdx + 2 < args.Length)
                            {
                                options[itemMatch.Groups[1].Value.ToLower()] = args[argIdx + 1];
                                argIdx++;
                            }
                            break;

                        case "screen":
                            options["print"] = false;
                            options[itemMatch.Groups[1].Value.ToLower()] = true;
                            break;

                        case "print":
                            options["screen"] = false;
                            options[itemMatch.Groups[1].Value.ToLower()] = true;
                            break;

                        default:
                            options[itemMatch.Groups[1].Value.ToLower()] = true;
                            break;
                        }
                    }
                    else
                    {
                        message = "Unknown option: " + item;
                        return((int)(ExitCode.Failed | ExitCode.InvalidArguments));
                    }
                }
                else if (filesSeen < 2)
                {
                    files[filesSeen++] = item;
                }
            }

            // Need to error here, as we need input and output files as the
            // arguments to this script
            if (filesSeen != 1 && filesSeen != 2)
            {
                ShowHelp();
            }

            // Make sure we only choose one of /screen or /print options
            if ((Boolean)options["screen"] && (Boolean)options["print"])
            {
                message = "You can only use one of /screen or /print - not both";
                return((int)(ExitCode.Failed | ExitCode.InvalidArguments));
            }

            // Make sure the input file looks like something we can handle (i.e. has an office
            // filename extension)
            Regex fileMatch = new Regex(@"\.(((ppt|pps|pot|do[ct]|xls|xlt)[xm]?)|od[cpt]|rtf|csv|vsd[xm]?|pub|msg|vcf|ics|mpp|svg|txt|html?)$", RegexOptions.IgnoreCase);

            if (fileMatch.Matches(files[0]).Count != 1)
            {
                message = "Input file can not be handled. Must be Word, PowerPoint, Excel, Outlook, Publisher or Visio";
                return((int)(ExitCode.Failed | ExitCode.UnsupportedFileFormat));
            }

            if (filesSeen == 1)
            {
                files[1] = Path.ChangeExtension(files[0], "pdf");
            }

            String inputFile = "";
            String outputFile;

            // Make sure the input file exists and is readable
            FileInfo info;

            try
            {
                info = new FileInfo(files[0]);

                if (info == null || !info.Exists)
                {
                    message = "Input file doesn't exist";
                    return((int)(ExitCode.Failed | ExitCode.FileNotFound));
                }
                inputFile = info.FullName;
            }
            catch
            {
                message = "Unable to open input file";
                return((int)(ExitCode.Failed | ExitCode.FileOpenFailure));
            }

            // Make sure the destination location exists
            FileInfo outputInfo = new FileInfo(files[1]);

            if (outputInfo != null && outputInfo.Exists)
            {
                System.IO.File.Delete(outputInfo.FullName);
            }
            if (!System.IO.Directory.Exists(outputInfo.DirectoryName))
            {
                message = "Output directory does not exist";
                return((int)(ExitCode.Failed | ExitCode.DirectoryNotFound));
            }
            outputFile = outputInfo.FullName;

            // Now, do the cleverness of determining what the extension is, and so, which
            // conversion class to pass it to
            int   converted = (int)ExitCode.UnknownError;
            Match extMatch  = fileMatch.Match(inputFile);

            if (extMatch.Success)
            {
                if ((Boolean)options["verbose"])
                {
                    message = "Converting " + inputFile + " to " + outputFile;
                }
                switch (extMatch.Groups[1].ToString().ToLower())
                {
                case "rtf":
                case "odt":
                case "doc":
                case "dot":
                case "docx":
                case "dotx":
                case "docm":
                case "dotm":
                case "txt":
                case "html":
                case "htm":
                    // Word
                    if ((Boolean)options["verbose"])
                    {
                        message = "Converting with Word converter";
                    }
                    converted = WordConverter.Convert(inputFile, outputFile, options);
                    break;

                case "csv":
                case "odc":
                case "xls":
                case "xlsx":
                case "xlt":
                case "xltx":
                case "xlsm":
                case "xltm":
                    // Excel
                    if ((Boolean)options["verbose"])
                    {
                        message = "Converting with Excel converter";
                    }
                    converted = ExcelConverter.Convert(inputFile, outputFile, options);
                    break;

                case "odp":
                case "ppt":
                case "pptx":
                case "pptm":
                case "pot":
                case "potm":
                case "potx":
                case "pps":
                case "ppsx":
                case "ppsm":
                    // Powerpoint
                    if ((Boolean)options["verbose"])
                    {
                        message = "Converting with Powerpoint converter";
                    }
                    converted = PowerpointConverter.Convert(inputFile, outputFile, options);
                    break;

                case "vsd":
                case "vsdm":
                case "vsdx":
                case "svg":
                    // Visio
                    if ((Boolean)options["verbose"])
                    {
                        message = "Converting with Visio converter";
                    }
                    converted = VisioConverter.Convert(inputFile, outputFile, options);
                    break;

                case "pub":
                    // Publisher
                    if ((Boolean)options["verbose"])
                    {
                        message = "Converting with Publisher converter";
                    }
                    converted = PublisherConverter.Convert(inputFile, outputFile, options);
                    break;

                case "msg":
                case "vcf":
                case "ics":
                    // Outlook
                    if ((Boolean)options["verbose"])
                    {
                        message = "Converting with Outlook converter";
                    }
                    converted = OutlookConverter.Convert(inputFile, outputFile, options);
                    break;

                case "mpp":
                    // Project
                    if ((Boolean)options["verbose"])
                    {
                        message = "Converting with Project converter";
                    }
                    converted = ProjectConverter.Convert(inputFile, outputFile, options);
                    break;
                }
            }
            if (converted != (int)ExitCode.Success)
            {
                message = "Did not convert";
                // Return the general failure code and the specific failure code
                return((int)ExitCode.Failed | converted);
            }
            else if ((Boolean)options["verbose"])
            {
                message = "Completed Conversion";
            }
            return((int)ExitCode.Success);
        }