예제 #1
0
        /// <summary>
        /// Shuts down the Application Insights Logging functionality
        /// and flushes any pending requests.
        ///
        /// This handles start and stop times and the application lifetime
        /// log entry that logs duration of operation.
        /// </summary>
        public static void ShutdownLogging()
        {
            if (Configuration.System.SendTelemetry &&
                Telemetry.UseApplicationInsights &&
                AppInsights != null)
            {
                var t = AppRunTelemetry.Telemetry;

                // multi-instance shutdown - ignore
                if (t.Properties.ContainsKey("usage"))
                {
                    return;
                }

                t.Properties.Add("usage", Configuration.ApplicationUpdates.AccessCount.ToString());
                t.Properties.Add("registered", UnlockKey.IsAppRegistered().ToString());
                t.Properties.Add("version", GetVersion());
                t.Properties.Add("dotnetversion", MarkdownMonster.Utilities.mmWindowsUtils.GetDotnetVersion());
                t.Properties.Add("culture", CultureInfo.CurrentUICulture.IetfLanguageTag);
                t.Stop();

                try
                {
                    AppInsights.StopOperation(AppRunTelemetry);
                }
                catch (Exception ex)
                {
                    LogLocal("Failed to Stop Telemetry Client: " + ex.GetBaseException().Message);
                }

                AppInsights.Flush();
                AppInsights = null;
                AppRunTelemetry.Dispose();
            }
        }
예제 #2
0
        /// <summary>
        /// Renders markdown of the current document text into raw HTML
        /// </summary>
        /// <param name="markdown">markdown to render</param>
        /// <param name="renderLinksExternal">Determines whether links have a target='top' attribute</param>
        /// <param name="usePragmaLines">renders line numbers into html output as ID tags for editor positioning</param>
        /// <returns></returns>
        public string RenderHtml(string markdown = null, bool renderLinksExternal = false, bool usePragmaLines = false)
        {
            if (string.IsNullOrEmpty(markdown))
            {
                markdown = CurrentText;
            }

            var parser = MarkdownParserFactory.GetParser(usePragmaLines: usePragmaLines,
                                                         forceLoad: true,
                                                         parserAddinId: mmApp.Configuration.MarkdownOptions.MarkdownParserName);
            var html = parser.Parse(markdown);


            if (!string.IsNullOrEmpty(html) && !UnlockKey.IsRegistered() && mmApp.Configuration.ApplicationUpdates.AccessCount > 20)
            {
                html += @"
<div style=""margin-top: 30px;margin-bottom: 10px;font-size: 0.8em;border-top: 1px solid #eee;padding-top: 8px;opacity: 0.75;""
     title=""This message doesn't display in the registered version of Markdown Monster."">
    <img src=""https://markdownmonster.west-wind.com/favicon.png""
         style=""height: 20px;float: left; margin-right: 10px;opacity: 0.75;""/>
    created with the free version of
    <a href=""https://markdownmonster.west-wind.com"" 
       target=""top"">Markdown Monster</a> 
</div>
";
            }

            return(html);
        }
예제 #3
0
        public static void Shutdown(bool errorShutdown = false)
        {
            if (Configuration.SendTelemetry && Telemetry.UseApplicationInsights && AppInsights != null)
            {
                var t = AppRunTelemetry.Telemetry;
                t.Properties.Add("usage", Configuration.ApplicationUpdates.AccessCount.ToString());
                t.Properties.Add("registered", UnlockKey.IsRegistered().ToString());
                t.Properties.Add("version", GetVersion());
                t.Properties.Add("dotnetversion", ComputerInfo.GetDotnetVersion());
                t.Stop();

                try
                {
                    AppInsights.StopOperation(AppRunTelemetry);
                }
                catch (Exception ex)
                {
                    LogToLogfile("Failed to Stop Telemetry Client: " + ex.GetBaseException().Message);
                }
                AppInsights.Flush();
                AppInsights = null;
            }
            else
            {
                SendTelemetry("shutdown");
            }
        }
