Example #1
0
 /// <summary>
 ///     Raised when the Chrome process exits
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void _chromeProcess_Exited(object sender, EventArgs e)
 {
     try
     {
         // ReSharper disable once AccessToModifiedClosure
         if (_chromeProcess == null)
         {
             return;
         }
         WriteToLog("Chrome exited unexpectedly, arguments used: " + string.Join(" ", DefaultArguments));
         WriteToLog("Process id: " + _chromeProcess.Id);
         WriteToLog("Process exit time: " + _chromeProcess.ExitTime.ToString("yyyy-MM-ddTHH:mm:ss.fff"));
         var exception =
             ExceptionHelpers.GetInnerException(Marshal.GetExceptionForHR(_chromeProcess.ExitCode));
         WriteToLog("Exception: " + exception);
         throw new ChromeException("Chrome exited unexpectedly, " + exception);
     }
     catch (Exception exception)
     {
         _chromeEventException = exception;
         if (_chromeProcess != null)
         {
             _chromeProcess.Exited -= _chromeProcess_Exited;
         }
         _chromeWaitEvent.Set();
     }
 }
Example #2
0
        /// <summary>
        ///     Opens the <paramref name="inputFile" /> and returns it as an <see cref="WordInterop.Document" /> object
        /// </summary>
        /// <param name="inputFile">The file to open</param>
        /// <param name="repairMode">When true the <paramref name="inputFile" /> is opened in repair mode</param>
        /// <returns></returns>
        private WordInterop.Document OpenDocument(string inputFile, bool repairMode)
        {
            Logger.WriteToLog($"Opening document '{inputFile}'{(repairMode ? " with repair mode" : string.Empty)}");

            try
            {
                WordInterop.Document document;

                var extension = Path.GetExtension(inputFile);

                if (extension != null && extension.ToUpperInvariant() == ".TXT")
                {
                    document = _word.Documents.OpenNoRepairDialog(inputFile, false, true, false, "dummy password",
                                                                  Format: WordInterop.WdOpenFormat.wdOpenFormatUnicodeText,
                                                                  OpenAndRepair: repairMode,
                                                                  NoEncodingDialog: true);
                }
                else
                {
                    document = _word.Documents.OpenNoRepairDialog(inputFile, false, true, false, "dummy password",
                                                                  OpenAndRepair: repairMode,
                                                                  NoEncodingDialog: true);
                }

                // This will lock or unlock all form fields in a Word document so that auto fill
                // and date/time field do or don't get updated automatic when converting
                if (document.Fields.Count > 0)
                {
                    Logger.WriteToLog("Locking all form fields against modifications");
                    foreach (WordInterop.Field field in document.Fields)
                    {
                        field.Locked = true;
                    }
                }

                Logger.WriteToLog("Document opened");
                return(document);
            }
            catch (Exception exception)
            {
                Logger.WriteToLog(
                    $"ERROR: Failed to open document, exception: '{ExceptionHelpers.GetInnerException(exception)}'");

                if (repairMode)
                {
                    throw new OCFileIsCorrupt("The file '" + Path.GetFileName(inputFile) +
                                              "' seems to be corrupt, error: " +
                                              ExceptionHelpers.GetInnerException(exception));
                }

                return(OpenDocument(inputFile, true));
            }
        }
Example #3
0
 /// <summary>
 /// Converts the <paramref name="inputFile"/> to PDF and saves it as the <paramref name="outputFile"/>
 /// </summary>
 /// <param name="inputFile">The Microsoft Office file</param>
 /// <param name="outputFile">The output file with full path</param>
 /// <returns>Returns true when the conversion is succesfull, false is retournerd when an exception occurred.
 /// The exception can be retrieved with the <see cref="GetErrorMessage"/> method</returns>
 public bool ConvertFromCom(string inputFile, string outputFile)
 {
     try
     {
         _errorMessage = string.Empty;
         Convert(inputFile, outputFile);
         return(true);
     }
     catch (Exception exception)
     {
         _errorMessage = ExceptionHelpers.GetInnerException(exception);
         return(false);
     }
 }
