2 /* -----------------------------------------------------------------------
3 * <copyright file="App.xaml.cs" company="GRNet">
5 * Copyright 2011-2012 GRNET S.A. All rights reserved.
7 * Redistribution and use in source and binary forms, with or
8 * without modification, are permitted provided that the following
11 * 1. Redistributions of source code must retain the above
12 * copyright notice, this list of conditions and the following
15 * 2. Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials
18 * provided with the distribution.
21 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
22 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
25 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
34 * The views and conclusions contained in the software and
35 * documentation are those of the authors and should not be
36 * interpreted as representing official policies, either expressed
37 * or implied, of GRNET S.A.
39 * -----------------------------------------------------------------------
43 using System.Collections.Generic;
47 using System.Reflection;
49 using System.Threading;
50 using System.Threading.Tasks;
53 using Pithos.Client.WPF.Configuration;
54 using Pithos.Client.WPF.Properties;
55 using Pithos.Interfaces;
56 using log4net.Appender;
58 using log4net.Repository.Hierarchy;
59 using System.Runtime.InteropServices;
62 namespace Pithos.Client.WPF
65 /// Interaction logic for App.xaml
67 public partial class App : Application
69 private static readonly log4net.ILog Log = log4net.LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType );
71 ///DLL Import to add restart manager support
72 [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
73 static extern uint RegisterApplicationRestart(string pwzCommandLine, RestartFlags dwFlags);
78 //var instanceMutex=new Mutex()
81 ///Register Application in the Restartmanager service
82 RegisterApplicationRestart("Upgrade", RestartFlags.NONE);
85 DispatcherUnhandledException += OnDispatcherUnhandledException;
86 AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
87 TaskScheduler.UnobservedTaskException += OnUnobservedException;
90 //Fix incorrect proxy settings by switching to default proxy, if the proxy server settings is empty
91 if (Settings.Default.UseManualProxy && String.IsNullOrWhiteSpace(Settings.Default.ProxyServer))
93 Settings.Default.UseManualProxy = false;
94 Settings.Default.UseDefaultProxy = true;
97 if (Settings.Default.IgnoreCertificateErrors)
98 ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;
101 InitializeComponent();
106 private void OnUpdateDetected(object sender, UpdateDetectedEventArgs e)
108 Log.InfoFormat("Update Detected {0}",e.LatestVersion.Version);
112 private static void InitializeLogging()
114 log4net.Config.XmlConfigurator.Configure();
118 var pithosDataPath = PithosSettings.PithosDataPath;
119 if (!Directory.Exists(pithosDataPath))
120 Directory.CreateDirectory(pithosDataPath);
122 var loggerRepository = (Hierarchy)log4net.LogManager.GetRepository();
124 var appenders = loggerRepository.GetAppenders();
127 var lossyAppender = appenders.OfType<BufferingForwardingAppender>()
128 .FirstOrDefault(appender => appender.Name == "LossyFileAppender");
129 if (lossyAppender!=null)
131 var dumpAppender = lossyAppender.Appenders.OfType<RollingFileAppender>().First();
132 dumpAppender.File = Path.Combine(pithosDataPath, "errorlog.xml");
133 dumpAppender.ActivateOptions();
136 var debugAppender =appenders.OfType<RollingFileAppender>()
137 .FirstOrDefault(a => a.Name == "DebugFileAppender");
138 if (debugAppender != null)
140 debugAppender.File = Path.Combine(pithosDataPath, "debuglog.xml");
141 if (!Settings.Default.DebugLoggingEnabled)
142 debugAppender.Threshold = Level.Off;
143 debugAppender.ActivateOptions();
146 catch (Exception exc)
148 Log.Error("Dumpl appender initialization failed",exc);
152 private Mutex _singleInstanceMutex;
154 protected override void OnStartup(StartupEventArgs e)
156 if (!Settings.Default.StartOnSystemStartup && e.Args.Contains("startup"))
163 _singleInstanceMutex = new Mutex(false, "PITHOSMUTEX", out firstInstance);
166 _singleInstanceMutex.Dispose();
167 _singleInstanceMutex = null;
172 //Delay during startup
173 if (e.Args.Contains("startup"))
175 if (Settings.Default.StartupDelay>TimeSpan.Zero)
176 Thread.Sleep(Settings.Default.StartupDelay);
179 var splashScreen = new SplashScreen("images/pithos_logo-title-margin-splash-600-whitebg.png");
180 splashScreen.Show(true);
185 protected override void OnExit(ExitEventArgs e)
189 if (_singleInstanceMutex!=null)
190 _singleInstanceMutex.Dispose();
191 _singleInstanceMutex = null;
197 private void OnUnobservedException(object sender, UnobservedTaskExceptionEventArgs e)
199 Log.Error("Unobserved Task Exception", e.Exception);
201 var messages = new List<UserMessage>();
202 e.Exception.Handle(exc=>{
203 messages.Add(new UserMessage
205 Message = "Unexpected Exception",
206 Details = exc.ToString(),
207 Severity = Severity.Error
213 //Do not display any messages if this is a 304 code
214 var ignoreExceptions = from exc in e.Exception.InnerExceptions.OfType<WebException>()
215 where IsAllowedException(exc)
218 if (ignoreExceptions.Any())
225 /* var message = String.Format(@"{0}" + Environment.NewLine + "{1}" + Environment.NewLine + "{2}",
226 WPF.Properties.Resources.Unexpected_Error,
227 WPF.Properties.Resources.We_Apologize,
228 WPF.Properties.Resources.Please_Submit_Error);
229 ShowMessages("Oops!",message, messages);*/
233 private bool IsAllowedException(Exception exc)
235 var we = exc as WebException;
240 var response = we.Response as HttpWebResponse;
241 return (response != null && response.StatusCode == HttpStatusCode.NotModified);
244 private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
247 //Do not display any messages if this is a 304 code
248 if (IsAllowedException(e.ExceptionObject as Exception))
253 Log.Error("Unhandled exception", (Exception)e.ExceptionObject);
255 if (!e.IsTerminating)
256 //Do not display a message unless the application is terminating
259 var description = e.IsTerminating
260 ? WPF.Properties.Resources.Unexpected_Error_Terminating
261 : WPF.Properties.Resources.Unexpected_Error;
262 var message = String.Format(@"{0}<LineBreak/>{1}<LineBreak/><LineBreak/>{2}",
264 WPF.Properties.Resources.We_Apologize,
265 WPF.Properties.Resources.Please_Submit_Error);
267 var exc = ((Exception) e.ExceptionObject);
268 var messages = new[]{
271 Message = exc.Message,
272 Details = exc.ToString(),
273 Severity = Severity.Error
278 ShowMessages("Oops!", message,messages);
283 void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
285 //Do not display any messages if this is a 304 code
286 if (IsAllowedException(e.Exception))
291 Log.Error("Unhandled Dispatcher exception", e.Exception);
293 /* var messages = new[]{
296 Message = e.Exception.Message,
297 Details = e.Exception.ToString(),
298 Severity = Severity.Error
301 ShowMessages(WPF.Properties.Resources.Error_Title,
302 WPF.Properties.Resources.Unexpected_Error,
307 void ShowMessages(string title,string message,IEnumerable<UserMessage> messages )
309 var messageList = messages.ToList();
310 LogMessages(messageList);
311 Execute.OnUIThread(()=>{
312 var messageView = new MessageView(messageList)
317 messageView.ShowDialog();
321 private void LogMessages(IEnumerable<UserMessage> messages)
323 var logMessage = CreateMessage(messages);
325 Log.Error(logMessage);
328 private static string CreateMessage(IEnumerable<UserMessage> messages)
330 var messageBuilder = messages.Aggregate(new StringBuilder("Unexpected Error\r\n"),
331 (builder, message) =>
333 builder.AppendFormat("\r\n[{0}] {1}\r\n{2}\r\n", message.Severity,
334 message.Message, message.Details);
337 var logMessage = messageBuilder.ToString();
347 RESTART_CYCLICAL = 1,
348 RESTART_NOTIFY_SOLUTION = 2,
349 RESTART_NOTIFY_FAULT = 4,
350 RESTART_NO_CRASH = 8,
351 RESTART_NO_HANG = 16,
352 RESTART_NO_PATCH = 32,
353 RESTART_NO_REBOOT = 64