예제 #4
0
        public static void SendTelemetry(string operation, string data = null)
        {
            var    v       = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location);
            string version = v.FileMajorPart + "." + v.FileMinorPart;

            var t = new Telemetry
            {
                Version    = version,
                Registered = UnlockKey.IsRegistered(),
                Access     = mmApp.Configuration.ApplicationUpdates.AccessCount,
                Operation  = operation,
                Time       = Convert.ToInt32((DateTime.UtcNow - Started).TotalSeconds),
                Data       = data
            };

            try
            {
                HttpUtils.JsonRequest <string>(new HttpRequestSettings()
                {
                    Url      = mmApp.Configuration.TelemetryUrl,
                    HttpVerb = "POST",
                    Content  = t,
                    Timeout  = 300
                });
            }
            catch (Exception ex2)
            {
                // don't log with exception otherwise we get an endless loop
                Log("Unable to send telemetry: " + ex2.Message);
            }
        }
예제 #5
0
        /// <summary>
        /// Logs messages to the standard log output for Markdown Monster:
        /// 
        /// * Application Insights
        /// * Local Log File
        /// 
        /// </summary>
        /// <param name="msg"></param>
        public static void Log(string msg, Exception ex = null, bool unhandledException = false, LogLevels logLevel = LogLevels.Error)
        {
            string version = GetVersion();
            string winVersion = null;
            
            if (Telemetry.UseApplicationInsights && AppRunTelemetry?.Telemetry != null)
            {
                var secs = (int) DateTimeOffset.UtcNow.Subtract(AppRunTelemetry.Telemetry.Timestamp).TotalSeconds;

                if (ex != null)
                {
                    AppRunTelemetry.Telemetry.Success = false;
                    AppInsights.TrackException(ex,
                        new Dictionary<string, string>
                        {
                            {"msg", msg},
                            {"exmsg", ex.Message},
                            {"exbasemsg", ex.GetBaseException().Message},
                            {"exsource", ex.Source},
                            {"extrace", ex.StackTrace},
                            {"severity", unhandledException ? "unhandled" : ""},
                            {"version", version},
                            {"winversion", winVersion},
                            {"dotnetversion", MarkdownMonster.Utilities.mmWindowsUtils.GetDotnetVersion()},
                            {"usage", Configuration.ApplicationUpdates.AccessCount.ToString()},
                            {"registered", UnlockKey.IsAppRegistered().ToString()},
                            {"culture", CultureInfo.CurrentCulture.IetfLanguageTag},
                            {"uiculture", CultureInfo.CurrentUICulture.IetfLanguageTag},
                            {"seconds", secs.ToString() },
                            {"level", ((int) logLevel).ToString() + " - " + logLevel.ToString()}
                        });

                }
                else
                {
                    // message only
                    var props = new Dictionary<string, string>()
                    {
                        {"msg", msg},
                        {"usage", Configuration.ApplicationUpdates.AccessCount.ToString()},
                        {"registered", UnlockKey.IsAppRegistered().ToString()},
                        {"version", GetVersion()},
                        {"culture", CultureInfo.CurrentCulture.IetfLanguageTag},
                        {"uiculture", CultureInfo.CurrentUICulture.IetfLanguageTag},
                        {"seconds", secs.ToString() },
                        {"level", ((int) logLevel).ToString() + " - " + logLevel.ToString() }
                    };
                    AppInsights.TrackTrace(msg, props);                    
                }
            }
            
            // also log to the local error log
            LogLocal(msg,ex);            
        }
