@@ -43,7 +43,7 @@ public partial class MainWindow : Window
4343        public  static readonly  string  projectNameFile  =  "ProjectName.txt" ; 
4444        public  static string  preferredVersion  =  null ; 
4545        public  static int  projectNameSetting  =  0 ;  // 0 = folder or ProjectName.txt if exists, 1=ProductName 
46-         public  static readonly  string  initScriptFileFullPath  =  GetInitScriptPath ( ) ; 
46+         public  static readonly  string  initScriptFileFullPath  =  Tools . GetSafeFilePath ( "Scripts" ,   "InitializeProject.cs" ) ; 
4747
4848        const  string  contextRegRoot  =  "Software\\ Classes\\ Directory\\ Background\\ shell" ; 
4949        const  string  githubURL  =  "https://github.com/unitycoder/UnityLauncherPro" ; 
@@ -2724,51 +2724,52 @@ private void MenuItemBrowsePersistentDataPath_Click(object sender, RoutedEventAr
27242724            } 
27252725        } 
27262726
2727-         void  ApplyTheme ( string  themeFile ) 
2727+         private   void  ApplyTheme ( string  themeFileName ) 
27282728        { 
2729-             if  ( chkUseCustomTheme . IsChecked  ==  false )  return ; 
2730- 
2731-             //Console.WriteLine("Load theme: " + themefile); 
2729+             if  ( chkUseCustomTheme . IsChecked  !=  true ) 
2730+                 return ; 
27322731
2733-             themeFile  =  "Themes/"  +  themeFile ; 
2732+             // 1) Compute the full, safe path to the INI 
2733+             string  themePath  =  Tools . GetSafeFilePath ( "Themes" ,  themeFileName ) ; 
27342734
2735-             if  ( File . Exists ( themeFile )  ==  true ) 
2735+             // 2) Try to load it 
2736+             if  ( File . Exists ( themePath ) ) 
27362737            { 
2737-                 var  colors  =  File . ReadAllLines ( themeFile ) ; 
2738- 
2739-                 // parse lines 
2740-                 for  ( int  i  =  0 ,  length  =  colors . Length ;  i  <  length ;  i ++ ) 
2738+                 var  lines  =  File . ReadAllLines ( themePath ) ; 
2739+                 for  ( int  i  =  0 ;  i  <  lines . Length ;  i ++ ) 
27412740                { 
2742-                     // skip comments 
2743-                     if  ( colors [ i ] . IndexOf ( '#' )  ==  0 )  continue ; 
2744-                     // split row (name and color) 
2745-                     var  row  =  colors [ i ] . Split ( '=' ) ; 
2746-                     // skip bad rows 
2747-                     if  ( row . Length  !=  2 )  continue ; 
2748- 
2749-                     // parse color 
2741+                     string  line  =  lines [ i ] . Trim ( ) ; 
2742+                     // skip empty or comment 
2743+                     if  ( string . IsNullOrEmpty ( line )  ||  line . StartsWith ( "#" ) ) 
2744+                         continue ; 
2745+ 
2746+                     var  parts  =  line . Split ( new [ ]  {  '='  } ,  2 ) ; 
2747+                     if  ( parts . Length  !=  2 ) 
2748+                         continue ; 
2749+ 
2750+                     string  key  =  parts [ 0 ] . Trim ( ) ; 
2751+                     string  value  =  parts [ 1 ] . Trim ( ) ; 
2752+ 
27502753                    try 
27512754                    { 
2752-                         //Console.WriteLine(row[0] +"="+ row[1].Trim()); 
2753-                         var  col  =  new  BrushConverter ( ) . ConvertFrom ( row [ 1 ] . Trim ( ) ) ; 
2754-                         // apply color 
2755-                         Application . Current . Resources [ row [ 0 ] ]  =  ( SolidColorBrush ) col ; 
2755+                         var  brush  =  ( SolidColorBrush ) new  BrushConverter ( ) . ConvertFrom ( value ) ; 
2756+                         Application . Current . Resources [ key ]  =  brush ; 
27562757                    } 
2757-                     catch  ( Exception  e ) 
2758+                     catch  ( Exception  ex ) 
27582759                    { 
2759-                         Console . WriteLine ( e ) ; 
2760-                         SetStatus ( "Failed to parse color value: "    +   row [ 1 ] ) ; 
2760+                         Console . WriteLine ( ex ) ; 
2761+                         SetStatus ( $ "Failed to parse color value: { value } " ) ; 
27612762                    } 
2762- 
27632763                } 
27642764            } 
27652765            else 
27662766            { 
2767-                 Console . WriteLine ( "Theme file not found: "    +   themeFile ) ; 
2768-                 SetStatus ( "Theme file not found: "    +   themeFile ) ; 
2767+                 Console . WriteLine ( $ "Theme file not found: { themePath } " ) ; 
2768+                 SetStatus ( $ "Theme file not found: { themePath } " ) ; 
27692769            } 
27702770        } 
27712771
2772+ 
27722773        void  ResetTheme ( ) 
27732774        { 
27742775            foreach  ( DictionaryEntry  item  in  Application . Current . Resources . MergedDictionaries [ 0 ] ) 
@@ -2809,8 +2810,8 @@ private void BtnReloadTheme_Click(object sender, RoutedEventArgs e)
28092810        private  void  TxtCustomThemeFile_LostFocus ( object  sender ,  RoutedEventArgs  e ) 
28102811        { 
28112812            var  s  =  ( TextBox ) sender ; 
2812-             Properties . Settings . Default . themeFile  =  s . Text ; 
2813-             Properties . Settings . Default . Save ( ) ; 
2813+             Settings . Default . themeFile  =  s . Text ; 
2814+             Settings . Default . Save ( ) ; 
28142815        } 
28152816
28162817        private  void  TxtCustomThemeFile_PreviewKeyDown ( object  sender ,  KeyEventArgs  e ) 
@@ -4105,31 +4106,6 @@ private void btnPurgeMissingFolders_Click(object sender, RoutedEventArgs e)
41054106            SetStatus ( "Purged "  +  removedCount  +  " items" ,  MessageType . Info ) ; 
41064107        } 
41074108
4108-         // to handle folders where user has no write access () 
4109-         private  static string  GetInitScriptPath ( ) 
4110-         { 
4111-             string  preferredDir  =  Path . Combine ( AppDomain . CurrentDomain . BaseDirectory ,  "Scripts" ) ; 
4112-             string  fallbackDir  =  Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . LocalApplicationData ) ,  "UnityLauncherPro" ,  "Scripts" ) ; 
4113- 
4114-             try 
4115-             { 
4116-                 Directory . CreateDirectory ( preferredDir ) ;  // safe even if it exists 
4117-                 return  Path . Combine ( preferredDir ,  "InitializeProject.cs" ) ; 
4118-             } 
4119-             catch  ( UnauthorizedAccessException ) 
4120-             { 
4121-                 // No write permission in Program Files etc. 
4122-             } 
4123-             catch  ( Exception  ex ) 
4124-             { 
4125-                 // Optional: log other unexpected errors 
4126-                 Console . WriteLine ( "Init folder fallback: "  +  ex . Message ) ; 
4127-             } 
4128- 
4129-             Directory . CreateDirectory ( fallbackDir ) ;  // always safe 
4130-             return  Path . Combine ( fallbackDir ,  "InitializeProject.cs" ) ; 
4131-         } 
4132- 
41334109        //private void menuProjectProperties_Click(object sender, RoutedEventArgs e) 
41344110        //{ 
41354111        //    var proj = GetSelectedProject(); 
0 commit comments