diff --git a/App.xaml b/App.xaml
new file mode 100644
index 0000000..a8442ea
--- /dev/null
+++ b/App.xaml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/App.xaml.cs b/App.xaml.cs
new file mode 100644
index 0000000..4d41b2b
--- /dev/null
+++ b/App.xaml.cs
@@ -0,0 +1,14 @@
+using System.Configuration;
+using System.Data;
+using System.Windows;
+
+namespace DirectoryCreator
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public partial class App : Application
+ {
+ }
+
+}
diff --git a/AssemblyInfo.cs b/AssemblyInfo.cs
new file mode 100644
index 0000000..b0ec827
--- /dev/null
+++ b/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/ConfigEditorWindow.xaml b/ConfigEditorWindow.xaml
new file mode 100644
index 0000000..eec762c
--- /dev/null
+++ b/ConfigEditorWindow.xaml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ConfigEditorWindow.xaml.cs b/ConfigEditorWindow.xaml.cs
new file mode 100644
index 0000000..484a9bd
--- /dev/null
+++ b/ConfigEditorWindow.xaml.cs
@@ -0,0 +1,211 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using DirectoryCreator.Models;
+using Microsoft.Win32;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.Text.Json;
+using System.Windows;
+
+namespace DirectoryCreator
+{
+ ///
+ /// Interaction logic for Window1.xaml
+ ///
+ public partial class ConfigEditorWindow : Window
+ {
+ public ConfigEditorWindow()
+ {
+ InitializeComponent();
+ }
+ }
+}
+
+namespace DirectoryCreator.ViewModels
+{
+
+ public partial class ConfigEditorViewModel : ObservableObject
+ {
+ private readonly Window _window;
+ private readonly string _configPath;
+ private bool _isNewConfig;
+
+ [ObservableProperty]
+ private string configDescription;
+
+ [ObservableProperty]
+ private string basePath;
+
+ [ObservableProperty]
+ private ObservableCollection folderStructures;
+
+ public ConfigEditorViewModel(Window window, FolderConfig? existingConfig = null, string? configPath = null)
+ {
+ _window = window;
+ _configPath = configPath;
+ _isNewConfig = existingConfig == null;
+
+ FolderStructures = new ObservableCollection();
+
+ if (existingConfig != null)
+ {
+ LoadFromConfig(existingConfig);
+ }
+ else
+ {
+ ConfigDescription = "Nueva Configuración";
+ BasePath = "";
+ }
+ }
+
+ private void LoadFromConfig(FolderConfig config)
+ {
+ ConfigDescription = config.Description;
+ BasePath = config.BasePath;
+
+ foreach (var structure in config.FolderStructures)
+ {
+ var structureVm = new FolderStructureViewModel
+ {
+ BasePath = structure.BasePath,
+ Subfolders = new ObservableCollection(
+ structure.Subfolders.Select(s => new SubfolderViewModel { Name = s }))
+ };
+ FolderStructures.Add(structureVm);
+ }
+ }
+
+ [RelayCommand]
+ private void SelectBasePath()
+ {
+ var dialog = new OpenFolderDialog
+ {
+ Title = "Seleccionar Carpeta Base"
+ };
+
+ if (dialog.ShowDialog() == true)
+ {
+ BasePath = dialog.FolderName;
+ }
+ }
+
+ [RelayCommand]
+ private void SelectStructurePath(FolderStructureViewModel structure)
+ {
+ var dialog = new OpenFolderDialog
+ {
+ Title = "Seleccionar Carpeta Base para la Estructura"
+ };
+
+ if (dialog.ShowDialog() == true)
+ {
+ structure.BasePath = dialog.FolderName;
+ }
+ }
+
+ [RelayCommand]
+ private void AddStructure()
+ {
+ FolderStructures.Add(new FolderStructureViewModel
+ {
+ BasePath = "",
+ Subfolders = new ObservableCollection()
+ });
+ }
+
+ [RelayCommand]
+ private void RemoveStructure(FolderStructureViewModel structure)
+ {
+ FolderStructures.Remove(structure);
+ }
+
+ [RelayCommand]
+ private void AddSubfolder(FolderStructureViewModel structure)
+ {
+ structure.Subfolders.Add(new SubfolderViewModel { Name = "Nueva Subcarpeta" });
+ }
+
+ [RelayCommand]
+ private void RemoveSubfolder(SubfolderViewModel subfolder)
+ {
+ foreach (var structure in FolderStructures)
+ {
+ if (structure.Subfolders.Contains(subfolder))
+ {
+ structure.Subfolders.Remove(subfolder);
+ break;
+ }
+ }
+ }
+
+ [RelayCommand]
+ private void Save()
+ {
+ try
+ {
+ var config = new FolderConfig
+ {
+ Description = ConfigDescription,
+ BasePath = BasePath,
+ FolderStructures = FolderStructures.Select(s => new FolderStructure
+ {
+ BasePath = s.BasePath,
+ Subfolders = s.Subfolders.Select(sf => sf.Name).ToList()
+ }).ToList()
+ };
+
+ string filePath = _configPath;
+ if (_isNewConfig || string.IsNullOrEmpty(filePath))
+ {
+ var dialog = new SaveFileDialog
+ {
+ Filter = "Archivos JSON (*.json)|*.json",
+ InitialDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Configurations"),
+ FileName = "config.json"
+ };
+
+ if (dialog.ShowDialog() != true)
+ return;
+
+ filePath = dialog.FileName;
+ }
+
+ var jsonString = JsonSerializer.Serialize(config, new JsonSerializerOptions
+ {
+ WriteIndented = true
+ });
+
+ File.WriteAllText(filePath, jsonString);
+ MessageBox.Show("Configuración guardada exitosamente!", "Éxito", MessageBoxButton.OK, MessageBoxImage.Information);
+ _window.DialogResult = true;
+ _window.Close();
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"Error al guardar la configuración: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+
+ [RelayCommand]
+ private void Cancel()
+ {
+ _window.DialogResult = false;
+ _window.Close();
+ }
+ }
+
+ public partial class FolderStructureViewModel : ObservableObject
+ {
+ [ObservableProperty]
+ private string basePath;
+
+ [ObservableProperty]
+ private ObservableCollection subfolders;
+ }
+
+ public partial class SubfolderViewModel : ObservableObject
+ {
+ [ObservableProperty]
+ private string name;
+ }
+}
\ No newline at end of file
diff --git a/DirectoryCreator.csproj b/DirectoryCreator.csproj
new file mode 100644
index 0000000..0f19ade
--- /dev/null
+++ b/DirectoryCreator.csproj
@@ -0,0 +1,21 @@
+
+
+
+ WinExe
+ net8.0-windows
+ enable
+ enable
+ true
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
diff --git a/DirectoryCreator.sln b/DirectoryCreator.sln
new file mode 100644
index 0000000..9085cba
--- /dev/null
+++ b/DirectoryCreator.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.12.35707.178 d17.12
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DirectoryCreator", "DirectoryCreator.csproj", "{87235683-100B-4DF9-9FD8-C67720C9F90C}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {87235683-100B-4DF9-9FD8-C67720C9F90C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {87235683-100B-4DF9-9FD8-C67720C9F90C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {87235683-100B-4DF9-9FD8-C67720C9F90C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {87235683-100B-4DF9-9FD8-C67720C9F90C}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/FolderConfig.cs b/FolderConfig.cs
new file mode 100644
index 0000000..62ff03f
--- /dev/null
+++ b/FolderConfig.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DirectoryCreator.Models
+{
+ public class FolderConfig
+ {
+ public string Description { get; set; }
+ public string BasePath { get; set; }
+ public List FolderStructures { get; set; }
+ }
+
+ public class FolderStructure
+ {
+ public string BasePath { get; set; }
+ public List Subfolders { get; set; }
+ }
+}
diff --git a/MainWindow.xaml b/MainWindow.xaml
new file mode 100644
index 0000000..27fe651
--- /dev/null
+++ b/MainWindow.xaml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs
new file mode 100644
index 0000000..9c11a97
--- /dev/null
+++ b/MainWindow.xaml.cs
@@ -0,0 +1,262 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using DirectoryCreator.Models;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+using System.IO;
+using System.Text.Json;
+using System.Windows;
+
+namespace DirectoryCreator.ViewModels
+{
+ public partial class MainWindowViewModel : ObservableObject
+ {
+ private readonly string configDirectory = "Configurations";
+ private FolderConfig currentConfig;
+
+ [ObservableProperty]
+ private string lastProjectNumber;
+
+ [ObservableProperty]
+ private string newProjectName;
+
+ [ObservableProperty]
+ private string basePath;
+
+ [ObservableProperty]
+ private ObservableCollection availableConfigurations;
+
+ [ObservableProperty]
+ private FolderConfig selectedConfiguration;
+
+ public MainWindowViewModel()
+ {
+ AvailableConfigurations = new ObservableCollection();
+ LoadConfigurations();
+ }
+
+ private void LoadConfigurations()
+ {
+ try
+ {
+ // Asegurar que existe el directorio de configuraciones
+ if (!Directory.Exists(configDirectory))
+ {
+ Directory.CreateDirectory(configDirectory);
+
+ // Si no existe, mover el archivo de configuración por defecto
+ if (File.Exists("folderConfig.json"))
+ {
+ File.Move("folderConfig.json", Path.Combine(configDirectory, "default.json"));
+ }
+ }
+
+ // Cargar todas las configuraciones
+ var jsonFiles = Directory.GetFiles(configDirectory, "*.json");
+ if (jsonFiles.Length == 0)
+ {
+ MessageBox.Show("No se encontraron archivos de configuración.", "Advertencia", MessageBoxButton.OK, MessageBoxImage.Warning);
+ return;
+ }
+
+ var options = new JsonSerializerOptions
+ {
+ PropertyNameCaseInsensitive = true,
+ AllowTrailingCommas = true
+ };
+
+ AvailableConfigurations.Clear();
+ foreach (var jsonFile in jsonFiles)
+ {
+ var jsonString = File.ReadAllText(jsonFile);
+ var config = JsonSerializer.Deserialize(jsonString, options);
+ if (config != null)
+ {
+ // Si no tiene descripción, usar el nombre del archivo
+ if (string.IsNullOrEmpty(config.Description))
+ {
+ config.Description = Path.GetFileNameWithoutExtension(jsonFile);
+ }
+ AvailableConfigurations.Add(config);
+ }
+ }
+
+ // Seleccionar la primera configuración por defecto
+ if (AvailableConfigurations.Count > 0)
+ {
+ SelectedConfiguration = AvailableConfigurations[0];
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"Error al cargar las configuraciones: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+
+ partial void OnSelectedConfigurationChanged(FolderConfig value)
+ {
+ if (value != null)
+ {
+ currentConfig = value;
+ BasePath = value.BasePath;
+ LoadLastProjectNumber();
+ }
+ }
+
+ [RelayCommand]
+ private void OpenBaseFolder()
+ {
+ try
+ {
+ if (Directory.Exists(BasePath))
+ {
+ Process.Start("explorer.exe", BasePath);
+ }
+ else
+ {
+ MessageBox.Show($"La carpeta base no existe: {BasePath}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"Error al abrir la carpeta base: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+
+ private void LoadLastProjectNumber()
+ {
+ try
+ {
+ if (string.IsNullOrEmpty(BasePath) || !Directory.Exists(BasePath))
+ {
+ NewProjectName = "001 - ";
+ return;
+ }
+
+ var directories = Directory.GetDirectories(BasePath)
+ .Select(d => new DirectoryInfo(d).Name)
+ .ToList();
+
+ var regex = new System.Text.RegularExpressions.Regex(@"^(\d{1,3})\s-\s");
+ var projectNumbers = new HashSet();
+
+ foreach (var dirName in directories)
+ {
+ var match = regex.Match(dirName);
+ if (match.Success && int.TryParse(match.Groups[1].Value, out int number))
+ {
+ projectNumbers.Add(number);
+ }
+ }
+
+ var sortedNumbers = projectNumbers.OrderByDescending(n => n).ToList();
+ int lastValidNumber = -1;
+ string lastProject = "";
+
+ foreach (int number in sortedNumbers)
+ {
+ if (projectNumbers.Contains(number - 1) && projectNumbers.Contains(number - 2))
+ {
+ lastValidNumber = number;
+ lastProject = directories.First(d => regex.Match(d).Success &&
+ int.Parse(regex.Match(d).Groups[1].Value) == number);
+ break;
+ }
+ }
+
+ LastProjectNumber = lastProject;
+ NewProjectName = lastValidNumber >= 0 ? $"{(lastValidNumber + 1):000} - " : "001 - ";
+
+ if (lastValidNumber < 0)
+ {
+ MessageBox.Show("No se encontró una secuencia válida de al menos 3 números consecutivos.\nSe iniciará desde 001.",
+ "Información", MessageBoxButton.OK, MessageBoxImage.Information);
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"Error al cargar el último proyecto: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ NewProjectName = "001 - ";
+ }
+ }
+
+ [RelayCommand]
+ private void EditConfigurations()
+ {
+ var window = new ConfigEditorWindow
+ {
+ Owner = System.Windows.Application.Current.MainWindow
+ };
+
+ if (SelectedConfiguration != null)
+ {
+ var configPath = Directory.GetFiles(configDirectory, "*.json")
+ .FirstOrDefault(f =>
+ {
+ var config = JsonSerializer.Deserialize(
+ File.ReadAllText(f),
+ new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
+ return config?.Description == SelectedConfiguration.Description;
+ });
+
+ window.DataContext = new ConfigEditorViewModel(window, SelectedConfiguration, configPath);
+ }
+ else
+ {
+ window.DataContext = new ConfigEditorViewModel(window);
+ }
+
+ if (window.ShowDialog() == true)
+ {
+ LoadConfigurations();
+ }
+ }
+
+ [RelayCommand]
+ private void CreateDirectories()
+ {
+ if (string.IsNullOrEmpty(NewProjectName))
+ {
+ MessageBox.Show("Por favor ingrese un nombre de proyecto!", "Advertencia", MessageBoxButton.OK, MessageBoxImage.Warning);
+ return;
+ }
+
+ if (currentConfig == null)
+ {
+ MessageBox.Show("Por favor seleccione una configuración!", "Advertencia", MessageBoxButton.OK, MessageBoxImage.Warning);
+ return;
+ }
+
+ try
+ {
+ foreach (var structure in currentConfig.FolderStructures)
+ {
+ var basePath = structure.BasePath.Replace("{year}", DateTime.Now.Year.ToString());
+ var projectPath = Path.Combine(basePath, NewProjectName);
+
+ if (Directory.Exists(projectPath))
+ {
+ MessageBox.Show($"El directorio ya existe: {projectPath}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ return;
+ }
+
+ Directory.CreateDirectory(projectPath);
+
+ foreach (var subfolder in structure.Subfolders)
+ {
+ var subfolderPath = Path.Combine(projectPath, subfolder);
+ Directory.CreateDirectory(subfolderPath);
+ }
+ }
+
+ Process.Start("explorer.exe", Path.Combine(BasePath, NewProjectName));
+ MessageBox.Show("Directorios creados exitosamente!", "Éxito", MessageBoxButton.OK, MessageBoxImage.Information);
+ LoadLastProjectNumber();
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"Error al crear directorios: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Window1.xaml b/Window1.xaml
new file mode 100644
index 0000000..99862ed
--- /dev/null
+++ b/Window1.xaml
@@ -0,0 +1,12 @@
+
+
+
+
+
diff --git a/Window1.xaml.cs b/Window1.xaml.cs
new file mode 100644
index 0000000..ef20a17
--- /dev/null
+++ b/Window1.xaml.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace DirectoryCreator
+{
+ ///
+ /// Interaction logic for Window1.xaml
+ ///
+ public partial class Window1 : Window
+ {
+ public Window1()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/folderConfig.json b/folderConfig.json
new file mode 100644
index 0000000..4925547
--- /dev/null
+++ b/folderConfig.json
@@ -0,0 +1,47 @@
+{
+ "description": "Configuración VM",
+ "basePath": "C:\\Trabajo\\VM",
+ "folderStructures": [
+ {
+ "basePath": "C:\\Trabajo\\VM",
+ "subfolders": [
+ "Documentos y Facturacion",
+ "InLavoro",
+ "InLavoro\\Backups",
+ "InLavoro\\PLC",
+ "InLavoro\\Manual",
+ "InLavoro\\Test",
+ "Entregar",
+ "Entregado por VM",
+ "Reporte",
+ "Simulation"
+ ]
+ },
+ {
+ "basePath": "C:\\Users\\migue\\OneDrive\\Miguel\\CSA - Trabajo\\{year}\\Facturacion\\Teknors",
+ "subfolders": []
+ },
+ {
+ "basePath": "C:\\Users\\migue\\OneDrive\\Miguel\\CSA - Trabajo\\{year}\\Software-Share",
+ "subfolders": []
+ },
+ {
+ "basePath": "C:\\Users\\migue\\OneDrive\\Miguel\\CSA - Trabajo\\{year}\\Videos",
+ "subfolders": []
+ },
+ {
+ "basePath": "C:\\Users\\migue\\OneDrive\\VM REVISAR",
+ "subfolders": []
+ },
+ {
+ "basePath": "C:\\Users\\migue\\OneDrive\\Miguel\\Obsidean\\Trabajo\\VM",
+ "subfolders": [
+ "Reporte"
+ ]
+ },
+ {
+ "basePath": "C:\\Users\\migue\\OneDrive\\Miguel\\CSA - Trabajo\\Software\\VM",
+ "subfolders": []
+ }
+ ]
+}
\ No newline at end of file