예제 #6
0
        /// <summary>
        /// Logs messages to the standard log output for Markdown Monster:
        ///
        /// * Application Insights
        /// * Local Log File
        ///
        /// </summary>
        /// <param name="msg"></param>
        public static void Log(string msg, Exception ex = null, bool unhandledException = false)
        {
            string version    = GetVersion();
            string winVersion = null;

            if (Telemetry.UseApplicationInsights)
            {
                if (ex != null)
                {
                    AppRunTelemetry.Telemetry.Success = false;
                    AppInsights.TrackException(ex,
                                               new Dictionary <string, string>
                    {
                        { "msg", msg },
                        { "exmsg", ex.Message },
                        { "exsource", ex.Source },
                        { "extrace", ex.StackTrace },
                        { "severity", unhandledException ? "unhandled" : "" },
                        { "version", version },
                        { "winversion", winVersion },
                        { "dotnetversion", WindowsUtils.GetDotnetVersion() },
                        { "usage", Configuration.ApplicationUpdates.AccessCount.ToString() },
                        { "registered", UnlockKey.IsRegistered().ToString() },
                        { "culture", CultureInfo.CurrentCulture.IetfLanguageTag },
                        { "uiculture", CultureInfo.CurrentUICulture.IetfLanguageTag }
                    });
                }
                else
                {
                    // message only
                    var props = new Dictionary <string, string>()
                    {
                        { "msg", msg },
                        { "usage", Configuration.ApplicationUpdates.AccessCount.ToString() },
                        { "registered", UnlockKey.IsRegistered().ToString() },
                        { "version", GetVersion() },
                        { "culture", CultureInfo.CurrentCulture.IetfLanguageTag },
                        { "uiculture", CultureInfo.CurrentUICulture.IetfLanguageTag }
                    };
                    AppInsights.TrackTrace(msg, props);
                }
            }

            // also log to the local error log
            LogLocal(msg, ex);
        }
예제 #7
0
        public static void Shutdown(bool errorShutdown = false)
        {
            if (Configuration.SendTelemetry && Telemetry.UseApplicationInsights && AppInsights != null)
            {
                var t = AppRunTelemetry.Telemetry;

                // multi-instance shutdown - ignore
                if (t.Properties.ContainsKey("usage"))
                {
                    return;
                }

                t.Properties.Add("usage", Configuration.ApplicationUpdates.AccessCount.ToString());
                t.Properties.Add("registered", UnlockKey.IsRegistered().ToString());
                t.Properties.Add("version", GetVersion());
                t.Properties.Add("dotnetversion", WindowsUtils.GetDotnetVersion());
                t.Properties.Add("culture", CultureInfo.CurrentUICulture.IetfLanguageTag);
                t.Stop();

                try
                {
                    AppInsights.StopOperation(AppRunTelemetry);
                }
                catch (Exception ex)
                {
                    LogLocal("Failed to Stop Telemetry Client: " + ex.GetBaseException().Message);
                }

                AppInsights.Flush();
                AppInsights = null;
                AppRunTelemetry.Dispose();
            }
            else
            {
                SendTelemetry("shutdown");
            }

            var tempPath = Path.GetTempPath();

            // Cleanup temp files
            File.Delete(Path.Combine(tempPath, "_MarkdownMonster_Preview.html"));
            FileUtils.DeleteTimedoutFiles(Path.Combine(tempPath, "mm_diff_*.*"), 1);
        }
예제 #8
0
        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);

            Hide();

            bool isNewVersion = CheckForNewVersion(false, false);

            mmApp.Configuration.ApplicationUpdates.AccessCount++;

            SaveSettings();

            if (!CloseAllTabs())
            {
                Show();
                e.Cancel = true;
                return;
            }

            if (mmApp.Configuration.UseSingleWindow)
            {
                PipeManager?.StopServer();

                if (App.Mutex != null)
                {
                    App.Mutex.Dispose();
                }
            }

            if (!isNewVersion &&
                mmApp.Configuration.ApplicationUpdates.AccessCount % 5 == 0 &&
                !UnlockKey.IsRegistered())
            {
                Hide();
                var rd = new RegisterDialog();
                rd.Owner = this;
                rd.ShowDialog();
            }

            mmApp.SendTelemetry("shutdown");

            e.Cancel = false;
        }
