/// <summary>
        /// Note that WriteOnce.Writer is not used for AnalyzeCommand which has specific Writer classes for formattig to html, json, text unlike
        /// other command classes to writting to a file here is handled by the AnalyzeCommand FlushAll() method
        /// </summary>
        void ConfigFileOutput()
        {
            WriteOnce.SafeLog("AnalyzeCommand::ConfigOutput", LogLevel.Trace);

            WriteOnce.FlushAll();//in case called more than once

            //error check for no output
            if (string.IsNullOrEmpty(_arg_outputFile) && _arg_consoleVerbosityLevel.ToLower() == "none")
            {
                throw new Exception(ErrMsg.GetString(ErrMsg.ID.CMD_NO_OUTPUT));
            }

            if (_arg_fileFormat == "html")
            {
                if (!string.IsNullOrEmpty(_arg_outputFile)) //dependent local files won't be there; TODO look into dir copy to target!
                {
                    _arg_outputFile = String.Empty;
                    WriteOnce.Info("output file argument ignored for html format");
                }

                if (!_arg_outputUniqueTagsOnly) //fix #183
                {
                    throw new Exception(ErrMsg.GetString(ErrMsg.ID.ANALYZE_NODUPLICATES_HTML_FORMAT));
                }

                if (_arg_simpleTagsOnly) //won't work for html that expects full data
                {
                    throw new Exception(ErrMsg.GetString(ErrMsg.ID.ANALYZE_SIMPLETAGS_HTML_FORMAT));
                }
            }

            //Set outstream
            _outputWriter = WriterFactory.GetWriter(_arg_fileFormat ?? "text", (string.IsNullOrEmpty(_arg_outputFile)) ? null : "text", _arg_outputTextFormat);
            if (!string.IsNullOrEmpty(_arg_outputFile))
            {
                _outputWriter.TextWriter = File.CreateText(_arg_outputFile);//not needed if html output since application controlled
            }
            else
            {
                _outputWriter.TextWriter = Console.Out;
            }
        }