Example #4
0
        /// <summary>
        /// Opens the <paramref name="inputFile"/> and returns it as an <see cref="WordInterop.Document"/> object
        /// </summary>
        /// <param name="word">The <see cref="WordInterop.Application"/></param>
        /// <param name="inputFile">The file to open</param>
        /// <param name="repairMode">When true the <paramref name="inputFile"/> is opened in repair mode</param>
        /// <returns></returns>
        private static WordInterop.Document Open(WordInterop._Application word,
                                                 string inputFile,
                                                 bool repairMode)
        {
            try
            {
                WordInterop.Document document;

                var extension = Path.GetExtension(inputFile);

                if (extension != null && extension.ToUpperInvariant() == ".TXT")
                {
                    document = word.Documents.OpenNoRepairDialog(inputFile, false, true, false, "dummypassword",
                                                                 Format: WordInterop.WdOpenFormat.wdOpenFormatUnicodeText,
                                                                 OpenAndRepair: repairMode,
                                                                 NoEncodingDialog: true);
                }
                else
                {
                    document = word.Documents.OpenNoRepairDialog(inputFile, false, true, false, "dummypassword",
                                                                 OpenAndRepair: repairMode,
                                                                 NoEncodingDialog: true);
                }

                // This will lock or unlock all form fields in a Word document so that auto fill
                // and date/time field do or don't get updated automaticly when converting
                if (document.Fields.Count > 0)
                {
                    foreach (WordInterop.Field field in document.Fields)
                    {
                        field.Locked = true;
                    }
                }

                return(document);
            }
            catch (Exception exception)
            {
                if (repairMode)
                {
                    throw new OCFileIsCorrupt("The file '" + Path.GetFileName(inputFile) +
                                              "' seems to be corrupt, error: " +
                                              ExceptionHelpers.GetInnerException(exception));
                }

                return(Open(word, inputFile, true));
            }
        }
Example #5
0
        /// <summary>
        /// This method will delete the automatic created Resiliency key. Word uses this registry key
        /// to make entries to corrupted documents. If there are to many entries under this key Word will
        /// get slower and slower to start. To prevent this we just delete this key when it exists
        /// </summary>
        private static void DeleteAutoRecoveryFiles()
        {
            try
            {
                // HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\Word\Resiliency\DocumentRecovery
                var version = string.Empty;

                switch (VersionNumber)
                {
                // Word 2003
                case 11:
                    version = "11.0";
                    break;

                // Word 2017
                case 12:
                    version = "12.0";
                    break;

                // Word 2010
                case 14:
                    version = "14.0";
                    break;

                // Word 2013
                case 15:
                    version = "15.0";
                    break;

                // Word 2016
                case 16:
                    version = "16.0";
                    break;
                }

                var key = @"Software\Microsoft\Office\" + version + @"\Word\Resiliency";

                if (Registry.CurrentUser.OpenSubKey(key, false) != null)
                {
                    Registry.CurrentUser.DeleteSubKeyTree(key);
                }
            }
            catch (Exception exception)
            {
                EventLog.WriteEntry("OfficeConverter", ExceptionHelpers.GetInnerException(exception), EventLogEntryType.Error);
            }
        }
Example #6
0
        /// <summary>
        ///     Opens the <paramref name="inputFile" /> and returns it as an <see cref="PowerPointInterop.Presentation" /> object
        /// </summary>
        /// <param name="inputFile">The file to open</param>
        /// <param name="repairMode">When true the <paramref name="inputFile" /> is opened in repair mode</param>
        /// <returns></returns>
        /// <exception cref="OCFileIsCorrupt">
        ///     Raised when the <paramref name="inputFile" /> is corrupt and can't be opened in
        ///     repair mode
        /// </exception>
        private PowerPointInterop.Presentation OpenPresentation(string inputFile, bool repairMode)
        {
            try
            {
                return(_powerPoint.Presentations.Open(inputFile, MsoTriState.msoTrue, MsoTriState.msoTrue,
                                                      MsoTriState.msoFalse));
            }
            catch (Exception exception)
            {
                if (repairMode)
                {
                    throw new OCFileIsCorrupt("The file '" + Path.GetFileName(inputFile) +
                                              "' seems to be corrupt, error: " +
                                              ExceptionHelpers.GetInnerException(exception));
                }

                return(OpenPresentation(inputFile, true));
            }
        }
Example #7
0
        /// <summary>
        ///     This method reads the <paramref name="inputFile" /> and when the file is supported it will do the following: <br />
        ///     - Extract the HTML, RTF (will be converted to html) or TEXT body (in these order) <br />
        ///     - Puts a header (with the sender, to, cc, etc... (depends on the message type) on top of the body so it looks
        ///     like if the object is printed from Outlook <br />
        ///     - Reads all the attachents <br />
        ///     And in the end writes everything to the given <paramref name="outputFolder" />
        /// </summary>
        /// <param name="inputFile">The vcf file</param>
        /// <param name="outputFolder">The folder where to save the extracted vcf file</param>
        /// <param name="hyperlinks">When true hyperlinks are clickable, otherwhise they are written as plain text</param>
        /// <param name="culture"></param>
        public string[] ExtractToFolderFromCom(string inputFile,
                                               string outputFolder,
                                               bool hyperlinks = false,
                                               string culture  = "")
        {
            try
            {
                if (!string.IsNullOrEmpty(culture))
                {
                    SetCulture(culture);
                }

                return(ExtractToFolder(inputFile, outputFolder));
            }
            catch (Exception exception)
            {
                _errorMessage = ExceptionHelpers.GetInnerException(exception);
                return(new string[0]);
            }
        }