예제 #9
0
        public static void SendTelemetry(string operation, string data = null)
        {
            if (!Configuration.SendTelemetry)
            {
                return;
            }

            bool isRegistered = UnlockKey.IsRegistered();
            int  accessCount  = mmApp.Configuration.ApplicationUpdates.AccessCount;

            string version = GetVersion();

            var t = new Telemetry
            {
                Version    = version,
                Registered = isRegistered,
                Access     = accessCount,
                Operation  = operation,
                Time       = Convert.ToInt32((DateTime.UtcNow - Started).TotalSeconds),
                Data       = data
            };

            try
            {
                HttpUtils.JsonRequest <string>(new HttpRequestSettings()
                {
                    Url      = mmApp.Configuration.TelemetryUrl,
                    HttpVerb = "POST",
                    Content  = t,
                    Timeout  = 1000
                });
            }
            catch (Exception ex2)
            {
                // don't log with exception otherwise we get an endless loop
                Log("Unable to send telemetry: " + ex2.Message);
            }
        }
예제 #10
0
        /// <summary>
        /// Starts the Application Insights logging functionality
        /// Note: this should be set on application startup once
        /// and will not fire multiple times.
        /// </summary>
        public static void InitializeLogging()
        {
            try
            {
                if (Configuration.System.SendTelemetry &&
                    Telemetry.UseApplicationInsights &&
                    AppInsights == null)
                {
                    AppInsights = new TelemetryClient
                    {
                        InstrumentationKey = Telemetry.Key
                    };
                    AppInsights.Context.Session.Id        = Guid.NewGuid().ToString();
                    AppInsights.Context.Component.Version = GetVersion();

                    AppRunTelemetry =
                        AppInsights.StartOperation <RequestTelemetry>(
                            $"{GetVersion()} - {Configuration.ApplicationUpdates.AccessCount + 1} - {(UnlockKey.IsAppRegistered() ? "registered" : "unregistered")}");
                    AppRunTelemetry.Telemetry.Start();
                }
            }
            catch (Exception ex)
            {
                Telemetry.UseApplicationInsights = false;
                LogLocal("Application Insights initialization failure: " + ex.GetBaseException().Message);
            }
        }
예제 #11
0
        /// <summary>
        /// Logs messages to the log file
        /// </summary>
        /// <param name="msg"></param>
        public static void Log(string msg, Exception ex = null, bool unhandledException = false)
        {
            string version    = GetVersion();
            string winVersion = null;

            string exMsg = string.Empty;

            if (ex != null)
            {
                winVersion = ComputerInfo.GetWindowsVersion() +
                             " - " + CultureInfo.CurrentUICulture.IetfLanguageTag +
                             " - NET " + ComputerInfo.GetDotnetVersion() + " - " +
                             (Environment.Is64BitProcess ? "64 bit" : "32 bit");

                ex    = ex.GetBaseException();
                exMsg = $@"
Markdown Monster v{version}
{winVersion}
---
{ex.Source}
{ex.StackTrace}
---------------------------


";
                SendBugReport(ex, msg);
            }

            if (Telemetry.UseApplicationInsights)
            {
                if (ex != null)
                {
                    AppRunTelemetry.Telemetry.Success = false;
                    AppInsights.TrackException(ex,
                                               new Dictionary <string, string>
                    {
                        { "msg", msg },
                        { "exmsg", ex.Message },
                        { "exsource", ex.Source },
                        { "extrace", ex.StackTrace },
                        { "severity", unhandledException ? "unhandled" : "" },
                        { "version", version },
                        { "winversion", winVersion },
                        { "usage", Configuration.ApplicationUpdates.AccessCount.ToString() },
                        { "registered", UnlockKey.IsRegistered().ToString() }
                    });
                }
                else
                {
                    var props = new Dictionary <string, string>()
                    {
                        { "msg", msg },
                        { "version", GetVersion() },
                        { "usage", Configuration.ApplicationUpdates.AccessCount.ToString() },
                        { "registered", UnlockKey.IsRegistered().ToString() }
                    };
                    AppInsights.TrackTrace(msg, props);
                }
            }
            var text = msg + exMsg;

            LogToLogfile(text);
        }
