📂FolderCreationApp
┣ 📂GUI
┃ ┣ 📜MainWindow.xaml # GUIのレイアウト
┃ ┗ 📜MainWindow.ps1 # GUIのイベント処理
┣ 📂Classes
┃ ┗ 📜FolderCreator.psm1 # フォルダ作成のロジック
┣ 📜App.bat # App.ps1を起動するバッチファイル
┗ 📜App.ps1 # アプリケーションのメインロジック
@echo off
PowerShell -NoProfile -ExecutionPolicy Bypass -File "App.ps1"
# 必要なモジュールの読み込み
Import-Module .\\Classes\\FolderCreator.psm1

# GUIの読み込み
[xml]$xaml = Get-Content '.\\GUI\\MainWindow.xaml'
$reader = (New-Object System.Xml.XmlNodeReader $xaml)
$window = [Windows.Markup.XamlReader]::Load($reader)

# イベントハンドラーの定義
. .\\GUI\\MainWindow.ps1

# イベントハンドラーの割り当て
$window.btnSelectFile.Add_Click({ SelectFile })
$window.btnSelectRootPath.Add_Click({ SelectRootPath })
$window.btnCreateFolders.Add_Click({ CreateFolders })

# メインウィンドウの表示
$window.ShowDialog() | Out-Null
Function ParseTreeStructure($filePath) {
    $treeStructure = @()
    $currentPath = ""
    $lines = Get-Content $filePath

    # ファイルの内容を行ごとに読み込む
    foreach ($line in $lines) {
        # 正規表現でインデントを計算
        $indentMatches = [regex]::Matches($line, "^(\\s*|\\t*|-*)")
        $indentLevel = $indentMatches[0].Value.Length

        # フォルダ名の取得(インデント部分を除去)
        $folderName = $line.TrimStart(" ", "`t", "-")

        # 現在のパスの更新
        $currentPath = $currentPath.Split("\\")[0..$indentLevel] -join "\\"
        $currentPath = Join-Path $currentPath $folderName

        if ($indentLevel -eq 0) {
            $currentPath = $folderName
        }

        $treeStructure += $currentPath
    }

    return $treeStructure | Select-Object -Unique
}

Function CreateFolders($treeStructure, $rootPath) {
    foreach ($nodePath in $treeStructure) {
        # $nodeに基づいてフォルダを作成する
        # フォルダが既に存在するかチェックし、存在しない場合のみ作成
        $fullPath = Join-Path $rootPath $nodePath
        if (-not (Test-Path $fullPath)) {
            New-Item -ItemType Directory -Path $fullPath -Force
        }
    }
}

Export-ModuleMember -Function ParseTreeStructure, CreateFolders
# GUIコンポーネントの読み込み
[xml]$xaml = Get-Content 'MainWindow.xaml'
$reader = (New-Object System.Xml.XmlNodeReader $xaml)
$window = [Windows.Markup.XamlReader]::Load($reader)

# ファイル選択イベント
Function SelectFile {
    # ファイル選択ダイアログの表示とファイルパスの取得
    [System.Windows.Forms.OpenFileDialog]$dialog = New-Object System.Windows.Forms.OpenFileDialog
    if ($dialog.ShowDialog() -eq "OK") {
        $window.txtFilePath.Text = $dialog.FileName
    }
}

# ルートパス選択イベント
Function SelectRootPath {
    # フォルダ選択ダイアログの表示とパスの取得
    $dialog = New-Object System.Windows.Forms.FolderBrowserDialog
    if ($dialog.ShowDialog() -eq "OK") {
        $window.txtRootPath.Text = $dialog.SelectedPath
    }
}

# フォルダ作成イベント
Function CreateFolders {
    # FolderCreatorを使用してフォルダを作成
    $filePath = $window.txtFilePath.Text
    $rootPath = $window.txtRootPath.Text
    $treeStructure = ParseTreeStructure $filePath
    CreateFolders $treeStructure $rootPath
}

# イベントハンドラーの割り当て
$window.btnSelectFile.Add_Click({ SelectFile })
$window.btnSelectRootPath.Add_Click({ SelectRootPath })
$window.btnCreateFolders.Add_Click({ CreateFolders })

# ウィンドウの表示
$window.ShowDialog() | Out-Null
<Window x:Class="FolderCreationApp.MainWindow"
        xmlns="<http://schemas.microsoft.com/winfx/2006/xaml/presentation>"
        xmlns:x="<http://schemas.microsoft.com/winfx/2006/xaml>"
        Title="Folder Creation App" Height="400" Width="525">
    <Grid>
        <Button x:Name="btnSelectFile" Content="ファイル選択" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="100" />
        <TextBox x:Name="txtFilePath" HorizontalAlignment="Left" Height="23" Margin="120,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="380" />

        <Label Content="ルートパス:" HorizontalAlignment="Left" Margin="10,40,0,0" VerticalAlignment="Top" />
        <TextBox x:Name="txtRootPath" HorizontalAlignment="Left" Height="23" Margin="120,40,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="380" />
        <Button x:Name="btnSelectRootPath" Content="選択" HorizontalAlignment="Right" Margin="0,40,10,0" VerticalAlignment="Top" Width="75" />

        <Button x:Name="btnCreateFolders" Content="フォルダ作成" HorizontalAlignment="Left" Margin="10,70,0,0" VerticalAlignment="Top" Width="100" />
        <TextBox x:Name="txtLog" HorizontalAlignment="Left" Margin="10,100,0,0" VerticalAlignment="Top" Width="490" Height="260" TextWrapping="Wrap" VerticalScrollBarVisibility="Auto" AcceptsReturn="True" IsReadOnly="True" />
    </Grid>
</Window>