Example #8
0
        /// <summary>
        /// If you want to run this code on a server then the following folders must exist, if they don't
        /// then you can't use Excel to convert files to PDF
        /// </summary>
        /// <exception cref="OCConfiguration">Raised when the needed directory could not be created</exception>
        private static void CheckIfSystemProfileDesktopDirectoryExists()
        {
            return;

            if (Environment.Is64BitOperatingSystem)
            {
                var x64DesktopPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows),
                                                  @"SysWOW64\config\systemprofile\desktop");

                if (!Directory.Exists(x64DesktopPath))
                {
                    try
                    {
                        Directory.CreateDirectory(x64DesktopPath);
                    }
                    catch (Exception exception)
                    {
                        throw new OCConfiguration("Can't create folder '" + x64DesktopPath +
                                                  "' Excel needs this folder to work on a server, error: " +
                                                  ExceptionHelpers.GetInnerException(exception));
                    }
                }
            }

            var x86DesktopPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows),
                                              @"System32\config\systemprofile\desktop");

            if (!Directory.Exists(x86DesktopPath))
            {
                try
                {
                    Directory.CreateDirectory(x86DesktopPath);
                }
                catch (Exception exception)
                {
                    throw new OCConfiguration("Can't create folder '" + x86DesktopPath +
                                              "' Excel needs this folder to work on a server, error: " +
                                              ExceptionHelpers.GetInnerException(exception));
                }
            }
        }
Example #9
0
        /// <summary>
        ///     This method will delete the automatic created Resiliency key. PowerPoint uses this registry key
        ///     to make entries to corrupted presentations. If there are to many entries under this key PowerPoint will
        ///     get slower and slower to start. To prevent this we just delete this key when it exists
        /// </summary>
        private void DeleteResiliencyKeys()
        {
            Logger.WriteToLog("Deleting PowerPoint resiliency keys from the registry");

            try
            {
                // HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\PowerPoint\Resiliency\DocumentRecovery
                var key = $@"Software\Microsoft\Office\{_versionNumber}.0\PowerPoint\Resiliency";

                if (Registry.CurrentUser.OpenSubKey(key, false) != null)
                {
                    Registry.CurrentUser.DeleteSubKeyTree(key);
                    Logger.WriteToLog("Resiliency keys deleted");
                }
                else
                {
                    Logger.WriteToLog("There are no keys to delete");
                }
            }
            catch (Exception exception)
            {
                Logger.WriteToLog($"Failed to delete resiliency keys, error: {ExceptionHelpers.GetInnerException(exception)}");
            }
        }