예제 #12
0
        /// <summary>
        /// Renders markdown of the current document text into raw HTML
        /// </summary>
        /// <param name="markdown">markdown to render</param>
        /// <param name="renderLinksExternal">Determines whether links have a target='top' attribute</param>
        /// <param name="usePragmaLines">renders line numbers into html output as ID tags for editor positioning</param>
        /// <returns></returns>
        public string RenderHtml(string markdown          = null,
                                 bool renderLinksExternal = false,
                                 bool usePragmaLines      = false)
        {
            if (string.IsNullOrEmpty(markdown))
            {
                markdown = CurrentText;
            }

            if (string.IsNullOrEmpty(markdown))
            {
                return(markdown);
            }

            OnBeforeDocumentRendered(ref markdown);

            var parser = MarkdownParserFactory.GetParser(usePragmaLines: usePragmaLines,
                                                         forceLoad: true,
                                                         parserAddinId: mmApp.Configuration.MarkdownOptions.MarkdownParserName);


            if (!string.IsNullOrEmpty(PreviewWebRootPath))
            {
                var path = FileUtils.AddTrailingSlash(PreviewWebRootPath).Replace("\\", "/");
                markdown = markdown.Replace("](~/", "](" + path);
                markdown = markdown.Replace("](/", "](" + path);
            }

            // allow override of RenderScriptTags if set
            var oldAllowScripts = mmApp.Configuration.MarkdownOptions.AllowRenderScriptTags;

            if (ProcessScripts)
            {
                mmApp.Configuration.MarkdownOptions.AllowRenderScriptTags = false;
            }

            var html = parser.Parse(markdown);

            mmApp.Configuration.MarkdownOptions.AllowRenderScriptTags = oldAllowScripts;


            OnDocumentRendered(ref html, ref markdown);


            if (!string.IsNullOrEmpty(html) && !UnlockKey.IsRegistered() && mmApp.Configuration.ApplicationUpdates.AccessCount > 20)
            {
                html += @"
<div style=""margin-top: 30px;margin-bottom: 10px;font-size: 0.8em;border-top: 1px solid #eee;padding-top: 8px;cursor: pointer;""
     title=""This message doesn't display in the registered version of Markdown Monster."" onclick=""window.open('https://markdownmonster.west-wind.com')"">
    <img src=""https://markdownmonster.west-wind.com/favicon.png""
         style=""height: 20px;float: left; margin-right: 10px;""/>
    created with the free version of
    <a href=""https://markdownmonster.west-wind.com""
       target=""top"">Markdown Monster</a>
</div>
";
            }



            return(html);
        }