Пример #2
0
        void ConfigOutput()
        {
            WriteOnce.SafeLog("AnalyzeCommand::ConfigOutput", LogLevel.Trace);

            //Set output type, format and outstream
            _outputWriter = WriterFactory.GetWriter(_arg_fileFormat ?? "text", (string.IsNullOrEmpty(_arg_outputFile)) ? null : "text", _arg_outputTextFormat);
            if (_arg_fileFormat == "html")
            {
                if (!string.IsNullOrEmpty(_arg_outputFile))
                {
                    WriteOnce.Info("output file ignored for html format");
                }
                _outputWriter.TextWriter = Console.Out;
            }
            else if (!string.IsNullOrEmpty(_arg_outputFile))
            {
                _outputWriter.TextWriter = File.CreateText(_arg_outputFile);//not needed if html output since application controlled
            }
            else
            {
                _outputWriter.TextWriter = Console.Out;
            }
        }
        public void FlushAll()
        {
            if (_outputWriter != null)
            {
                _outputWriter.WriteApp(_appProfile);

                if (_outputWriter.TextWriter != null)
                {
                    if (_arg_fileFormat != "html")
                    {
                        _outputWriter.FlushAndClose();//not required for htmt formal i.e. already closed
                        _outputWriter    = null;
                        WriteOnce.Writer = null;

                        //Special case to avoid writing tmp file path to output file for TagTest,TagDiff or when called as a DLL since unnecessary
                        if (_arg_consoleVerbosityLevel.ToLower() != "none")
                        {
                            if (!String.IsNullOrEmpty(_arg_outputFile) && Utils.CLIExecutionContext)
                            {
                                WriteOnce.Info(ErrMsg.FormatString(ErrMsg.ID.ANALYZE_OUTPUT_FILE, _arg_outputFile), true, WriteOnce.ConsoleVerbosity.Medium, false);
                            }
                            else
                            {
                                WriteOnce.NewLine();
                            }
                        }
                    }
                    else
                    {
                        if (!_arg_suppressBrowserOpen && Utils.CLIExecutionContext)
                        {
                            WriteOnce.Any(ErrMsg.FormatString(ErrMsg.ID.ANALYZE_OUTPUT_FILE, "output.html"), true, ConsoleColor.Gray, WriteOnce.ConsoleVerbosity.Low);
                        }
                    }
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Main entry from CLI
        /// </summary>
        /// <returns></returns>
        public override int Run()
        {
            bool issues = false;

            WriteOnce.Operation(ErrMsg.FormatString(ErrMsg.ID.CMD_RUNNING, "Verify Rules"));

            //load [each] rules file separately to report out where a failure is happening
            RuleSet rules = new RuleSet(WriteOnce.Log);
            IEnumerable <string> fileListing = new List <string>();

            foreach (string rulePath in _rulePaths)
            {
                if (Directory.Exists(rulePath))
                {
                    fileListing = Directory.EnumerateFiles(rulePath, "*.json", SearchOption.AllDirectories);
                }
                else if (File.Exists(rulePath) && Path.GetExtension(rulePath) == ".json")
                {
                    fileListing = new List <string>()
                    {
                        new string(rulePath)
                    }
                }
                ;
                else
                {
                    throw new OpException(ErrMsg.FormatString(ErrMsg.ID.CMD_INVALID_RULE_PATH, rulePath));
                }

                //test loading each file
                foreach (string filename in fileListing)
                {
                    try
                    {
                        rules.AddFile(filename);
                        WriteOnce.Info(string.Format("Rule file added {0}", filename), true, WriteOnce.ConsoleVerbosity.High);
                    }
                    catch (Exception e)
                    {
                        WriteOnce.Error(string.Format("Rule file add failed {0}", filename));
                        WriteOnce.SafeLog(e.Message + "\n" + e.StackTrace, NLog.LogLevel.Error);
                        issues = true;
                    }
                }
            }

            //option to write validating data
            if (_arg_consoleVerbosityLevel.ToLower() == "high")
            {
                WritePartialRuleDetails(rules);
            }

            //final status report
            if (issues)
            {
                WriteOnce.Any(ErrMsg.GetString(ErrMsg.ID.VERIFY_RULES_RESULTS_FAIL), true, ConsoleColor.Red, WriteOnce.ConsoleVerbosity.Low);
            }
            else
            {
                WriteOnce.Any(ErrMsg.GetString(ErrMsg.ID.VERIFY_RULES_RESULTS_SUCCESS), true, ConsoleColor.Green, WriteOnce.ConsoleVerbosity.Low);
            }

            WriteOnce.Operation(ErrMsg.FormatString(ErrMsg.ID.CMD_COMPLETED, "Verify Rules"));
            WriteOnce.FlushAll();
            if (!String.IsNullOrEmpty(_arg_outputFile))
            {
                WriteOnce.Any(ErrMsg.FormatString(ErrMsg.ID.ANALYZE_OUTPUT_FILE, _arg_outputFile), true, ConsoleColor.Gray, WriteOnce.ConsoleVerbosity.Low);
            }

            return(issues ? (int)ExitCode.NotVerified : (int)ExitCode.Verified);
        }
Пример #5
0
        /// <summary>
        /// Main entry from CLI
        /// </summary>
        /// <returns></returns>
        public override int Run()
        {
            WriteOnce.SafeLog("TagDiffCommand::Run", LogLevel.Trace);
            WriteOnce.Operation(ErrMsg.FormatString(ErrMsg.ID.CMD_RUNNING, "tagdiff"));

            ExitCode exitCode = ExitCode.CriticalError;

            //save to quiet analyze cmd and restore
            WriteOnce.ConsoleVerbosity saveVerbosity     = WriteOnce.Verbosity;
            AnalyzeCommand.ExitCode    analyzeCmdResult1 = AnalyzeCommand.ExitCode.CriticalError;
            AnalyzeCommand.ExitCode    analyzeCmdResult2 = AnalyzeCommand.ExitCode.CriticalError;

            try
            {
                #region setup analyze calls

                string tmp1 = Path.GetTempFileName();
                string tmp2 = Path.GetTempFileName();

                AnalyzeCommand cmd1 = new AnalyzeCommand(new AnalyzeCommandOptions
                {
                    SourcePath            = _arg_src1,
                    OutputFilePath        = tmp1,
                    OutputFileFormat      = "json",
                    CustomRulesPath       = _arg_customRulesPath,
                    IgnoreDefaultRules    = _arg_ignoreDefault,
                    FilePathExclusions    = _arg_fileExclusionList,
                    SimpleTagsOnly        = true,
                    ConsoleVerbosityLevel = "none",
                    Log = _arg_logger
                });
                AnalyzeCommand cmd2 = new AnalyzeCommand(new AnalyzeCommandOptions
                {
                    SourcePath            = _arg_src2,
                    OutputFilePath        = tmp2,
                    OutputFileFormat      = "json",
                    CustomRulesPath       = _arg_customRulesPath,
                    IgnoreDefaultRules    = _arg_ignoreDefault,
                    FilePathExclusions    = _arg_fileExclusionList,
                    SimpleTagsOnly        = true,
                    ConsoleVerbosityLevel = "none",
                    Log = _arg_logger
                });


                analyzeCmdResult1 = (AnalyzeCommand.ExitCode)cmd1.Run();
                analyzeCmdResult2 = (AnalyzeCommand.ExitCode)cmd2.Run();

                ConfigureFileOutput();

                //restore
                WriteOnce.Verbosity = saveVerbosity;

                #endregion

                bool equalTagsCompare1 = true;
                bool equalTagsCompare2 = true;

                //process results for each analyze call before comparing results
                if (analyzeCmdResult1 == AnalyzeCommand.ExitCode.CriticalError)
                {
                    throw new Exception(ErrMsg.FormatString(ErrMsg.ID.CMD_CRITICAL_FILE_ERR, _arg_src1));
                }
                else if (analyzeCmdResult2 == AnalyzeCommand.ExitCode.CriticalError)
                {
                    throw new Exception(ErrMsg.FormatString(ErrMsg.ID.CMD_CRITICAL_FILE_ERR, _arg_src2));
                }
                else if (analyzeCmdResult1 == AnalyzeCommand.ExitCode.NoMatches || analyzeCmdResult2 == AnalyzeCommand.ExitCode.NoMatches)
                {
                    throw new Exception(ErrMsg.GetString(ErrMsg.ID.TAGDIFF_NO_TAGS_FOUND));
                }
                else //compare tag results; assumed (result1&2 == AnalyzeCommand.ExitCode.Success)
                {
                    //setup output here rather than top to avoid analyze command output in this command output
                    ConfigureFileOutput();
                    ConfigureConsoleOutput();//recheck

                    string file1TagsJson = File.ReadAllText(tmp1);
                    string file2TagsJson = File.ReadAllText(tmp2);

                    var file1Tags = JsonConvert.DeserializeObject <TagsFile>(file1TagsJson);
                    var file2Tags = JsonConvert.DeserializeObject <TagsFile>(file2TagsJson);

                    //can't simply compare counts as content may differ; must compare both in directions in two passes a->b; b->a
                    WriteOnce.General(ErrMsg.FormatString(ErrMsg.ID.TAGDIFF_RESULTS_GAP, Path.GetFileName(_arg_src1), Path.GetFileName(_arg_src2)),
                                      true, WriteOnce.ConsoleVerbosity.High);
                    equalTagsCompare1 = CompareTags(file1Tags.Tags, file2Tags.Tags);

                    //reverse order for second pass
                    WriteOnce.General(ErrMsg.FormatString(ErrMsg.ID.TAGDIFF_RESULTS_GAP, Path.GetFileName(_arg_src2), Path.GetFileName(_arg_src1)),
                                      true, WriteOnce.ConsoleVerbosity.High);
                    equalTagsCompare2 = CompareTags(file2Tags.Tags, file1Tags.Tags);

                    //final results
                    bool resultsDiffer = !(equalTagsCompare1 && equalTagsCompare2);
                    if (_arg_tagTestType == TagTestType.Inequality && !resultsDiffer)
                    {
                        exitCode = ExitCode.TestFailed;
                    }
                    else if (_arg_tagTestType == TagTestType.Equality && resultsDiffer)
                    {
                        exitCode = ExitCode.TestFailed;
                    }
                    else
                    {
                        exitCode = ExitCode.TestPassed;
                    }

                    WriteOnce.General(ErrMsg.FormatString(ErrMsg.ID.TAGDIFF_RESULTS_DIFFER), false);
                    WriteOnce.Result(resultsDiffer.ToString());
                    WriteOnce.Operation(ErrMsg.FormatString(ErrMsg.ID.CMD_COMPLETED, "tagdiff"));
                    if (!String.IsNullOrEmpty(_arg_outputFile) && Utils.CLIExecutionContext)
                    {
                        WriteOnce.Info(ErrMsg.FormatString(ErrMsg.ID.ANALYZE_OUTPUT_FILE, _arg_outputFile), true, WriteOnce.ConsoleVerbosity.Low, false);
                    }

                    WriteOnce.FlushAll();
                }

                //cleanup
                try
                {
                    File.Delete(tmp1);
                    File.Delete(tmp2);
                }
                catch
                {
                    //no action needed;
                }
            }
            catch (Exception e)
            {
                WriteOnce.Verbosity = saveVerbosity;
                if (analyzeCmdResult1 == AnalyzeCommand.ExitCode.Success && analyzeCmdResult2 == AnalyzeCommand.ExitCode.Success) //error not previously logged
                {
                    WriteOnce.Error(e.Message);
                }
                else
                {
                    WriteOnce.Error(e.Message, true, WriteOnce.ConsoleVerbosity.Low, false);//console but don't log again
                }
                //exit normaly for CLI callers and throw for DLL callers
                if (Utils.CLIExecutionContext)
                {
                    return((int)ExitCode.CriticalError);
                }
                else
                {
                    throw;
                }
            }
            finally
            {
                if (_arg_close_log_on_exit)
                {
                    Utils.Logger  = null;
                    WriteOnce.Log = null;
                }
            }

            return((int)exitCode);
        }
Пример #6
0
        /// <summary>
        /// Main entry from CLI
        /// </summary>
        /// <returns></returns>
        public override int Run()
        {
            WriteOnce.SafeLog("TagTestCommand::Run", LogLevel.Trace);
            WriteOnce.Operation(ErrMsg.FormatString(ErrMsg.ID.CMD_RUNNING, "tagtest"));

            //init based on true or false present argument value
            ExitCode exitCode = ExitCode.CriticalError;

            WriteOnce.ConsoleVerbosity saveVerbosity    = WriteOnce.Verbosity;
            AnalyzeCommand.ExitCode    analyzeCmdResult = AnalyzeCommand.ExitCode.CriticalError;

            try
            {
                //one file vs ruleset
                string tmp1 = Path.GetTempFileName();

                //setup analyze call with silent option
                AnalyzeCommand cmd1 = new AnalyzeCommand(new AnalyzeCommandOptions
                {
                    SourcePath            = _arg_srcPath,
                    OutputFilePath        = tmp1,
                    OutputFileFormat      = "json",
                    IgnoreDefaultRules    = true,
                    CustomRulesPath       = _arg_customRulesPath,
                    FilePathExclusions    = _arg_fileExclusionList,
                    SimpleTagsOnly        = true,
                    ConsoleVerbosityLevel = "None",
                    Log = _arg_logger
                });


                //get and perform initial analyze on results
                analyzeCmdResult = (AnalyzeCommand.ExitCode)cmd1.Run();

                //must be done here to avoid losing our handle from analyze command overwriting WriteOnce.Writer
                ConfigureFileOutput();

                //restore
                WriteOnce.Verbosity = saveVerbosity;

                if (analyzeCmdResult == AnalyzeCommand.ExitCode.CriticalError)
                {
                    throw new Exception(ErrMsg.GetString(ErrMsg.ID.CMD_CRITICAL_FILE_ERR));
                }
                else if (analyzeCmdResult == AnalyzeCommand.ExitCode.NoMatches)
                {
                    WriteOnce.General(ErrMsg.FormatString(ErrMsg.ID.TAGTEST_RESULTS_TEST_TYPE, _arg_tagTestType.ToString()), false, WriteOnce.ConsoleVerbosity.Low);
                    if (_arg_tagTestType == TagTestType.RulesPresent)
                    {
                        WriteOnce.Any(ErrMsg.GetString(ErrMsg.ID.TAGTEST_RESULTS_FAIL), true, ConsoleColor.Red, WriteOnce.ConsoleVerbosity.Low);
                    }
                    else
                    {
                        WriteOnce.Any(ErrMsg.GetString(ErrMsg.ID.TAGTEST_RESULTS_SUCCESS), true, ConsoleColor.Green, WriteOnce.ConsoleVerbosity.Low);
                    }

                    WriteOnce.Operation(ErrMsg.FormatString(ErrMsg.ID.CMD_COMPLETED, "tagtest"));

                    exitCode = _arg_tagTestType == TagTestType.RulesPresent ? ExitCode.TestFailed : ExitCode.TestPassed;
                }
                else //assumed (result == AnalyzeCommand.ExitCode.MatchesFound)
                {
                    string file1TagsJson = File.ReadAllText(tmp1);
                    var    file1Tags     = JsonConvert.DeserializeObject <TagsFile>(file1TagsJson);
                    File.Delete(tmp1);

                    exitCode = ExitCode.TestPassed;
                    foreach (Rule r in _rulesSet)
                    {
                        //supports both directions by generalizing
                        string[] testList1 = _arg_tagTestType == TagTestType.RulesNotPresent ?
                                             r.Tags : file1Tags.Tags;

                        string[] testList2 = _arg_tagTestType == TagTestType.RulesNotPresent ?
                                             file1Tags.Tags : r.Tags;

                        foreach (string t in testList2)
                        {
                            if (TagTest(testList1, t))
                            {
                                WriteOnce.Result(ErrMsg.FormatString(ErrMsg.ID.TAGTEST_RESULTS_TAGS_FOUND, t), true, WriteOnce.ConsoleVerbosity.High);
                            }
                            else
                            {
                                exitCode = ExitCode.TestFailed;
                                WriteOnce.Result(ErrMsg.FormatString(ErrMsg.ID.TAGTEST_RESULTS_TAGS_MISSING, t), true, WriteOnce.ConsoleVerbosity.High);
                            }

                            if (exitCode != ExitCode.TestPassed)
                            {
                                break;
                            }
                        }

                        if (exitCode != ExitCode.TestPassed)
                        {
                            break;
                        }
                    }

                    //results
                    WriteOnce.General(ErrMsg.FormatString(ErrMsg.ID.TAGTEST_RESULTS_TEST_TYPE, _arg_tagTestType.ToString()), false, WriteOnce.ConsoleVerbosity.Low);

                    if (exitCode == ExitCode.TestFailed)
                    {
                        WriteOnce.Any(ErrMsg.GetString(ErrMsg.ID.TAGTEST_RESULTS_FAIL), true, ConsoleColor.Red, WriteOnce.ConsoleVerbosity.Low);
                    }
                    else
                    {
                        WriteOnce.Any(ErrMsg.GetString(ErrMsg.ID.TAGTEST_RESULTS_SUCCESS), true, ConsoleColor.Green, WriteOnce.ConsoleVerbosity.Low);
                    }

                    WriteOnce.Operation(ErrMsg.FormatString(ErrMsg.ID.CMD_COMPLETED, "Tagtest"));
                    if (!String.IsNullOrEmpty(_arg_outputFile) && Utils.CLIExecutionContext)
                    {
                        WriteOnce.Info(ErrMsg.FormatString(ErrMsg.ID.ANALYZE_OUTPUT_FILE, _arg_outputFile), true, WriteOnce.ConsoleVerbosity.Low, false);
                    }

                    WriteOnce.FlushAll();
                }
            }
            catch (Exception e)
            {
                WriteOnce.Verbosity = saveVerbosity;
                if (analyzeCmdResult == AnalyzeCommand.ExitCode.Success) //then error was not previously logged
                {
                    WriteOnce.Error(e.Message);
                }
                else
                {
                    WriteOnce.Error(e.Message, true, WriteOnce.ConsoleVerbosity.Low, false);
                }

                //exit normaly for CLI callers and throw for DLL callers
                if (Utils.CLIExecutionContext)
                {
                    return((int)ExitCode.CriticalError);
                }
                else
                {
                    throw;
                }
            }
            finally
            {
                if (_arg_close_log_on_exit)
                {
                    Utils.Logger  = null;
                    WriteOnce.Log = null;
                }
            }

            return((int)exitCode);
        }
        readonly int MAX_HTML_REPORT_FILE_SIZE = 1024 * 1000 * 3;  //warn about potential slow rendering

        /// <summary>
        /// Registers datatypes with html framework liquid and sets up data for use within it and used
        /// with html partial.liquid files that are embedded as resources
        /// Liquid processing within partial html files only requires data ref to object while JS requires json objects
        /// </summary>
        /// <param name="app"></param>
        public override void WriteApp(AppProfile app)
        {
            var htmlTemplateText = File.ReadAllText(Path.Combine(Utils.GetPath(Utils.AppPath.basePath), "html/index.html"));

            Template.FileSystem = new EmbeddedFileSystem(Assembly.GetEntryAssembly(), "Microsoft.ApplicationInspector.CLI.html.partials");

            RegisterSafeType(typeof(AppProfile));
            RegisterSafeType(typeof(AppMetaData));

            var htmlTemplate = Template.Parse(htmlTemplateText);
            var data         = new Dictionary <string, object>();

            data["AppProfile"] = app;

            var hashData = new Hash();

            hashData["json"] = Newtonsoft.Json.JsonConvert.SerializeObject(data);//json serialization required for [js] access to objects
            hashData["application_version"] = Utils.GetVersionString();

            //add dynamic sets of groups of taginfo read from preferences for Profile page
            List <TagGroup> tagGroupList = app.GetCategoryTagGroups("profile");

            hashData["groups"] = tagGroupList;

            //add summary values for sorted tags lists of taginfo
            foreach (string outerKey in app.KeyedSortedTagInfoLists.Keys)
            {
                hashData.Add(outerKey, app.KeyedSortedTagInfoLists[outerKey]);
            }

            //add summary metadata lists
            hashData["cputargets"]   = app.MetaData.CPUTargets;
            hashData["apptypes"]     = app.MetaData.AppTypes;
            hashData["packagetypes"] = app.MetaData.PackageTypes;
            hashData["ostargets"]    = app.MetaData.OSTargets;
            hashData["outputs"]      = app.MetaData.Outputs;
            hashData["filetypes"]    = app.MetaData.FileExtensions;
            hashData["tagcounters"]  = app.MetaData.TagCountersUI;

            var    htmlResult         = htmlTemplate.Render(hashData);
            string htmlOutputFilePath = Path.Combine(Utils.GetPath(Utils.AppPath.basePath), "output.html");

            File.WriteAllText(htmlOutputFilePath, htmlResult);

            //writes out json report for convenience and linking to from report page(s)
            String jsonReportPath = Path.Combine(Utils.GetPath(Utils.AppPath.basePath), "output.json");
            Writer jsonWriter     = WriterFactory.GetWriter("json", jsonReportPath);

            jsonWriter.TextWriter = File.CreateText(jsonReportPath);
            jsonWriter.WriteApp(app);
            jsonWriter.FlushAndClose();

            //html report size warning
            string outputHTMLPath = Path.Combine(Utils.GetPath(Utils.AppPath.basePath), "output.html");

            if (File.Exists(outputHTMLPath) && new FileInfo(outputHTMLPath).Length > MAX_HTML_REPORT_FILE_SIZE)
            {
                WriteOnce.Info(ErrMsg.GetString(ErrMsg.ID.ANALYZE_REPORTSIZE_WARN));
            }

            if (!app.SuppressBrowserOpen)
            {
                Utils.OpenBrowser(htmlOutputFilePath);
            }
        }
        //Main entry from CLI
        public override int Run()
        {
            WriteOnce.SafeLog("ExportTagsCommand::Run", LogLevel.Trace);
            WriteOnce.Operation(ErrMsg.FormatString(ErrMsg.ID.CMD_RUNNING, "Exporttags"));

            SortedDictionary <string, string> uniqueTags = new SortedDictionary <string, string>();

            try
            {
                foreach (Rule r in _rules)
                {
                    //builds a list of unique tags
                    foreach (string t in r.Tags)
                    {
                        if (uniqueTags.ContainsKey(t))
                        {
                            continue;
                        }
                        else
                        {
                            uniqueTags.Add(t, t);
                        }
                    }
                }

                //separate loop so results are sorted (Sorted type)
                foreach (string s in uniqueTags.Values)
                {
                    WriteOnce.Result(s, true);
                }

                WriteOnce.Operation(ErrMsg.FormatString(ErrMsg.ID.CMD_COMPLETED, "Exporttags"));
                if (!String.IsNullOrEmpty(_arg_outputFile) && Utils.CLIExecutionContext)
                {
                    WriteOnce.Info(ErrMsg.FormatString(ErrMsg.ID.ANALYZE_OUTPUT_FILE, _arg_outputFile), true, WriteOnce.ConsoleVerbosity.Low, false);
                }

                WriteOnce.FlushAll();
            }
            catch (Exception e)
            {
                WriteOnce.Error(e.Message);
                //exit normaly for CLI callers and throw for DLL callers
                if (Utils.CLIExecutionContext)
                {
                    return((int)ExitCode.CriticalError);
                }
                else
                {
                    throw;
                }
            }
            finally
            {
                if (_arg_close_log_on_exit)
                {
                    Utils.Logger  = null;
                    WriteOnce.Log = null;
                }
            }

            return((int)ExitCode.Success);
        }