Fixed blocking issue
[pithos-ms-client] / trunk / Pithos.Client.WPF / App.xaml.cs
index 3a03fab..e9ab29e 100644 (file)
-using System;
-using System.Collections.Generic;
-using System.Configuration;
-using System.Data;
-using System.Diagnostics;
-using System.Linq;
-using System.Net;
-using System.Net.Mail;
-using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using Caliburn.Micro;
-using Microsoft.Win32;
-using Caliburn.Micro.Logging;
-using Pithos.Client.WPF.Properties;
-
-
-namespace Pithos.Client.WPF
-{
-    /// <summary>
-    /// Interaction logic for App.xaml
-    /// </summary>
-    public partial class App : Application
-    {
-        private readonly log4net.ILog _log = log4net.LogManager.GetLogger(typeof (App));
-
-        public App()
-        {
-            log4net.Config.XmlConfigurator.Configure();            
-            
-            this.DispatcherUnhandledException += OnUnhandledException;
-            AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
-            TaskScheduler.UnobservedTaskException += OnUnobservedException;
-
-            //Fix incorrect proxy settings by switching to default proxy, if the proxy server settings is empty
-            if (Settings.Default.UseManualProxy && String.IsNullOrWhiteSpace(Settings.Default.ProxyServer))
-            {
-                Settings.Default.UseManualProxy = false;
-                Settings.Default.UseDefaultProxy = true;
-            }
-
-            InitializeComponent();            
-        }
-
-        protected override void OnStartup(StartupEventArgs e)
-        {            
-            if (!Settings.Default.StartOnSystemStartup && e.Args.Contains("startup"))
-            {
-                this.Shutdown();
-            }
-            base.OnStartup(e);
-        }
-
-        private void OnUnobservedException(object sender, UnobservedTaskExceptionEventArgs e)
-        {            
-            var messages=new List<UserMessage>();
-            e.Exception.Handle(exc=>{
-                messages.Add(new UserMessage
-                {
-                    Message = "Unexpected Exception",
-                    Details = exc.ToString(),
-                    Severity = Severity.Error
-                });
-                return true;
-            });
-
-            ShowMessages("Oops!","Where did that come from? \r\nErm, an exception occured.\r\nWe apologize for the inconvenience", messages);
-            e.SetObserved();
-        }
-
-        private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
-        {
-            var message = e.IsTerminating
-                              ? "Unexpected Exception. The application must terminate"
-                              : "Unexpected Exception";
-
-
-            var messages = new[]{
-                                   new UserMessage
-                                       {
-                                           Message = (e.ExceptionObject as Exception).Message,
-                                           Details = e.ExceptionObject.ToString(),
-                                           Severity = Severity.Error
-                                       }
-                               };
-            ShowMessages("Oops!", message,messages);
-        }
-
-        void OnUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
-        {                        
-            var messages = new[]{
-                                   new UserMessage
-                                       {
-                                           Message = e.Exception.Message, 
-                                           Details = e.Exception.ToString(),
-                                           Severity = Severity.Error
-                                       }
-                               };
-            ShowMessages("Oops!", "Unexcpected Exception", messages);
-            e.Handled=true;
-        }
-
-        void ShowMessages(string title,string message,IEnumerable<UserMessage> messages )
-        {
-            LogMessages(messages);
-            Execute.OnUIThread(()=>{
-                var messageView = new MessageView(messages);
-                messageView.Title = title;
-                messageView.Message = message;
-                messageView.ShowDialog();
-            });
-        }
-
-        private void LogMessages(IEnumerable<UserMessage> messages)
-        {
-            var logMessage = CreateMessage(messages);
-
-            _log.Error(logMessage);
-        }
-
-        private static string CreateMessage(IEnumerable<UserMessage> messages)
-        {
-            var messageBuilder = messages.Aggregate(new StringBuilder("Unexpected Error\r\n"),
-                                                    (builder, message) =>
-                                                        {
-                                                            builder.AppendFormat("\r\n[{0}] {1}\r\n{2}\r\n", message.Severity,
-                                                                                 message.Message, message.Details);
-                                                            return builder;
-                                                        });
-            var logMessage = messageBuilder.ToString();
-            return logMessage;
-        }
-    }
-
-}
+#region\r
+/* -----------------------------------------------------------------------\r
+ * <copyright file="App.xaml.cs" company="GRNet">\r
+ * \r
+ * Copyright 2011-2012 GRNET S.A. All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or\r
+ * without modification, are permitted provided that the following\r
+ * conditions are met:\r
+ *\r
+ *   1. Redistributions of source code must retain the above\r
+ *      copyright notice, this list of conditions and the following\r
+ *      disclaimer.\r
+ *\r
+ *   2. Redistributions in binary form must reproduce the above\r
+ *      copyright notice, this list of conditions and the following\r
+ *      disclaimer in the documentation and/or other materials\r
+ *      provided with the distribution.\r
+ *\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS\r
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR\r
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\r
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\r
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * The views and conclusions contained in the software and\r
+ * documentation are those of the authors and should not be\r
+ * interpreted as representing official policies, either expressed\r
+ * or implied, of GRNET S.A.\r
+ * </copyright>\r
+ * -----------------------------------------------------------------------\r
+ */\r
+#endregion\r
+using System;\r
+using System.Collections.Generic;\r
+using System.IO;\r
+using System.Linq;\r
+using System.Net;\r
+using System.Reflection;\r
+using System.Text;\r
+using System.Threading;\r
+using System.Threading.Tasks;\r
+using System.Windows;\r
+using Caliburn.Micro;\r
+using Pithos.Client.WPF.Configuration;\r
+using Pithos.Client.WPF.Properties;\r
+using Pithos.Interfaces;\r
+using log4net.Appender;\r
+using log4net.Core;\r
+using log4net.Repository.Hierarchy;\r
+using System.Runtime.InteropServices;\r
+\r
+\r
+namespace Pithos.Client.WPF\r
+{\r
+    /// <summary>\r
+    /// Interaction logic for App.xaml\r
+    /// </summary>\r
+    public partial class App : Application\r
+    {\r
+        private static readonly log4net.ILog Log = log4net.LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType );\r
+        \r
+            //DLL Import to add restart manager support\r
+            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]\r
+            public static extern Int32 RegisterApplicationRestart(String commandLineArgs, UInt32 flags);\r
+               \r
+        public App()\r
+        {\r
+\r
+            //var instanceMutex=new Mutex()\r
+            InitializeLogging();\r
+\r
+\r
+            //Detect OS, if Major Version is 6+ use RestartManager\r
+            OperatingSystem os = Environment.OSVersion;\r
+            Version vs = os.Version;\r
+\r
+            //Register Application in the Restartmanager service\r
+            Log.ErrorFormat("OS: [{0}]", vs.Major);\r
+            if (vs.Major > 5)\r
+            {\r
+                Int32 result = RegisterApplicationRestart(null, 0);\r
+                Log.ErrorFormat("RM Result: [{0}]", result);\r
+            }\r
+\r
+            DispatcherUnhandledException += OnDispatcherUnhandledException;\r
+            AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;\r
+            TaskScheduler.UnobservedTaskException += OnUnobservedException;\r
+\r
+\r
+            //Fix incorrect proxy settings by switching to default proxy, if the proxy server settings is empty\r
+            if (Settings.Default.UseManualProxy && String.IsNullOrWhiteSpace(Settings.Default.ProxyServer))\r
+            {\r
+                Settings.Default.UseManualProxy = false;\r
+                Settings.Default.UseDefaultProxy = true;\r
+            }\r
+\r
+            if (Settings.Default.IgnoreCertificateErrors)\r
+                ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;\r
+            ServicePointManager.Expect100Continue = false;\r
+            InitializeComponent();            \r
+        }       \r
+\r
+\r
+/*\r
+        private void OnUpdateDetected(object sender, UpdateDetectedEventArgs e)\r
+        {\r
+            Log.InfoFormat("Update Detected {0}",e.LatestVersion.Version);    \r
+        }\r
+*/\r
+\r
+        private static void InitializeLogging()\r
+        {\r
+            log4net.Config.XmlConfigurator.Configure();\r
+\r
+            try\r
+            {\r
+                var pithosDataPath = PithosSettings.PithosDataPath;\r
+                if (!Directory.Exists(pithosDataPath))\r
+                    Directory.CreateDirectory(pithosDataPath);\r
+\r
+                var loggerRepository = (Hierarchy)log4net.LogManager.GetRepository();\r
+\r
+                var appenders = loggerRepository.GetAppenders();\r
+                \r
+\r
+                var lossyAppender = appenders.OfType<BufferingForwardingAppender>()\r
+                    .FirstOrDefault(appender => appender.Name == "LossyFileAppender");\r
+                if (lossyAppender!=null)\r
+                {\r
+                    var dumpAppender = lossyAppender.Appenders.OfType<RollingFileAppender>().First();\r
+                    dumpAppender.File = Path.Combine(pithosDataPath, "errorlog.xml");\r
+                    dumpAppender.ActivateOptions();\r
+                }\r
+                \r
+                var debugAppender =appenders.OfType<RollingFileAppender>()\r
+                    .FirstOrDefault(a => a.Name == "DebugFileAppender");\r
+                if (debugAppender != null)\r
+                {\r
+                    debugAppender.File = Path.Combine(pithosDataPath, "debuglog.xml");\r
+                    if (!Settings.Default.DebugLoggingEnabled)\r
+                        debugAppender.Threshold = Level.Off;\r
+                    debugAppender.ActivateOptions();\r
+                }\r
+            }\r
+            catch (Exception exc)\r
+            {\r
+                Log.Error("Dumpl appender initialization failed",exc);                \r
+            }\r
+        }\r
+\r
+        private Mutex _singleInstanceMutex;\r
+\r
+        protected override void OnStartup(StartupEventArgs e)\r
+        {\r
+            if (!Settings.Default.StartOnSystemStartup && e.Args.Contains("startup"))\r
+            {\r
+                Shutdown();\r
+                return;\r
+            }\r
+\r
+            bool firstInstance;\r
+            _singleInstanceMutex = new Mutex(false, "PITHOSMUTEX", out firstInstance);\r
+            if (!firstInstance)\r
+            {\r
+                _singleInstanceMutex.Dispose();\r
+                _singleInstanceMutex = null;\r
+                Shutdown();\r
+                return;\r
+            }\r
+\r
+            //Delay during startup\r
+            if (e.Args.Contains("startup"))\r
+            {\r
+                if (Settings.Default.StartupDelay>TimeSpan.Zero)\r
+                    Thread.Sleep(Settings.Default.StartupDelay);\r
+            }\r
+\r
+            var splashScreen = new SplashScreen("images/pithos_logo-title-margin-splash-600-whitebg.png");\r
+            splashScreen.Show(true);\r
+            \r
+            base.OnStartup(e);\r
+        }\r
+\r
+        protected override void OnExit(ExitEventArgs e)\r
+        {\r
+            try\r
+            {\r
+                if (_singleInstanceMutex!=null)\r
+                    _singleInstanceMutex.Dispose();\r
+                _singleInstanceMutex = null;\r
+            }\r
+            catch { }\r
+            base.OnExit(e);\r
+        }\r
+\r
+        private void OnUnobservedException(object sender, UnobservedTaskExceptionEventArgs e)\r
+        {\r
+            Log.Error("Unobserved Task Exception", e.Exception); \r
+            \r
+            var messages = new List<UserMessage>();\r
+            e.Exception.Handle(exc=>{\r
+                messages.Add(new UserMessage\r
+                {\r
+                    Message = "Unexpected Exception",\r
+                    Details = exc.ToString(),\r
+                    Severity = Severity.Error\r
+                });\r
+                return true;\r
+            });\r
+\r
+\r
+            //Do not display any messages if this is a 304 code\r
+            var ignoreExceptions = from exc in e.Exception.InnerExceptions.OfType<WebException>()\r
+                                   where IsAllowedException(exc)\r
+                                   select exc;\r
+\r
+            if (ignoreExceptions.Any())\r
+            {\r
+                e.SetObserved();\r
+                return;\r
+            }\r
+\r
+\r
+           /* var message = String.Format(@"{0}" + Environment.NewLine + "{1}" + Environment.NewLine + "{2}", \r
+                WPF.Properties.Resources.Unexpected_Error,\r
+                WPF.Properties.Resources.We_Apologize, \r
+                WPF.Properties.Resources.Please_Submit_Error);\r
+            ShowMessages("Oops!",message, messages);*/\r
+            e.SetObserved();            \r
+        }\r
+\r
+        private bool IsAllowedException(Exception exc)\r
+        {\r
+            var we = exc as WebException;\r
+            if (we==null)\r
+            {\r
+                return false;\r
+            }\r
+            var response = we.Response as HttpWebResponse;\r
+            return (response != null && response.StatusCode == HttpStatusCode.NotModified);\r
+        }\r
+\r
+        private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)\r
+        {\r
+\r
+            //Do not display any messages if this is a 304 code\r
+            if (IsAllowedException(e.ExceptionObject as Exception))\r
+            {\r
+                return;\r
+            }\r
+\r
+            if (e.ExceptionObject is ReflectionTypeLoadException)\r
+            {\r
+                var les=(ReflectionTypeLoadException) e.ExceptionObject;\r
+                Log.Error("Unhandled exception", les);\r
+                foreach (var le in les.LoaderExceptions)\r
+                {\r
+                    Log.Error("Dll load error", le);    \r
+                }\r
+            }\r
+            else\r
+                Log.Error("Unhandled exception", (Exception)e.ExceptionObject);\r
+\r
+            if (!e.IsTerminating)\r
+                //Do not display a message unless the application is terminating\r
+                return;\r
+\r
+            var description = e.IsTerminating\r
+                              ? WPF.Properties.Resources.Unexpected_Error_Terminating\r
+                              : WPF.Properties.Resources.Unexpected_Error;\r
+            var message = String.Format(@"{0}<LineBreak/>{1}<LineBreak/><LineBreak/>{2}",\r
+                description,\r
+                WPF.Properties.Resources.We_Apologize,\r
+                WPF.Properties.Resources.Please_Submit_Error);\r
+\r
+            var exc = ((Exception) e.ExceptionObject);\r
+            var messages = new[]{\r
+                                   new UserMessage\r
+                                       {\r
+                                           Message = exc.Message,\r
+                                           Details = exc.ToString(),\r
+                                           Severity = Severity.Error\r
+                                       }\r
+                               };\r
+\r
+\r
+            ShowMessages("Oops!", message,messages);\r
+        }\r
+\r
+\r
+\r
+        void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)\r
+        {\r
+            //Do not display any messages if this is a 304 code\r
+            if (IsAllowedException(e.Exception))\r
+            {\r
+                return;\r
+            }\r
+\r
+            if (e.Exception is ReflectionTypeLoadException)\r
+            {\r
+                var les = (ReflectionTypeLoadException)e.Exception;\r
+                Log.Error("Unhandled exception", les);\r
+                foreach (var le in les.LoaderExceptions)\r
+                {\r
+                    Log.Error("Dll load error", le);\r
+                }\r
+            }\r
+            else\r
+                Log.Error("Unhandled Dispatcher exception", e.Exception);\r
+            \r
+           /* var messages = new[]{\r
+                                   new UserMessage\r
+                                       {\r
+                                           Message = e.Exception.Message, \r
+                                           Details = e.Exception.ToString(),\r
+                                           Severity = Severity.Error\r
+                                       }\r
+                               };\r
+            ShowMessages(WPF.Properties.Resources.Error_Title, \r
+                WPF.Properties.Resources.Unexpected_Error,\r
+                messages);*/\r
+            e.Handled=true;\r
+        }\r
+\r
+        void ShowMessages(string title,string message,IEnumerable<UserMessage> messages )\r
+        {\r
+            var messageList = messages.ToList();\r
+            LogMessages(messageList);\r
+            Execute.OnUIThread(()=>{\r
+                                       var messageView = new MessageView(messageList)\r
+                                                        {\r
+                                                            Title = title, \r
+                                                            Message = message\r
+                                                        };\r
+                                       messageView.ShowDialog();\r
+            });\r
+        }\r
+\r
+        private void LogMessages(IEnumerable<UserMessage> messages)\r
+        {\r
+            var logMessage = CreateMessage(messages);\r
+\r
+            Log.Error(logMessage);\r
+        }\r
+\r
+        private static string CreateMessage(IEnumerable<UserMessage> messages)\r
+        {\r
+            var messageBuilder = messages.Aggregate(new StringBuilder("Unexpected Error\r\n"),\r
+                                                    (builder, message) =>\r
+                                                        {\r
+                                                            builder.AppendFormat("\r\n[{0}] {1}\r\n{2}\r\n", message.Severity,\r
+                                                                                 message.Message, message.Details);\r
+                                                            return builder;\r
+                                                        });\r
+            var logMessage = messageBuilder.ToString();\r
+            return logMessage;\r
+        }\r
+    }\r
+\r
+}\r
+\r
+    enum RestartFlags\r
+    {\r
+        NONE = 0,\r
+        RESTART_CYCLICAL = 1,\r
+        RESTART_NOTIFY_SOLUTION = 2,\r
+        RESTART_NOTIFY_FAULT = 4,\r
+        RESTART_NO_CRASH = 8,\r
+        RESTART_NO_HANG = 16,\r
+        RESTART_NO_PATCH = 32,\r
+        RESTART_NO_REBOOT = 64\r
+    }
\ No newline at end of file