Example #10
0
        /// <summary>
        /// Extract the given <paramref name="inputFile"/> to the given <paramref name="outputFolder"/>
        /// </summary>
        /// <param name="inputFile">The input file</param>
        /// <param name="outputFolder">The folder where to save the extracted web archive</param>
        /// <param name="options"><see cref="ExtractorOptions"/></param>
        /// <param name="logStream">When set then logging is written to this stream</param>
        /// <returns></returns>
        /// <exception cref="WAEInvalidFile">Raised when a required resource is not found in the web archive</exception>
        /// <exception cref="WAEResourceMissing">Raised when a required resource is not found in the web archive</exception>
        /// <exception cref="FileNotFoundException">Raised when the <paramref name="inputFile"/> is not found</exception>
        /// <exception cref="DirectoryNotFoundException">Raised when the <paramref name="outputFolder"/> does not exist</exception>
        public string Extract(string inputFile, string outputFolder, ExtractorOptions options = ExtractorOptions.None, Stream logStream = null)
        {
            if (logStream != null)
            {
                Logger.LogStream = logStream;
            }

            try
            {
                if (!Directory.Exists(outputFolder))
                {
                    throw new DirectoryNotFoundException($"The output folder '{outputFolder}' does not exist");
                }

                var reader = new PList.BinaryPlistReader();

                IDictionary archive;

                try
                {
                    archive = reader.ReadObject(inputFile);
                }
                catch (Exception exception)
                {
                    throw new WAEInvalidFile($"The file '{inputFile}' is not a valid Safari web archive", exception);
                }

                if (!archive.Contains(WebMainResource))
                {
                    var message = $"Can't find the resource '{WebMainResource}' in the webarchive";
                    Logger.WriteToLog(message);
                    throw new WAEResourceMissing(message);
                }

                var mainResource    = (IDictionary)archive[WebMainResource];
                var webPageFileName = Path.Combine(outputFolder, "webpage.html");

                Logger.WriteToLog($"Getting main web page from '{WebMainResource}'");
                var webPage = ProcessMainResource(mainResource, out var mainUri);

#if (DEBUG)
                File.WriteAllText(webPageFileName, webPage);
#endif

                if (!archive.Contains(WebSubresources))
                {
                    Logger.WriteToLog("Web archive does not contain any sub resources");
                }
                else
                {
                    var subResources = (object[])archive[WebSubresources];
                    var count        = subResources.Length;
                    Logger.WriteToLog($"Web archive has {count} sub resource{(count > 1 ? "s" : string.Empty)}");

                    foreach (IDictionary subResource in subResources)
                    {
                        ProcessSubResources(subResource, outputFolder, mainUri, options, ref webPage);
                    }
                }

                if (!archive.Contains(WebSubframeArchives))
                {
                    Logger.WriteToLog("Web archive does not contain any sub frame archives");
                }
                else
                {
                    var subFrameResources      = (object[])archive[WebSubframeArchives];
                    var subFrameResourcesCount = subFrameResources.Length;

                    Logger.WriteToLog($"Web archive has {subFrameResourcesCount} sub frame resource{(subFrameResourcesCount > 1 ? "s" : string.Empty)}");

                    var i = 1;

                    foreach (IDictionary subFrameResource in subFrameResources)
                    {
                        var subFrameMainResource = (IDictionary)subFrameResource[WebMainResource];

                        Logger.WriteToLog($"Getting web page from sub frame resource '{WebMainResource}'");
                        var subFrameResourceWebPage = ProcessSubFrameMainResource(subFrameMainResource, out var frameName, out var subFrameMainUri);
                        var subFrameOutputFolder    = Path.Combine(outputFolder, $"subframe_{i}");

                        Logger.WriteToLog($"Creating folder '{subFrameOutputFolder}' for iframe '{frameName}' content");
                        Directory.CreateDirectory(subFrameOutputFolder);
                        i += 1;

                        var subFrameSubResources = (object[])subFrameResource[WebSubresources];

                        if (subFrameSubResources == null)
                        {
                            Logger.WriteToLog("Web archive sub frame does not contain any sub resources");
                        }
                        else
                        {
                            var subFrameSubResourcesCount = subFrameSubResources.Length;
                            Logger.WriteToLog($"Web archive sub frame has {subFrameSubResourcesCount} sub resource{(subFrameSubResourcesCount > 1 ? "s" : string.Empty)}");

                            foreach (IDictionary subFrameSubResource in subFrameSubResources)
                            {
                                ProcessSubResources(subFrameSubResource, subFrameOutputFolder, subFrameMainUri, options,
                                                    ref subFrameResourceWebPage);
                            }
                        }

                        var subFrameWebPageFileName    = Path.Combine(subFrameOutputFolder, "webpage.html");
                        var subFrameWebPageRelativeUri = $"subframe_{i}/webpage.html";
                        var subFrameUri = subFrameMainUri.ToString();
                        var subFrameUriWithoutScheme  = subFrameUri.Replace($"{subFrameMainUri.Scheme}:", string.Empty);
                        var subFrameUriWithoutMainUri = subFrameUri.Replace($"{mainUri.Scheme}://{mainUri.Host}{mainUri.AbsolutePath}", string.Empty);

                        if (webPage.Contains(subFrameUri))
                        {
                            Logger.WriteToLog($"Replacing '{subFrameUri}' with '{subFrameWebPageRelativeUri}'");
                            webPage = webPage.Replace(subFrameUri, subFrameWebPageRelativeUri);
                        }
                        else if (webPage.Contains(subFrameUriWithoutScheme))
                        {
                            Logger.WriteToLog($"Replacing '{subFrameUriWithoutScheme}' with '{subFrameWebPageRelativeUri}'");
                            webPage = webPage.Replace(subFrameUriWithoutScheme, $"{subFrameWebPageRelativeUri}");
                        }
                        else if (webPage.Contains(subFrameUriWithoutMainUri))
                        {
                            Logger.WriteToLog($"Replacing '{subFrameUriWithoutMainUri}' with '{subFrameWebPageRelativeUri}'");
                            webPage = webPage.Replace(subFrameUriWithoutMainUri, $"{subFrameWebPageRelativeUri}");
                        }
                        else
                        {
                            Logger.WriteToLog($"Could not find any resources with url '{subFrameUri}' in the web page");
                        }

                        File.WriteAllText(subFrameWebPageFileName, subFrameResourceWebPage);
                    }
                }

                File.WriteAllText(webPageFileName, webPage);
                return(webPageFileName);
            }
            catch (Exception exception)
            {
                Logger.WriteToLog(ExceptionHelpers.GetInnerException(exception));
                throw;
            }
        }