예제 #13
0
        private void HandleCommandLineArguments(string[] commandArgs)
        {
            var arg0 = CommandArgs[0].ToLower().TrimStart('-');

            if (CommandArgs[0] == "-")
            {
                arg0 = "-";
            }

            if (Environment.CommandLine.Contains("-presentation"))
            {
                StartInPresentationMode = true;
            }

            switch (arg0)
            {
            case "version":
                // just display the header
                break;

            case "uninstall":
                _noStart = true;
                UninstallSettings();

                ConsoleHeader();
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("Markdown Monster Machine Wide Settings uninstalled.");
                ConsoleFooter();

                break;

            case "reset":
                // load old config and backup
                mmApp.Configuration.Backup();
                mmApp.Configuration.Reset();     // forces exit

                ConsoleHeader();
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("Markdown Monster Settings reset to defaults.");
                ConsoleFooter();

                break;

            case "setportable":
                ConsoleHeader();

                // Note: Startup logic to handle portable startup is in AppConfiguration::FindCommonFolder
                try
                {
                    string portableSettingsFolder = Path.Combine(InitialStartDirectory, "PortableSettings");
                    bool   exists          = Directory.Exists(portableSettingsFolder);
                    string oldCommonFolder = mmApp.Configuration.CommonFolder;

                    File.WriteAllText("_IsPortable",
                                      @"forces the settings to be read from .\PortableSettings rather than %appdata%");

                    if (!exists &&
                        Directory.Exists(oldCommonFolder) &&
                        MessageBox.Show(
                            "Portable mode set. Do you want to copy settings from:\r\n\r\n" +
                            oldCommonFolder + "\r\n\r\nto the PortableSettings folder?",
                            "Markdown MonsterPortable Mode",
                            MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                    {
                        FileUtils.CopyDirectory(oldCommonFolder,
                                                portableSettingsFolder, deepCopy: true);

                        mmApp.Configuration.CommonFolder = portableSettingsFolder;
                        mmApp.Configuration.Read();
                    }


                    mmApp.Configuration.CommonFolder = portableSettingsFolder;
                    mmApp.Configuration.Write();
                }
                catch (Exception ex)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Unable to set portable mode: " + ex.Message);
                }

                ConsoleFooter();
                break;

            case "unsetportable":
                ConsoleHeader();
                try
                {
                    File.Delete("_IsPortable");
                    mmApp.Configuration.InternalCommonFolder = Path.Combine(
                        Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Markdown Monster");
                    mmApp.Configuration.CommonFolder = mmApp.Configuration.InternalCommonFolder;
                    mmApp.Configuration.Write();

                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine("Removed Portable settings for this installation. Use `mm SetPortable` to reenable.");
                }
                catch (Exception ex)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine($"Unable to delete portable settings switch file\r\n_IsPortable\r\n\r\n{ex.Message}");
                }

                break;

            case "register":
                ConsoleHeader();
                if (CommandArgs.Length < 2)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Missing registration code. Please pass a registration code.");
                }
                else
                {
                    if (!UnlockKey.Register(CommandArgs[1]))
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.WriteLine("Invalid registration code. Please pass a valid registration code.");
                    }
                    else
                    {
                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.WriteLine("Registration succeeded. Thank your for playing fair.");
                    }
                }
                ConsoleFooter();
                break;

            // Standard In Re-Routing
            case "stdin":
                string stdin = null;
                if (Console.IsInputRedirected)
                {
                    using (var stream = Console.OpenStandardInput())
                    {
                        byte[] buffer  = new byte[1000];     // Use whatever size you want
                        var    builder = new StringBuilder();
                        int    read    = -1;
                        while (true)
                        {
                            var gotInput    = new AutoResetEvent(false);
                            var inputThread = new Thread(() =>
                            {
                                try
                                {
                                    read = stream.Read(buffer, 0, buffer.Length);
                                    gotInput.Set();
                                }
                                catch (ThreadAbortException)
                                {
                                    Thread.ResetAbort();
                                }
                            })
                            {
                                IsBackground = true
                            };

                            inputThread.Start();

                            // Timeout expired?
                            if (!gotInput.WaitOne(100))
                            {
                                inputThread.Abort();
                                break;
                            }

                            // End of stream?
                            if (read == 0)
                            {
                                stdin = builder.ToString();
                                break;
                            }

                            // Got data
                            builder.Append(Console.InputEncoding.GetString(buffer, 0, read));
                        }

                        if (builder.Length > 0)
                        {
                            var tempFile = Path.ChangeExtension(Path.GetTempFileName(), "md");
                            File.WriteAllText(tempFile, builder.ToString());
                            CommandArgs[0] = tempFile;
                        }
                        else
                        {
                            CommandArgs[0] = null;
                        }
                    }
                }

                break;
            }
        }
예제 #14
0
        public static void ApplicationStart()
        {
            Started = DateTime.UtcNow;

            if (Telemetry.UseApplicationInsights)
            {
                AppInsights = new TelemetryClient {
                    InstrumentationKey = Telemetry.Key
                };
                AppInsights.Context.Session.Id        = Guid.NewGuid().ToString();
                AppInsights.Context.Component.Version = GetVersion();

                AppRunTelemetry = AppInsights.StartOperation <RequestTelemetry>($"App Run - {GetVersion()} - {Configuration.ApplicationUpdates.AccessCount + 1} - {(UnlockKey.IsRegistered() ? "registered" : "unregistered")}");
                AppRunTelemetry.Telemetry.Start();
            }
        }