From f17c1790c49a4a8ad835f96197f7b1abb29c8280 Mon Sep 17 00:00:00 2001 From: VoR Date: Tue, 1 Mar 2016 12:09:51 -0500 Subject: [PATCH] Added error logging to application. Alert user when layout file has an error. --- App.xaml.cs | 30 ++++---- MainWindow.xaml.cs | 9 ++- OpenKeyboard.csproj | 1 + vLayout.cs | 162 +++++++++++++++++++++++--------------------- vLogger.cs | 67 ++++++++++++++++++ 5 files changed, 176 insertions(+), 93 deletions(-) create mode 100644 vLogger.cs diff --git a/App.xaml.cs b/App.xaml.cs index 2aff6b9..e6ee0e1 100644 --- a/App.xaml.cs +++ b/App.xaml.cs @@ -1,17 +1,19 @@ using System; -using System.Collections.Generic; -using System.Configuration; -using System.Data; -using System.Linq; -using System.Threading.Tasks; using System.Windows; +using System.Windows.Threading; -namespace OpenKeyboard -{ - /// - /// Interaction logic for App.xaml - /// - public partial class App : Application - { - } -} +namespace OpenKeyboard{ + public partial class App : Application{ + public void App_Startup(object sender, StartupEventArgs e) { + DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException); + }//event + + public void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) { + if(e.Exception.InnerException != null) vLogger.Exception("app.UnhandledException", e.Exception.InnerException); + else vLogger.Exception("app.UnhandledException", e.Exception); + + e.Handled = true; + Application.Current.Shutdown(); + }//func + }//cls +}//ns diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index 61a63ae..9a5852d 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -27,8 +27,13 @@ private void Window_Loaded(object sender, RoutedEventArgs e){ //Check which keyboard profile to load in. string[] args = Environment.GetCommandLineArgs(); - if(args.Length > 1) { vLayout.Load(args[1],mainContainer,this); } - else vLayout.Load("Thumbbar",mainContainer,this); + string layoutName = (args.Length > 1) ? layoutName = args[1] : "Default"; + + if(!vLayout.Load(layoutName, mainContainer, this)){ + MessageBox.Show("Error loading layout:" + layoutName); + this.Close(); + return; + }//if CreateContextMenu(); LoadLayoutList(); diff --git a/OpenKeyboard.csproj b/OpenKeyboard.csproj index e6b4a35..32d235c 100644 --- a/OpenKeyboard.csproj +++ b/OpenKeyboard.csproj @@ -69,6 +69,7 @@ + diff --git a/vLayout.cs b/vLayout.cs index 0d67dc5..e0e3ff7 100644 --- a/vLayout.cs +++ b/vLayout.cs @@ -8,85 +8,93 @@ namespace OpenKeyboard{ public abstract class vLayout{ public static FontFamily mIconFont = new FontFamily(new Uri("pack://application:,,,/fonts/#FontAwesome"), "./#FontAwesome"); - public static void Load(string fName,Grid uiGrid,Window uiWindow){ - //.......................................... - //Load up Layout XML - XmlDocument xml = new XmlDocument(); - xml.Load(RootPath("Layouts\\" + fName + ".xml")); - - XmlElement root = xml.DocumentElement; - if(root.ChildNodes.Count == 0) return; - - //.......................................... - //Set window size and position - double sHeight = SystemParameters.WorkArea.Height; - double sWidth = SystemParameters.WorkArea.Width; + public static bool Load(string fName,Grid uiGrid,Window uiWindow){ + try{ + //.......................................... + //Load up Layout XML + XmlDocument xml = new XmlDocument(); + xml.Load(RootPath("Layouts\\" + fName + ".xml")); + + XmlElement root = xml.DocumentElement; + if(root.ChildNodes.Count == 0) return false; + + //.......................................... + //Set window size and position + double sHeight = SystemParameters.WorkArea.Height; + double sWidth = SystemParameters.WorkArea.Width; - uiWindow.Width = double.Parse(root.GetAttribute("width")); - uiWindow.Height = double.Parse(root.GetAttribute("height")); - - switch(root.GetAttribute("vpos")){ - case "top": uiWindow.Top = 20; break; - case "center": uiWindow.Top = (sHeight - uiWindow.Height) / 2; break; - case "bottom": uiWindow.Top = sHeight - uiWindow.Height - 20; break; - }//switch - - switch(root.GetAttribute("hpos")){ - case "left": uiWindow.Left = 20; break; - case "center": uiWindow.Left = (sWidth - uiWindow.Width) / 2; break; - case "right": uiWindow.Left = sWidth - uiWindow.Width - 20; break; - }//switch - - //.......................................... - string sMargin = root.GetAttribute("margin"); - if(!String.IsNullOrEmpty(sMargin)){ - String[] aryMargin = sMargin.Split(','); - if(aryMargin.Length == 4){ - uiGrid.Margin = new Thickness( - int.Parse(aryMargin[0]) - , int.Parse(aryMargin[1]) - , int.Parse(aryMargin[2]) - , int.Parse(aryMargin[3]) - ); + uiWindow.Width = double.Parse(root.GetAttribute("width")); + uiWindow.Height = double.Parse(root.GetAttribute("height")); + + switch(root.GetAttribute("vpos")){ + case "top": uiWindow.Top = 20; break; + case "center": uiWindow.Top = (sHeight - uiWindow.Height) / 2; break; + case "bottom": uiWindow.Top = sHeight - uiWindow.Height - 20; break; + }//switch + + switch(root.GetAttribute("hpos")){ + case "left": uiWindow.Left = 20; break; + case "center": uiWindow.Left = (sWidth - uiWindow.Width) / 2; break; + case "right": uiWindow.Left = sWidth - uiWindow.Width - 20; break; + }//switch + + //.......................................... + string sMargin = root.GetAttribute("margin"); + if(!String.IsNullOrEmpty(sMargin)){ + String[] aryMargin = sMargin.Split(','); + if(aryMargin.Length == 4){ + uiGrid.Margin = new Thickness( + int.Parse(aryMargin[0]) + , int.Parse(aryMargin[1]) + , int.Parse(aryMargin[2]) + , int.Parse(aryMargin[3]) + ); + }//if }//if - }//if - - //.......................................... - //Reset UI Grid - uiGrid.Children.Clear(); - uiGrid.RowDefinitions.Clear(); - uiGrid.ColumnDefinitions.Clear(); - - //Create all the rows on the main UI Grid - for(int i=0; i < root.ChildNodes.Count; i++) uiGrid.RowDefinitions.Add(new RowDefinition(){ Height=new GridLength(1,GridUnitType.Star) }); - - //.......................................... - //Reset UI Grid - int iRow=0,iKey=0; - Grid rGrid; - - foreach(XmlNode row in root.ChildNodes){ - //Create Key Row Container - rGrid = CreateGrid(); - Grid.SetRow(rGrid,iRow); - Grid.SetColumn(rGrid,0); - uiGrid.Children.Add(rGrid); - - //Create Keys - iKey=0; - double gLen = 0; - string sgLen = ""; - foreach(XmlElement key in row.ChildNodes){ - sgLen = key.GetAttribute("weight"); - gLen = (String.IsNullOrEmpty(sgLen))?1:Double.Parse(sgLen); - - rGrid.ColumnDefinitions.Add(new ColumnDefinition(){ Width=new GridLength(gLen,GridUnitType.Star) }); - rGrid.Children.Add(CreateButton(key,iKey)); - iKey++; - }//for - iRow++; - }//for - }//func + + //.......................................... + //Reset UI Grid + uiGrid.Children.Clear(); + uiGrid.RowDefinitions.Clear(); + uiGrid.ColumnDefinitions.Clear(); + + //Create all the rows on the main UI Grid + for(int i=0; i < root.ChildNodes.Count; i++) uiGrid.RowDefinitions.Add(new RowDefinition(){ Height=new GridLength(1,GridUnitType.Star) }); + + //.......................................... + //Reset UI Grid + int iRow=0,iKey=0; + Grid rGrid; + + foreach(XmlNode row in root.ChildNodes){ + //Create Key Row Container + rGrid = CreateGrid(); + Grid.SetRow(rGrid,iRow); + Grid.SetColumn(rGrid,0); + uiGrid.Children.Add(rGrid); + + //Create Keys + iKey=0; + double gLen = 0; + string sgLen = ""; + foreach(XmlElement key in row.ChildNodes){ + sgLen = key.GetAttribute("weight"); + gLen = (String.IsNullOrEmpty(sgLen))?1:Double.Parse(sgLen); + + rGrid.ColumnDefinitions.Add(new ColumnDefinition(){ Width=new GridLength(gLen,GridUnitType.Star) }); + rGrid.Children.Add(CreateButton(key,iKey)); + iKey++; + }//for + iRow++; + }//for + + return true; + }catch(Exception e) { + vLogger.Exception("vLayout.Load", e, fName); + }//try + + return false; + }//func private static Grid CreateGrid(){ Grid grid = new Grid(); diff --git a/vLogger.cs b/vLogger.cs new file mode 100644 index 0000000..27ffc80 --- /dev/null +++ b/vLogger.cs @@ -0,0 +1,67 @@ +using System; +using System.IO; + +namespace OpenKeyboard { + public abstract class vLogger{ + public static void Exception(string errCode, Exception e) { Exception(errCode, e, ""); } + public static void Exception(string errCode, Exception e, string custom) { + try { + int i = 0; + do { + Console.WriteLine("ERROR " + errCode + " : " + e.Message + " : " + e.StackTrace + "\n\r" + custom); + FileAppend(String.Format("{2}{3}{4}" + , (e.InnerException != null || i > 0) ? errCode + "." + i.ToString() : errCode + , GetDate() + , EscapeXML(e.Message) + , EscapeXML(e.StackTrace) + , EscapeXML(custom) + , System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString() + )); + i++; e = e.InnerException; + } while(e != null); + } catch(Exception ex) { + System.Windows.MessageBox.Show(String.Format("ERROR ON SAVING ERROR : {2}{3}{4}" + , errCode + , GetDate() + , EscapeXML(e.Message) + , EscapeXML(e.StackTrace) + , EscapeXML(custom) + )); + }//try + }//func + + #region Support Function + public static string GetLogFilePath() { + string rtn = System.IO.Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName); + if(!rtn.EndsWith("\\")) rtn += "\\"; + return rtn + "error_log.txt"; + }//func + + public static string GetDate() { return DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss"); } + public static string EscapeXML(string txt) { return System.Security.SecurityElement.Escape(txt); } + + public static Boolean FileAppend(string txt) { return FileAppend(txt, 1); } + public static Boolean FileAppend(string txt, int step) { + string path = GetLogFilePath(); + StreamWriter sw = null; + Boolean stat = true; + Console.WriteLine(path); + try { + sw = new StreamWriter(path, true); + sw.WriteLine(txt); + } catch(Exception ex) { + //Error saving to Progress files, Try to save it to AppData before we quit. + if(step <= 1) stat = FileAppend(txt, 2); + else { + System.Windows.MessageBox.Show("ERROR ON SAVING ERROR : " + txt + " :: " + ex.Message); + stat = false; + }//if + } finally { + if(sw != null) { sw.Close(); sw = null; } + }//try + + return stat; + }//func + #endregion + }//cls +}//ns \ No newline at end of file