Example #11
0
        /// <summary>
        /// Opens the <paramref name="inputFile"/> and returns it as an <see cref="ExcelInterop.Workbook"/> object
        /// </summary>
        /// <param name="excel">The <see cref="ExcelInterop.Application"/></param>
        /// <param name="inputFile">The file to open</param>
        /// <param name="extension">The file extension</param>
        /// <param name="repairMode">When true the <paramref name="inputFile"/> is opened in repair mode</param>
        /// <returns></returns>
        /// <exception cref="OCCsvFileLimitExceeded">Raised when a CSV <paramref name="inputFile"/> has to many rows</exception>
        private static ExcelInterop.Workbook Open(ExcelInterop._Application excel,
                                                  string inputFile,
                                                  string extension,
                                                  bool repairMode)
        {
            try
            {
                switch (extension.ToUpperInvariant())
                {
                case ".CSV":

                    var count        = File.ReadLines(inputFile).Count();
                    var excelMaxRows = MaxRows;
                    if (count > excelMaxRows)
                    {
                        throw new OCCsvFileLimitExceeded("The input CSV file has more then " + excelMaxRows +
                                                         " rows, the installed Excel version supports only " +
                                                         excelMaxRows + " rows");
                    }

                    string separator;
                    ExcelInterop.XlTextQualifier textQualifier;

                    GetCsvSeperator(inputFile, out separator, out textQualifier);

                    switch (separator)
                    {
                    case ";":
                        excel.Workbooks.OpenText(inputFile, Type.Missing, Type.Missing,
                                                 ExcelInterop.XlTextParsingType.xlDelimited,
                                                 textQualifier, true, false, true);
                        return(excel.ActiveWorkbook);

                    case ",":
                        excel.Workbooks.OpenText(inputFile, Type.Missing, Type.Missing,
                                                 ExcelInterop.XlTextParsingType.xlDelimited, textQualifier,
                                                 Type.Missing, false, false, true);
                        return(excel.ActiveWorkbook);

                    case "\t":
                        excel.Workbooks.OpenText(inputFile, Type.Missing, Type.Missing,
                                                 ExcelInterop.XlTextParsingType.xlDelimited, textQualifier,
                                                 Type.Missing, true);
                        return(excel.ActiveWorkbook);

                    case " ":
                        excel.Workbooks.OpenText(inputFile, Type.Missing, Type.Missing,
                                                 ExcelInterop.XlTextParsingType.xlDelimited, textQualifier,
                                                 Type.Missing, false, false, false, true);
                        return(excel.ActiveWorkbook);

                    default:
                        excel.Workbooks.OpenText(inputFile, Type.Missing, Type.Missing,
                                                 ExcelInterop.XlTextParsingType.xlDelimited, textQualifier,
                                                 Type.Missing, false, true);
                        return(excel.ActiveWorkbook);
                    }

                default:

                    if (repairMode)
                    {
                        return(excel.Workbooks.Open(inputFile, false, true,
                                                    Password: "******",
                                                    IgnoreReadOnlyRecommended: true,
                                                    AddToMru: false,
                                                    CorruptLoad: ExcelInterop.XlCorruptLoad.xlRepairFile));
                    }

                    return(excel.Workbooks.Open(inputFile, false, true,
                                                Password: "******",
                                                IgnoreReadOnlyRecommended: true,
                                                AddToMru: false));
                }
            }
            catch (COMException comException)
            {
                if (comException.ErrorCode == -2146827284)
                {
                    throw new OCFileIsPasswordProtected("The file '" + Path.GetFileName(inputFile) +
                                                        "' is password protected");
                }

                throw new OCFileIsCorrupt("The file '" + Path.GetFileName(inputFile) +
                                          "' could not be opened, error: " + ExceptionHelpers.GetInnerException(comException));
            }
            catch (Exception exception)
            {
                if (repairMode)
                {
                    throw new OCFileIsCorrupt("The file '" + Path.GetFileName(inputFile) +
                                              "' could not be opened, error: " +
                                              ExceptionHelpers.GetInnerException(exception));
                }

                return(Open(excel, inputFile, extension, true));
            }
        }
