@@ -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