Example #12
0
            /// <summary>
            /// Returns a dictionary with all the property mappings
            /// </summary>
            /// <param name="propertyIdents">List with all the named property idents, e.g 8005, 8006, 801C, etc...</param>
            /// <returns></returns>
            internal List <MapiTagMapping> GetMapping(IEnumerable <string> propertyIdents)
            {
                var result            = new List <MapiTagMapping>();
                var entryStreamBytes  = GetStreamBytes(MapiTags.EntryStream);
                var stringStreamBytes = GetStreamBytes(MapiTags.StringStream);

                if (entryStreamBytes.Length == 0)
                {
                    return(result);
                }

                foreach (var propertyIdent in propertyIdents)
                {
                    try
                    {
                        // To read the correct mapped property we need to calculate the offset in the entry stream
                        // The offset is calculated bij subtracting 32768 (8000 hex) from the named property and
                        // multiply the outcome with 8
                        var identValue  = ushort.Parse(propertyIdent, NumberStyles.HexNumber);
                        var entryOffset = (identValue - 32768) * 8;
                        if (entryOffset > entryStreamBytes.Length)
                        {
                            continue;
                        }

                        string entryIdentString;

                        // We need the first 2 bytes for the mapping, but because the nameStreamBytes is in little
                        // endian we need to swap the first 2 bytes

                        if (entryStreamBytes[entryOffset + 1] == 0)
                        {
                            var entryIdent = new[] { entryStreamBytes[entryOffset] };
                            entryIdentString = BitConverter.ToString(entryIdent).Replace("-", string.Empty);
                        }
                        else
                        {
                            var entryIdent = new[] { entryStreamBytes[entryOffset + 1], entryStreamBytes[entryOffset] };
                            entryIdentString = BitConverter.ToString(entryIdent).Replace("-", string.Empty);
                        }

                        var stringOffset = ushort.Parse(entryIdentString, NumberStyles.HexNumber);

                        if (stringOffset >= stringStreamBytes.Length)
                        {
                            //Debug.Print($"{propertyIdent} - {entryIdentString}");
                            result.Add(new MapiTagMapping(propertyIdent, entryIdentString));
                            continue;
                        }

                        // Read the first 4 bytes to determine the length of the string to read
                        var stringLength = 0;

                        var len = stringStreamBytes.Length - stringOffset;

                        if (len == 1)
                        {
                            var bytes = new byte[1];
                            Buffer.BlockCopy(stringStreamBytes, stringOffset, bytes, 0, len);
                            stringLength = bytes[0];
                        }

                        if (len == 2)
                        {
                            stringLength = BitConverter.ToInt16(stringStreamBytes, stringOffset);
                        }

                        if (len == 3)
                        {
                            var bytes = new byte[3];
                            Buffer.BlockCopy(stringStreamBytes, stringOffset, bytes, 0, len);
                            stringLength = Bytes2Int(bytes[2], bytes[1], bytes[0]);
                        }
                        else if (len >= 4)
                        {
                            stringLength = BitConverter.ToInt32(stringStreamBytes, stringOffset);
                        }

                        if (stringOffset + stringLength >= stringStreamBytes.Length)
                        {
                            result.Add(new MapiTagMapping(propertyIdent, entryIdentString));
                            continue;
                        }

                        var str = string.Empty;

                        // Skip 4 bytes and start reading the string
                        stringOffset += 4;
                        for (var i = stringOffset; i < stringOffset + stringLength; i += 2)
                        {
                            var chr = BitConverter.ToChar(stringStreamBytes, i);
                            str += chr;
                        }

                        // Remove any null character
                        str = str.Replace("\0", string.Empty);
                        result.Add(new MapiTagMapping(str, propertyIdent, true));
                    }
                    catch (Exception exception)
                    {
                        Logger.WriteToLog(ExceptionHelpers.GetInnerException(exception));
                        throw;
                    }
                }

                return(result);
            }
Example #13
0
        /// <summary>
        ///     Start Chrome headless with the debugger set to the given port
        /// </summary>
        /// <remarks>
        ///     If Chrome is already running then this step is skipped
        /// </remarks>
        /// <exception cref="ChromeException"></exception>
        private void StartChromeHeadless()
        {
            if (IsChromeRunning)
            {
                return;
            }

            var starting = true;

            var userName = string.Empty;

            if (_userName.Contains("\\"))
            {
                userName = _userName.Split('\\')[1];
            }

            var domain = _userName.Split('\\')[0];

            WriteToLog($"Starting Chrome from location {_chromeExeFileName}");
            WriteToLog($"{_chromeExeFileName} {string.Join(" ", DefaultArguments)}");
            _chromeProcess = new Process();
            var processStartInfo = new ProcessStartInfo
            {
                FileName        = _chromeExeFileName,
                Arguments       = string.Join(" ", DefaultArguments),
                UseShellExecute = false,
                CreateNoWindow  = true,
                ErrorDialog     = false,
                WindowStyle     = ProcessWindowStyle.Hidden,
                // ReSharper disable once AssignNullToNotNullAttribute
                WorkingDirectory       = Path.GetDirectoryName(_chromeExeFileName),
                RedirectStandardOutput = true,
                RedirectStandardError  = true
            };

            if (!string.IsNullOrWhiteSpace(_userName))
            {
                WriteToLog($"Starting Chrome with user '{userName}' on domain '{domain}'");

                processStartInfo.Domain   = domain;
                processStartInfo.UserName = userName;

                var secureString = new SecureString();
                foreach (var t in _password)
                {
                    secureString.AppendChar(t);
                }

                processStartInfo.Password = secureString;
            }

            _chromeProcess.StartInfo = processStartInfo;

            var waitEvent = new ManualResetEvent(false);

            _chromeProcess.OutputDataReceived += (sender, args) =>
            {
                if (!string.IsNullOrWhiteSpace(args.Data))
                {
                    WriteToLog($"Error: {args.Data}");
                }
            };

            _chromeProcess.ErrorDataReceived += (sender, args) =>
            {
                if (args.Data == null)
                {
                    return;
                }

                if (args.Data.StartsWith("DevTools listening on"))
                {
                    // DevTools listening on ws://127.0.0.1:50160/devtools/browser/53add595-f351-4622-ab0a-5a4a100b3eae
                    _browser = new Browser(new Uri(args.Data.Replace("DevTools listening on ", string.Empty)));
                    WriteToLog("Connected to dev protocol");
                    waitEvent.Set();
                }
                else if (!string.IsNullOrWhiteSpace(args.Data))
                {
                    WriteToLog($"Error: {args.Data}");
                }
            };

            _chromeProcess.Exited += (sender, args) =>
            {
                // ReSharper disable once AccessToModifiedClosure
                if (!starting)
                {
                    return;
                }
                WriteToLog("Chrome exited unexpectedly, arguments used: " + string.Join(" ", DefaultArguments));
                WriteToLog("Process id: " + _chromeProcess.Id);
                WriteToLog("Process exit time: " + _chromeProcess.ExitTime.ToString("yyyy-MM-ddTHH:mm:ss.fff"));
                var exception =
                    ExceptionHelpers.GetInnerException(Marshal.GetExceptionForHR(_chromeProcess.ExitCode));
                WriteToLog("Exception: " + exception);
                throw new ChromeException("Chrome exited unexpectedly, " + exception);
            };

            _chromeProcess.EnableRaisingEvents = true;
            _chromeProcess.Start();
            WriteToLog("Chrome process started");

            _chromeProcess.BeginErrorReadLine();
            _chromeProcess.BeginOutputReadLine();

            if (_conversionTimeout.HasValue)
            {
                waitEvent.WaitOne(_conversionTimeout.Value);
            }
            else
            {
                waitEvent.WaitOne();
            }

            starting = false;

            WriteToLog("Chrome started");
        }
Example #14
0
        /// <summary>
        ///     Start Chrome headless with the debugger set to the given port
        /// </summary>
        /// <remarks>
        ///     If Chrome is already running then this step is skipped
        /// </remarks>
        /// <exception cref="ChromeException"></exception>
        private void StartChromeHeadless()
        {
            if (IsChromeRunning())
            {
                return;
            }

            WriteToLog($"Starting Chrome from location {_chromeExeFileName}");

            _chromeProcess = new Process();
            var processStartInfo = new ProcessStartInfo
            {
                FileName               = _chromeExeFileName,
                Arguments              = string.Join(" ", _defaultArguments),
                UseShellExecute        = false,
                RedirectStandardOutput = true,
                RedirectStandardError  = true,
            };

            if (!string.IsNullOrWhiteSpace(_userName))
            {
                var userName = string.Empty;

                if (_userName.Contains("\\"))
                {
                    userName = _userName.Split('\\')[1];
                }

                var domain = _userName.Split('\\')[0];

                WriteToLog($"Starting Chrome with user '{userName}' on domain '{domain}'");

                processStartInfo.Domain   = domain;
                processStartInfo.UserName = userName;

                var secureString = new SecureString();
                foreach (var t in _password)
                {
                    secureString.AppendChar(t);
                }

                processStartInfo.Password = secureString;
            }

            _chromeProcess.StartInfo = processStartInfo;

            var waitEvent = new ManualResetEvent(false);

            _chromeProcess.ErrorDataReceived += (sender, args) =>
            {
                if (args.Data == null)
                {
                    return;
                }

                if (args.Data.StartsWith("DevTools listening on"))
                {
                    // DevTools listening on ws://127.0.0.1:50160/devtools/browser/53add595-f351-4622-ab0a-5a4a100b3eae
                    _communicator = new Browser(new Uri(args.Data.Replace("DevTools listening on ", string.Empty)));
                    WriteToLog("Connected to dev protocol");
                    waitEvent.Set();
                }
                else if (!string.IsNullOrWhiteSpace(args.Data))
                {
                    WriteToLog($"Error: {args.Data}");
                }
            };

            _chromeProcess.Exited += (sender, args) =>
            {
                WriteToLog("Chrome process: " + _chromeExeFileName);
                WriteToLog("Arguments used: " + string.Join(" ", _defaultArguments));
                var exception = ExceptionHelpers.GetInnerException(Marshal.GetExceptionForHR(_chromeProcess.ExitCode));
                WriteToLog("Exception: " + exception);
                throw new ChromeException("Could not start Chrome, " + exception);
            };

            _chromeProcess.Start();
            _chromeProcess.BeginErrorReadLine();
            waitEvent.WaitOne();

            WriteToLog("Chrome started");
        }
Example #15
0
        /// <summary>
        ///     Start Chrome headless
        /// </summary>
        /// <remarks>
        ///     If Chrome is already running then this step is skipped
        /// </remarks>
        /// <exception cref="ChromeException"></exception>
        public void EnsureRunning()
        {
            lock (mutex)
            {
                if (IsChromeRunning)
                {
                    WriteToLog($"Chrome is already running on PID {_chromeProcess.Id}... skipped");
                    return;
                }

                _chromeEventException = null;
                var workingDirectory = Path.GetDirectoryName(_chromeExeFileName);

                WriteToLog(
                    $"Starting Chrome from location '{_chromeExeFileName}' with working directory '{workingDirectory}'");
                WriteToLog($"\"{_chromeExeFileName}\" {string.Join(" ", DefaultArguments)}");

                _chromeProcess = new Process();
                var processStartInfo = new ProcessStartInfo
                {
                    FileName        = _chromeExeFileName,
                    Arguments       = string.Join(" ", DefaultArguments),
                    UseShellExecute = false,
                    CreateNoWindow  = true,
                    ErrorDialog     = false,
                    WindowStyle     = ProcessWindowStyle.Hidden,
                    // ReSharper disable once AssignNullToNotNullAttribute
                    WorkingDirectory       = workingDirectory,
                    RedirectStandardOutput = true,
                    RedirectStandardError  = true
                };

                try
                {
                    processStartInfo.LoadUserProfile = false;

                    if (!string.IsNullOrWhiteSpace(_userName))
                    {
                        var userName = string.Empty;
                        var domain   = string.Empty;

                        if (_userName.Contains("\\"))
                        {
                            userName = _userName.Split('\\')[1];
                            domain   = _userName.Split('\\')[0];
                        }

                        WriteToLog($"Starting Chrome with username '{userName}' on domain '{domain}'");

                        processStartInfo.Domain   = domain;
                        processStartInfo.UserName = userName;

                        var secureString = new SecureString();
                        foreach (var t in _password)
                        {
                            secureString.AppendChar(t);
                        }

                        processStartInfo.Password        = secureString;
                        processStartInfo.LoadUserProfile = true;
                    }
                }
                catch (Exception ex)
                {
                    _logger?.LogWarning($"Failed to set user info {ex.Message}");
                }

                processStartInfo.Environment[UniqueEnviromentKey] = UniqueEnviromentKey;

                _chromeProcess.StartInfo = processStartInfo;

                _chromeWaitEvent = new ManualResetEvent(false);

                _chromeProcess.OutputDataReceived += _chromeProcess_OutputDataReceived;
                _chromeProcess.ErrorDataReceived  += _chromeProcess_ErrorDataReceived;
                _chromeProcess.Exited             += _chromeProcess_Exited;

                _chromeProcess.EnableRaisingEvents = true;

                try
                {
                    _chromeProcess.Start();
                }
                catch (Exception exception)
                {
                    WriteToLog("Could not start the Chrome process due to the following reason: " +
                               ExceptionHelpers.GetInnerException(exception));
                    throw;
                }

                WriteToLog("Chrome process started");

                _chromeProcess.BeginErrorReadLine();
                _chromeProcess.BeginOutputReadLine();


                if (_conversionTimeout.HasValue)
                {
                    _chromeWaitEvent.WaitOne(_conversionTimeout.Value);
                }
                else
                {
                    _chromeWaitEvent.WaitOne();
                }

                if (_chromeEventException != null)
                {
                    WriteToLog("Exception: " + ExceptionHelpers.GetInnerException(_chromeEventException));
                    throw _chromeEventException;
                }

                WriteToLog("Chrome started");
            }
        }
Example #16
0
        /// <summary>
        ///     Stops Word
        /// </summary>
        private void StopWord()
        {
            if (IsWordRunning)
            {
                Logger.WriteToLog("Stopping Word");

                try
                {
                    _word.Quit(false);
                }
                catch (Exception exception)
                {
                    Logger.WriteToLog($"Word did not shutdown gracefully, exception: {ExceptionHelpers.GetInnerException(exception)}");
                }

                var counter = 0;

                // Give Word 2 seconds to close
                while (counter < 200)
                {
                    if (!IsWordRunning)
                    {
                        break;
                    }
                    counter++;
                    Thread.Sleep(10);
                }

                if (IsWordRunning)
                {
                    Logger.WriteToLog($"Word did not shutdown gracefully in 2 seconds ... killing it on process id {_wordProcess.Id}");
                    _wordProcess.Kill();
                    Logger.WriteToLog("Word process killed");
                }
                else
                {
                    Logger.WriteToLog("Word stopped");
                }
            }

            if (_word != null)
            {
                Marshal.ReleaseComObject(_word);
                _word = null;
            }

            _wordProcess = null;

            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
Example #17
0
        /// <summary>
        ///     Stops PowerPoint
        /// </summary>
        private void StopPowerPoint()
        {
            if (IsPowerPointRunning)
            {
                Logger.WriteToLog("Stopping PowerPoint");

                try
                {
                    _powerPoint.Quit();
                }
                catch (Exception exception)
                {
                    Logger.WriteToLog($"PowerPoint did not shutdown gracefully, exception: {ExceptionHelpers.GetInnerException(exception)}");
                }

                var counter = 0;

                // Give PowerPoint 2 seconds to close
                while (counter < 200)
                {
                    if (!IsPowerPointRunning)
                    {
                        break;
                    }
                    counter++;
                    Thread.Sleep(10);
                }

                if (IsPowerPointRunning)
                {
                    Logger.WriteToLog(
                        $"PowerPoint did not shutdown gracefully in 2 seconds ... killing it on process id {_powerPointProcess.Id}");
                    _powerPointProcess.Kill();
                    Logger.WriteToLog("PowerPoint process killed");
                }
                else
                {
                    Logger.WriteToLog("PowerPoint stopped");
                }
            }

            if (_powerPoint != null)
            {
                Marshal.ReleaseComObject(_powerPoint);
                _powerPoint = null;
            }

            _powerPointProcess = null;

            GC.Collect();
            GC.WaitForPendingFinalizers();
        }