# 第一部分:初始化和管理员检查 # 添加必要的程序集 Add-Type -AssemblyName PresentationFramework Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName PresentationCore # 检查管理员权限 if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Write-Host "需要管理员权限运行此脚本!" -ForegroundColor Red $result = [System.Windows.MessageBox]::Show("此工具需要管理员权限才能执行分区操作。是否以管理员身份重新启动?", "需要管理员权限", [System.Windows.MessageBoxButton]::YesNo, [System.Windows.MessageBoxImage]::Warning) if ($result -eq 'Yes') { Start-Process PowerShell -Verb RunAs -ArgumentList "-File `"$PSCommandPath`"" } exit } # 第二部分:辅助函数定义 # 函数定义 function ShowDiskPartitionInfo { param($Disk) try { $Partitions = Get-Partition -DiskNumber $Disk.Number -ErrorAction SilentlyContinue $PartitionInfo = "磁盘 $($Disk.Number) 分区信息:`n" $PartitionInfo += "型号: $($Disk.Model)`n" $PartitionInfo += "总容量: $([math]::Round($Disk.Size / 1GB, 2)) GB`n" $PartitionInfo += "分区表: $($Disk.PartitionStyle)`n" $PartitionInfo += "状态: $($Disk.OperationalStatus)`n`n" if ($Partitions) { $PartitionInfo += "现有分区列表:`n" $PartitionInfo += "------------------------`n" foreach ($Partition in $Partitions) { $SizeGB = [math]::Round($Partition.Size / 1GB, 2) $DriveLetter = if ($Partition.DriveLetter) { $Partition.DriveLetter } else { "无" } $Type = $Partition.Type $PartitionInfo += "分区 $($Partition.PartitionNumber):`n" $PartitionInfo += " 盘符: $DriveLetter`n" $PartitionInfo += " 大小: $SizeGB GB`n" $PartitionInfo += " 类型: $Type`n" $PartitionInfo += "------------------------`n" } } else { $PartitionInfo += "无分区或磁盘未初始化" } [System.Windows.MessageBox]::Show($PartitionInfo, "磁盘分区信息", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information) } catch { [System.Windows.MessageBox]::Show("获取分区信息失败: $($_.Exception.Message)", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) } } function DeleteAllPartitions { param($Disk, $StatusText, $RefreshCallback) try { # 获取分区信息用于确认 $Partitions = Get-Partition -DiskNumber $Disk.Number -ErrorAction SilentlyContinue if (-not $Partitions -or $Partitions.Count -eq 0) { [System.Windows.MessageBox]::Show("磁盘 $($Disk.Number) 上没有找到分区。", "信息", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information) return } # 显示分区列表用于确认 $PartitionList = "即将删除以下分区:`n`n" foreach ($Partition in $Partitions) { $SizeGB = [math]::Round($Partition.Size / 1GB, 2) $DriveLetter = if ($Partition.DriveLetter) { $Partition.DriveLetter } else { "无盘符" } $PartitionList += "分区 $($Partition.PartitionNumber) - $DriveLetter - $SizeGB GB`n" } $Result = [System.Windows.MessageBox]::Show( "确定要删除磁盘 $($Disk.Number) 的所有分区吗?`n`n$PartitionList`n此操作将永久删除分区上的所有数据!", "确认删除分区", [System.Windows.MessageBoxButton]::YesNo, [System.Windows.MessageBoxImage]::Warning ) if ($Result -eq 'No') { return } $StatusText.Text = "正在删除所有分区..." $StatusText.Foreground = 'Orange' # 清除磁盘所有分区 Clear-Disk -Number $Disk.Number -RemoveData -RemoveOEM -Confirm:$false -ErrorAction Stop # 等待操作完成 Start-Sleep -Seconds 2 $StatusText.Text = "分区删除完成!磁盘现在为空。" $StatusText.Foreground = 'Green' [System.Windows.MessageBox]::Show("所有分区已成功删除!", "完成", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information) # 执行刷新回调 if ($RefreshCallback) { & $RefreshCallback } } catch { $StatusText.Text = "删除分区失败: $($_.Exception.Message)" $StatusText.Foreground = 'Red' [System.Windows.MessageBox]::Show("删除分区失败: $($_.Exception.Message)", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) } } function ExecuteOtherDiskPartition { param($Disk, $PartitionSizes, $PartitionStyle, $FileSystem, $AllocationUnit, $StatusText, $RefreshCallback) try { $StatusText.Text = "正在准备磁盘..." $StatusText.Foreground = 'Orange' # 强制刷新磁盘信息 $CurrentDisk = $null $retryCount = 0 while (-not $CurrentDisk -and $retryCount -lt 3) { try { $CurrentDisk = Get-Disk -Number $Disk.Number -ErrorAction Stop } catch { $retryCount++ Start-Sleep -Seconds 1 } } if (-not $CurrentDisk) { [System.Windows.MessageBox]::Show("无法访问磁盘 $($Disk.Number),请检查磁盘是否存在或是否被其他程序占用。", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) return } Write-Host "磁盘当前状态: $($CurrentDisk.PartitionStyle), 操作状态: $($CurrentDisk.OperationalStatus)" -ForegroundColor Yellow # 检查并清除现有分区 $Partitions = Get-Partition -DiskNumber $Disk.Number -ErrorAction SilentlyContinue if ($Partitions -and $Partitions.Count -gt 0) { $StatusText.Text = "正在清除磁盘所有分区和数据..." Write-Host "发现 $($Partitions.Count) 个分区,正在清除..." -ForegroundColor Yellow # 使用更彻底的清除方法 Clear-Disk -Number $Disk.Number -RemoveData -RemoveOEM -Confirm:$false -ErrorAction Stop Write-Host "磁盘清除完成" -ForegroundColor Green # 等待磁盘状态更新 Start-Sleep -Seconds 2 } # 重新获取磁盘状态 $CurrentDisk = Get-Disk -Number $Disk.Number -ErrorAction Stop Write-Host "清除后磁盘状态: $($CurrentDisk.PartitionStyle)" -ForegroundColor Yellow # 强制初始化磁盘(无论当前状态如何) $StatusText.Text = "正在初始化磁盘为 $PartitionStyle 格式..." Write-Host "正在初始化磁盘为 $PartitionStyle 格式..." -ForegroundColor Yellow # 如果磁盘已经有分区表但不是我们需要的类型,先清除 if ($CurrentDisk.PartitionStyle -ne "RAW" -and $CurrentDisk.PartitionStyle -ne $PartitionStyle) { Write-Host "磁盘分区表类型不匹配,重新初始化..." -ForegroundColor Yellow Clear-Disk -Number $Disk.Number -RemoveData -RemoveOEM -Confirm:$false -ErrorAction Stop Start-Sleep -Seconds 1 } # 初始化磁盘 if ($CurrentDisk.PartitionStyle -eq "RAW" -or $CurrentDisk.PartitionStyle -ne $PartitionStyle) { Initialize-Disk -Number $Disk.Number -PartitionStyle $PartitionStyle -ErrorAction Stop Write-Host "磁盘初始化完成" -ForegroundColor Green } # 再次等待确保初始化完成 Start-Sleep -Seconds 2 # 验证磁盘初始化状态 $FinalDisk = Get-Disk -Number $Disk.Number -ErrorAction Stop if ($FinalDisk.PartitionStyle -ne $PartitionStyle) { throw "磁盘初始化失败,当前分区表类型: $($FinalDisk.PartitionStyle),期望: $PartitionStyle" } $StatusText.Text = "磁盘已初始化为 $PartitionStyle 格式,正在创建分区..." Write-Host "磁盘初始化验证通过,开始创建分区..." -ForegroundColor Green # 设置分配单元大小 $FormatParams = @{ FileSystem = $FileSystem Confirm = $false } if ($AllocationUnit -ne "默认") { $UnitSize = switch ($AllocationUnit) { "4096 字节 (4K)" { 4096 } "8192 字节 (8K)" { 8192 } "16384 字节 (16K)" { 16384 } "32768 字节 (32K)" { 32768 } "65536 字节 (64K)" { 65536 } default { 4096 } } $FormatParams.AllocationUnitSize = $UnitSize } # 创建分区 $CreatedPartitions = @() $TotalPartitions = $PartitionSizes.Count for ($i = 0; $i -lt $TotalPartitions; $i++) { $PartitionSize = $PartitionSizes[$i] $StatusText.Text = "正在创建分区 $($i+1)/$TotalPartitions..." Write-Host "创建分区 $($i+1)/$TotalPartitions,大小: $PartitionSize GB" -ForegroundColor Cyan if ($PartitionSize -eq 0 -and $i -eq $TotalPartitions - 1) { # 最后一个分区使用剩余空间 $NewPartition = New-Partition -DiskNumber $Disk.Number -UseMaximumSize -AssignDriveLetter -ErrorAction Stop } else { # 指定大小的分区 $SizeInBytes = $PartitionSize * 1GB $NewPartition = New-Partition -DiskNumber $Disk.Number -Size $SizeInBytes -AssignDriveLetter -ErrorAction Stop } if ($NewPartition) { # 等待分区创建完成 Start-Sleep -Seconds 1 # 格式化分区 $StatusText.Text = "正在格式化分区 $($i+1)..." Write-Host "格式化分区,盘符: $($NewPartition.DriveLetter)" -ForegroundColor Cyan $FormatResult = Format-Volume -DriveLetter $NewPartition.DriveLetter @FormatParams -ErrorAction Stop $CreatedPartitions += @{ Number = $i + 1 DriveLetter = $NewPartition.DriveLetter SizeGB = [math]::Round($NewPartition.Size / 1GB, 2) } $StatusText.Text = "分区 $($i+1) 创建完成 (盘符: $($NewPartition.DriveLetter))..." Write-Host "-- 分区 $($i+1) 创建成功,盘符: $($NewPartition.DriveLetter), 大小: $([math]::Round($NewPartition.Size / 1GB, 2)) GB, 文件系统: $FileSystem" -ForegroundColor Green } } # 显示分区结果摘要 $PartitionSummary = "分区操作完成!`n`n创建的分区:`n" foreach ($Part in $CreatedPartitions) { $PartitionSummary += "分区 $($Part.Number): 盘符 $($Part.DriveLetter) - $($Part.SizeGB) GB`n" } $StatusText.Text = "磁盘分区完成!" $StatusText.Foreground = 'Green' [System.Windows.MessageBox]::Show($PartitionSummary, "分区完成", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information) # 执行刷新回调 if ($RefreshCallback) { & $RefreshCallback } } catch { $ErrorMessage = $_.Exception.Message $StatusText.Text = "操作失败: $ErrorMessage" $StatusText.Foreground = 'Red' Write-Host "分区操作失败: $ErrorMessage" -ForegroundColor Red # 提供更详细的错误信息 $DetailedError = "分区操作失败!`n`n错误信息: $ErrorMessage`n`n建议:`n- 检查磁盘是否被其他程序占用`n- 尝试重新启动计算机后重试`n- 检查磁盘硬件状态`n- 确保有足够的管理员权限" [System.Windows.MessageBox]::Show($DetailedError, "分区操作失败", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) } } # 第三部分:其他硬盘分区工具窗口 function CreateOtherDiskPartitionWindow { $OtherDiskWindow = New-Object System.Windows.Window $OtherDiskWindow.Title = "其他硬盘分区工具" $OtherDiskWindow.Height = 380 # 设置初始高度为380 $OtherDiskWindow.Width = 750 $OtherDiskWindow.WindowStartupLocation = 'CenterOwner' $OtherDiskWindow.Owner = $MainWindow $OtherDiskWindow.Topmost = $true $OtherDiskWindow.ResizeMode = 'NoResize' # 创建主网格 $OtherDiskGrid = New-Object System.Windows.Controls.Grid $OtherDiskGrid.Margin = New-Object System.Windows.Thickness(15) # 定义行(减少一行,因为自定义分区改为折叠) for ($i = 0; $i -lt 10; $i++) { $RowDef = New-Object System.Windows.Controls.RowDefinition if ($i -eq 9) { $RowDef.Height = '*' } else { $RowDef.Height = 'Auto' } $OtherDiskGrid.RowDefinitions.Add($RowDef) } # 定义列 $OtherDiskGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '110'})) $OtherDiskGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '*'})) $OtherDiskGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '30'})) # 标题 $TitleLabel = New-Object System.Windows.Controls.Label $TitleLabel.Content = "其他硬盘分区工具" $TitleLabel.FontSize = 16 $TitleLabel.FontWeight = 'Bold' $TitleLabel.HorizontalAlignment = 'Center' $TitleLabel.Margin = '0,0,0,15' $TitleLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 0) $TitleLabel.SetValue([System.Windows.Controls.Grid]::ColumnSpanProperty, 3) $OtherDiskGrid.Children.Add($TitleLabel) # 获取所有磁盘(排除系统磁盘) $SystemDisk = Get-Partition -DriveLetter C | Get-Disk $Disks = Get-Disk | Where-Object { $_.OperationalStatus -eq 'Online' -and $_.Number -ne $SystemDisk.Number } if ($Disks.Count -eq 0) { [System.Windows.MessageBox]::Show("未找到可用的其他硬盘。", "信息", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information) return } # 磁盘选择 $DiskLabel = New-Object System.Windows.Controls.Label $DiskLabel.Content = "选择磁盘:" $DiskLabel.VerticalAlignment = 'Center' $DiskLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 1) $DiskLabel.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) $OtherDiskGrid.Children.Add($DiskLabel) $DiskComboBox = New-Object System.Windows.Controls.ComboBox $DiskComboBox.Name = "DiskComboBox" $DiskComboBox.Margin = '5' $DiskComboBox.Height = 25 $DiskComboBox.VerticalAlignment = 'Center' $DiskComboBox.SetValue([System.Windows.Controls.Grid]::RowProperty, 1) $DiskComboBox.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) foreach ($Disk in $Disks) { $Partitions = Get-Partition -DiskNumber $Disk.Number -ErrorAction SilentlyContinue # 修复分区计数问题 $PartitionCount = if ($Partitions) { @($Partitions).Count } else { 0 } $PartitionStyle = if ($Disk.PartitionStyle -eq "RAW") { "未初始化" } else { $Disk.PartitionStyle } $DiskInfo = "磁盘 $($Disk.Number) - $($Disk.Model) - $([math]::Round($Disk.Size / 1GB, 2)) GB - $PartitionStyle - $PartitionCount 个分区" $DiskComboBox.Items.Add($DiskInfo) | Out-Null } $DiskComboBox.SelectedIndex = 0 $OtherDiskGrid.Children.Add($DiskComboBox) # 分区表类型 $PartitionStyleLabel = New-Object System.Windows.Controls.Label $PartitionStyleLabel.Content = "分区表类型:" $PartitionStyleLabel.VerticalAlignment = 'Center' $PartitionStyleLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 2) $PartitionStyleLabel.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) $OtherDiskGrid.Children.Add($PartitionStyleLabel) $PartitionStyleComboBox = New-Object System.Windows.Controls.ComboBox $PartitionStyleComboBox.Name = "PartitionStyleComboBox" $PartitionStyleComboBox.Margin = '5' $PartitionStyleComboBox.Height = 25 $PartitionStyleComboBox.VerticalAlignment = 'Center' $PartitionStyleComboBox.SetValue([System.Windows.Controls.Grid]::RowProperty, 2) $PartitionStyleComboBox.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) $PartitionStyleComboBox.Items.Add("GPT (GUID 分区表) - 推荐") | Out-Null $PartitionStyleComboBox.Items.Add("MBR (主引导记录)") | Out-Null $PartitionStyleComboBox.SelectedIndex = 0 $OtherDiskGrid.Children.Add($PartitionStyleComboBox) # 文件系统类型 $FileSystemLabel = New-Object System.Windows.Controls.Label $FileSystemLabel.Content = "文件系统:" $FileSystemLabel.VerticalAlignment = 'Center' $FileSystemLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 3) $FileSystemLabel.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) $OtherDiskGrid.Children.Add($FileSystemLabel) $FileSystemComboBox = New-Object System.Windows.Controls.ComboBox $FileSystemComboBox.Name = "FileSystemComboBox" $FileSystemComboBox.Margin = '5' $FileSystemComboBox.Height = 25 $FileSystemComboBox.VerticalAlignment = 'Center' $FileSystemComboBox.SetValue([System.Windows.Controls.Grid]::RowProperty, 3) $FileSystemComboBox.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) $FileSystemComboBox.Items.Add("NTFS (Windows)") | Out-Null $FileSystemComboBox.Items.Add("FAT32 (兼容性)") | Out-Null $FileSystemComboBox.Items.Add("exFAT (大文件支持)") | Out-Null $FileSystemComboBox.SelectedIndex = 0 $OtherDiskGrid.Children.Add($FileSystemComboBox) # 分配单元大小 $AllocationUnitLabel = New-Object System.Windows.Controls.Label $AllocationUnitLabel.Content = "分配单元大小:" $AllocationUnitLabel.VerticalAlignment = 'Center' $AllocationUnitLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 4) $AllocationUnitLabel.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) $OtherDiskGrid.Children.Add($AllocationUnitLabel) $AllocationUnitComboBox = New-Object System.Windows.Controls.ComboBox $AllocationUnitComboBox.Name = "AllocationUnitComboBox" $AllocationUnitComboBox.Margin = '5' $AllocationUnitComboBox.Height = 25 $AllocationUnitComboBox.VerticalAlignment = 'Center' $AllocationUnitComboBox.SetValue([System.Windows.Controls.Grid]::RowProperty, 4) $AllocationUnitComboBox.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) $AllocationUnitComboBox.Items.Add("默认") | Out-Null $AllocationUnitComboBox.Items.Add("4096 字节 (4K)") | Out-Null $AllocationUnitComboBox.Items.Add("8192 字节 (8K)") | Out-Null $AllocationUnitComboBox.Items.Add("16384 字节 (16K)") | Out-Null $AllocationUnitComboBox.Items.Add("32768 字节 (32K)") | Out-Null $AllocationUnitComboBox.Items.Add("65536 字节 (64K)") | Out-Null $AllocationUnitComboBox.SelectedIndex = 0 $OtherDiskGrid.Children.Add($AllocationUnitComboBox) # 分区方案选择 $SchemeLabel = New-Object System.Windows.Controls.Label $SchemeLabel.Content = "分区方案:" $SchemeLabel.VerticalAlignment = 'Center' $SchemeLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 5) $SchemeLabel.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) $OtherDiskGrid.Children.Add($SchemeLabel) $SchemeComboBox = New-Object System.Windows.Controls.ComboBox $SchemeComboBox.Name = "SchemeComboBox" $SchemeComboBox.Margin = '5' $SchemeComboBox.Height = 25 $SchemeComboBox.VerticalAlignment = 'Center' $SchemeComboBox.SetValue([System.Windows.Controls.Grid]::RowProperty, 5) $SchemeComboBox.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) $SchemeComboBox.Items.Add("2个分区 (各50%)") | Out-Null $SchemeComboBox.Items.Add("3个分区 (33% 每个)") | Out-Null $SchemeComboBox.Items.Add("4个分区 (25% 每个)") | Out-Null $SchemeComboBox.Items.Add("单个分区 (使用全部空间)") | Out-Null $SchemeComboBox.Items.Add("自定义分区") | Out-Null $SchemeComboBox.SelectedIndex = 0 $OtherDiskGrid.Children.Add($SchemeComboBox) # 自定义分区大小输入(默认折叠) $CustomPartitionStack = New-Object System.Windows.Controls.StackPanel $CustomPartitionStack.Orientation = 'Vertical' $CustomPartitionStack.Margin = '0,10,0,0' $CustomPartitionStack.Visibility = 'Collapsed' $CustomPartitionStack.SetValue([System.Windows.Controls.Grid]::RowProperty, 6) $CustomPartitionStack.SetValue([System.Windows.Controls.Grid]::ColumnSpanProperty, 3) $OtherDiskGrid.Children.Add($CustomPartitionStack) $CustomLabel = New-Object System.Windows.Controls.Label $CustomLabel.Content = "自定义分区容量 (GB,用逗号分隔):" $CustomLabel.Margin = '0,5,0,5' $CustomPartitionStack.Children.Add($CustomLabel) $CustomTextBox = New-Object System.Windows.Controls.TextBox $CustomTextBox.Name = "CustomTextBox" $CustomTextBox.Margin = '5' $CustomTextBox.Height = 25 $CustomTextBox.VerticalContentAlignment = 'Center' $CustomTextBox.Text = "100,200,MAX" $CustomPartitionStack.Children.Add($CustomTextBox) # 显示方案选择变化 - 修改为自动展开/折叠自定义分区输入 $SchemeComboBox.Add_SelectionChanged({ if ($SchemeComboBox.SelectedIndex -eq 4) { # 选择自定义分区时展开 $CustomPartitionStack.Visibility = 'Visible' $OtherDiskWindow.Height = 465 # 增加窗口高度以显示自定义分区输入 } else { # 选择其他方案时折叠 $CustomPartitionStack.Visibility = 'Collapsed' $OtherDiskWindow.Height = 380 # 恢复初始高度 } }) # 按钮区域 $ButtonStack = New-Object System.Windows.Controls.StackPanel $ButtonStack.Orientation = 'Horizontal' $ButtonStack.HorizontalAlignment = 'Center' $ButtonStack.Margin = '0,20,0,10' $ButtonStack.SetValue([System.Windows.Controls.Grid]::RowProperty, 7) $ButtonStack.SetValue([System.Windows.Controls.Grid]::ColumnSpanProperty, 3) $OtherDiskGrid.Children.Add($ButtonStack) # 查看分区按钮 $DiskInfoButton = New-Object System.Windows.Controls.Button $DiskInfoButton.Content = "查看分区" $DiskInfoButton.Width = 95 $DiskInfoButton.Height = 35 $DiskInfoButton.FontSize = 11 $DiskInfoButton.Background = '#2196F3' $DiskInfoButton.Foreground = 'White' $DiskInfoButton.Margin = '0,0,3,0' $ButtonStack.Children.Add($DiskInfoButton) # 删除分区按钮 $DeletePartitionsButton = New-Object System.Windows.Controls.Button $DeletePartitionsButton.Content = "删除分区" $DeletePartitionsButton.Width = 95 $DeletePartitionsButton.Height = 35 $DeletePartitionsButton.FontSize = 11 $DeletePartitionsButton.Background = '#F44336' $DeletePartitionsButton.Foreground = 'White' $DeletePartitionsButton.Margin = '0,0,3,0' $DeletePartitionsButton.ToolTip = "删除此磁盘的所有分区" $ButtonStack.Children.Add($DeletePartitionsButton) # 刷新磁盘按钮 $RefreshButton = New-Object System.Windows.Controls.Button $RefreshButton.Content = "刷新" $RefreshButton.Width = 95 $RefreshButton.Height = 35 $RefreshButton.FontSize = 11 $RefreshButton.Background = '#FF9800' $RefreshButton.Foreground = 'White' $RefreshButton.Margin = '0,0,3,0' $RefreshButton.ToolTip = "刷新磁盘列表和状态" $ButtonStack.Children.Add($RefreshButton) # 开始分区按钮 $StartButton = New-Object System.Windows.Controls.Button $StartButton.Content = "开始分区" $StartButton.Width = 95 $StartButton.Height = 35 $StartButton.FontSize = 12 $StartButton.Background = '#4CAF50' $StartButton.Foreground = 'White' $StartButton.Margin = '0,0,3,0' $ButtonStack.Children.Add($StartButton) # 显示详细说明按钮 $ToggleInstructionsButton = New-Object System.Windows.Controls.Button $ToggleInstructionsButton.Content = "显示说明" $ToggleInstructionsButton.Width = 95 $ToggleInstructionsButton.Height = 35 $ToggleInstructionsButton.FontSize = 11 $ToggleInstructionsButton.Background = '#607D8B' $ToggleInstructionsButton.Foreground = 'White' $ToggleInstructionsButton.Margin = '0,0,3,0' $ButtonStack.Children.Add($ToggleInstructionsButton) # 取消按钮 $CancelButton = New-Object System.Windows.Controls.Button $CancelButton.Content = "取消" $CancelButton.Width = 95 $CancelButton.Height = 35 $CancelButton.FontSize = 12 $ButtonStack.Children.Add($CancelButton) # 说明区域(默认折叠) $InstructionGrid = New-Object System.Windows.Controls.Grid $InstructionGrid.Margin = '10,5,10,5' $InstructionGrid.Visibility = 'Collapsed' $InstructionGrid.SetValue([System.Windows.Controls.Grid]::RowProperty, 8) $InstructionGrid.SetValue([System.Windows.Controls.Grid]::ColumnSpanProperty, 3) # 创建4列 $InstructionGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '*'})) $InstructionGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '*'})) $InstructionGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '*'})) $InstructionGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '*'})) $OtherDiskGrid.Children.Add($InstructionGrid) # 第一列 - 分区表类型 $Col1Text = New-Object System.Windows.Controls.TextBlock $Col1Text.Text = @" 🔧 分区表类型 GPT (推荐) ✓ 支持>2TB磁盘 ✓ 最多128分区 ✓ 更安全可靠 ✓ 现代标准 MBR (传统) ✓ 兼容性好 ✓ 传统系统支持 ✗ 限4主分区 ✗ 单分区2TB "@ $Col1Text.FontSize = 9 $Col1Text.Foreground = 'Gray' $Col1Text.TextWrapping = 'Wrap' $Col1Text.Margin = '3' $Col1Text.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) $InstructionGrid.Children.Add($Col1Text) # 第二列 - 文件系统 $Col2Text = New-Object System.Windows.Controls.TextBlock $Col2Text.Text = @" 💾 文件系统 NTFS ✓ Windows标准 ✓ 权限管理 ✓ 大文件支持 ✓ 单个文件16TB FAT32 ✓ 兼容性好 ✓ 适合U盘 ✗ 单文件4GB ✗ 无权限管理 exFAT ✓ 跨平台 ✓ 大文件支持 ✓ 移动设备 "@ $Col2Text.FontSize = 9 $Col2Text.Foreground = 'Gray' $Col2Text.TextWrapping = 'Wrap' $Col2Text.Margin = '3' $Col2Text.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) $InstructionGrid.Children.Add($Col2Text) # 第三列 - 分区方案 $Col3Text = New-Object System.Windows.Controls.TextBlock $Col3Text.Text = @" 📊 分区方案 预设方案 • 2分区(各50%) • 3分区(33%每个) • 4分区(25%每个) • 单分区(全部) 自定义分区 格式:100,200,MAX • 数字=固定容量(GB) • MAX=剩余所有空间 • 只能有一个MAX 示例: 100,200,MAX =100GB+200GB+剩余 "@ $Col3Text.FontSize = 9 $Col3Text.Foreground = 'Gray' $Col3Text.TextWrapping = 'Wrap' $Col3Text.Margin = '3' $Col3Text.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 2) $InstructionGrid.Children.Add($Col3Text) # 第四列 - 警告提示 $Col4Text = New-Object System.Windows.Controls.TextBlock $Col4Text.Text = @" ⚠️ 重要警告 数据安全 • 永久删除所有数据 • 操作前备份文件 • 确认目标磁盘 • 谨慎操作谨防数据丢失 操作提示 • 选择正确磁盘 • 勿中断操作 • 等待完成提示 "@ $Col4Text.FontSize = 9 $Col4Text.Foreground = 'Gray' $Col4Text.TextWrapping = 'Wrap' $Col4Text.Margin = '3' $Col4Text.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 3) $InstructionGrid.Children.Add($Col4Text) # 折叠按钮事件 $ToggleInstructionsButton.Add_Click({ if ($InstructionGrid.Visibility -eq 'Visible') { $InstructionGrid.Visibility = 'Collapsed' $ToggleInstructionsButton.Content = "显示说明" if ($CustomPartitionStack.Visibility -eq 'Visible') { $OtherDiskWindow.Height = 465 } else { $OtherDiskWindow.Height = 380 } } else { $InstructionGrid.Visibility = 'Visible' $ToggleInstructionsButton.Content = "隐藏说明" if ($CustomPartitionStack.Visibility -eq 'Visible') { $OtherDiskWindow.Height = 680 } else { $OtherDiskWindow.Height = 600 } } }) # 状态显示 $StatusText = New-Object System.Windows.Controls.TextBlock $StatusText.Name = "StatusText" $StatusText.Text = "选择磁盘和配置分区参数..." $StatusText.FontSize = 10 $StatusText.Foreground = 'Blue' $StatusText.TextWrapping = 'Wrap' $StatusText.Margin = '10,5,10,5' $StatusText.SetValue([System.Windows.Controls.Grid]::RowProperty, 9) $StatusText.SetValue([System.Windows.Controls.Grid]::ColumnSpanProperty, 3) $OtherDiskGrid.Children.Add($StatusText) # 刷新磁盘列表函数 $RefreshDiskList = { $StatusText.Text = "正在刷新磁盘列表..." $StatusText.Foreground = 'Blue' # 保存当前选择的磁盘 $PreviouslySelectedIndex = $DiskComboBox.SelectedIndex $PreviouslySelectedDiskNumber = -1 if ($PreviouslySelectedIndex -ge 0 -and $PreviouslySelectedIndex -lt $Disks.Count) { $PreviouslySelectedDiskNumber = $Disks[$PreviouslySelectedIndex].Number } # 重新获取磁盘列表 $SystemDisk = Get-Partition -DriveLetter C | Get-Disk $script:Disks = Get-Disk | Where-Object { $_.OperationalStatus -eq 'Online' -and $_.Number -ne $SystemDisk.Number } # 清空并重新填充下拉框 $DiskComboBox.Items.Clear() $NewSelectedIndex = -1 foreach ($Disk in $script:Disks) { # 获取过滤后的分区信息(保留无盘符的数据分区) $Partitions = Get-Partition -DiskNumber $Disk.Number -ErrorAction SilentlyContinue | Where-Object { # 保留条件:有盘符的数据分区 或 无盘符但类型是Basic/IFS的分区 ($_.DriveLetter -ne $null -and $_.DriveLetter -ne '' -and $_.DriveLetter -match '[A-Z]') -or (($_.Type -eq 'Basic' -or $_.Type -eq 'IFS') -and ($_.DriveLetter -eq $null -or $_.DriveLetter -eq '')) } $PartitionCount = if ($Partitions) { @($Partitions).Count } else { 0 } $PartitionStyle = if ($Disk.PartitionStyle -eq "RAW") { "未初始化" } else { $Disk.PartitionStyle } # 构建更详细的磁盘信息 $DiskInfo = "磁盘 $($Disk.Number) - $($Disk.Model) - $([math]::Round($Disk.Size / 1GB, 2)) GB - $PartitionStyle - $PartitionCount 个分区" $DiskComboBox.Items.Add($DiskInfo) | Out-Null # 检查是否是之前选择的磁盘 if ($Disk.Number -eq $PreviouslySelectedDiskNumber) { $NewSelectedIndex = $DiskComboBox.Items.Count - 1 } # === 调试信息开始 === Write-Host "=== 调试信息 - 磁盘 $($Disk.Number) ===" -ForegroundColor Yellow Write-Host "磁盘型号: $($Disk.Model)" -ForegroundColor Cyan Write-Host "分区表类型: $($Disk.PartitionStyle)" -ForegroundColor Cyan if ($Partitions) { Write-Host "找到 $($Partitions.Count) 个分区:" -ForegroundColor Green foreach ($Part in $Partitions) { $SizeGB = [math]::Round($Part.Size / 1GB, 2) $DriveLetter = if ($Part.DriveLetter) { $Part.DriveLetter } else { "无" } Write-Host " 分区 $($Part.PartitionNumber): 类型=$($Part.Type), 大小=$SizeGB GB, 盘符=$DriveLetter" -ForegroundColor White } } else { Write-Host "没有找到分区" -ForegroundColor Red } Write-Host "=== 调试信息结束 ===" -ForegroundColor Yellow # === 调试信息结束 === } # 设置选择 if ($NewSelectedIndex -ge 0) { $DiskComboBox.SelectedIndex = $NewSelectedIndex } elseif ($script:Disks.Count -gt 0) { $DiskComboBox.SelectedIndex = 0 } else { $DiskComboBox.SelectedIndex = -1 } # 更新状态显示 $DiskCount = $script:Disks.Count if ($DiskCount -eq 0) { $StatusText.Text = "刷新完成!未找到可用的其他硬盘。" $StatusText.Foreground = 'Orange' } else { $StatusText.Text = "刷新完成!找到 $DiskCount 个可用磁盘。" $StatusText.Foreground = 'Green' # 显示当前选择的磁盘信息(使用过滤后的分区计数) $CurrentIndex = $DiskComboBox.SelectedIndex if ($CurrentIndex -ge 0) { $CurrentDisk = $script:Disks[$CurrentIndex] $Partitions = Get-Partition -DiskNumber $CurrentDisk.Number -ErrorAction SilentlyContinue | Where-Object { ($_.DriveLetter -ne $null -and $_.DriveLetter -ne '' -and $_.DriveLetter -match '[A-Z]') -or (($_.Type -eq 'Basic' -or $_.Type -eq 'IFS') -and ($_.DriveLetter -eq $null -or $_.DriveLetter -eq '')) } $PartitionCount = if ($Partitions) { @($Partitions).Count } else { 0 } $StatusText.Text += " 当前选择: 磁盘 $($CurrentDisk.Number) ($PartitionCount 个分区)" } } Write-Host "刷新完成,找到 $DiskCount 个可用磁盘" -ForegroundColor Green # 如果有磁盘,显示详细信息 if ($DiskCount -gt 0) { Write-Host "可用磁盘列表:" -ForegroundColor Cyan foreach ($Disk in $script:Disks) { $Partitions = Get-Partition -DiskNumber $Disk.Number -ErrorAction SilentlyContinue | Where-Object { ($_.DriveLetter -ne $null -and $_.DriveLetter -ne '' -and $_.DriveLetter -match '[A-Z]') -or (($_.Type -eq 'Basic' -or $_.Type -eq 'IFS') -and ($_.DriveLetter -eq $null -or $_.DriveLetter -eq '')) } $PartitionCount = if ($Partitions) { @($Partitions).Count } else { 0 } Write-Host " 磁盘 $($Disk.Number): $($Disk.Model) - $([math]::Round($Disk.Size / 1GB, 2)) GB - $($Disk.PartitionStyle) - $PartitionCount 个分区" -ForegroundColor White } } } # 刷新按钮事件 $RefreshButton.Add_Click({ & $RefreshDiskList }) # 查看分区信息按钮事件 $DiskInfoButton.Add_Click({ $SelectedDiskIndex = $DiskComboBox.SelectedIndex if ($SelectedDiskIndex -eq -1) { [System.Windows.MessageBox]::Show("请先选择磁盘。", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) return } $SelectedDisk = $Disks[$SelectedDiskIndex] ShowDiskPartitionInfo -Disk $SelectedDisk }) # 删除分区按钮事件 $DeletePartitionsButton.Add_Click({ $SelectedDiskIndex = $DiskComboBox.SelectedIndex if ($SelectedDiskIndex -eq -1) { [System.Windows.MessageBox]::Show("请先选择磁盘。", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) return } $SelectedDisk = $Disks[$SelectedDiskIndex] DeleteAllPartitions -Disk $SelectedDisk -StatusText $StatusText -RefreshCallback $RefreshDiskList }) # 开始分区按钮事件 $StartButton.Add_Click({ $SelectedDiskIndex = $DiskComboBox.SelectedIndex if ($SelectedDiskIndex -eq -1) { [System.Windows.MessageBox]::Show("请选择要分区的磁盘。", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) return } $SelectedDisk = $Disks[$SelectedDiskIndex] $TotalSizeGB = [math]::Round($SelectedDisk.Size / 1GB, 2) # 获取配置参数 $PartitionStyle = if ($PartitionStyleComboBox.SelectedIndex -eq 0) { "GPT" } else { "MBR" } $FileSystem = @("NTFS", "FAT32", "exFAT")[$FileSystemComboBox.SelectedIndex] $AllocationUnit = $AllocationUnitComboBox.SelectedItem # 根据选择的方案计算分区大小 $PartitionSizes = @() $SchemeIndex = $SchemeComboBox.SelectedIndex switch ($SchemeIndex) { 0 { # 2个分区 $Size = [math]::Round($TotalSizeGB / 2) $PartitionSizes = @($Size, 0) } 1 { # 3个分区 $Size = [math]::Round($TotalSizeGB / 3) $PartitionSizes = @($Size, $Size, 0) } 2 { # 4个分区 $Size = [math]::Round($TotalSizeGB / 4) $PartitionSizes = @($Size, $Size, $Size, 0) } 3 { # 单个分区 $PartitionSizes = @(0) } 4 { # 自定义分区 $CustomText = $CustomTextBox.Text.Trim() if ([string]::IsNullOrWhiteSpace($CustomText)) { [System.Windows.MessageBox]::Show("请输入自定义分区容量。", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) return } $SizeStrings = $CustomText.Split(',') $hasRemainingSpaceMarker = $false foreach ($SizeStr in $SizeStrings) { $TrimmedSize = $SizeStr.Trim() if ($TrimmedSize -eq "MAX" -or $TrimmedSize -eq "0") { if ($hasRemainingSpaceMarker) { [System.Windows.MessageBox]::Show("错误:只能有一个分区标记为 MAX(剩余容量)。", "配置错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) return } $PartitionSizes += 0 $hasRemainingSpaceMarker = $true } else { $SizeInt = 0 if ([int]::TryParse($TrimmedSize, [ref]$SizeInt) -and $SizeInt -gt 0) { $PartitionSizes += $SizeInt } else { [System.Windows.MessageBox]::Show("分区容量必须是正整数或'MAX'。", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) return } } } } } # 确认对话框 $PartitionSummary = "磁盘: $($SelectedDisk.Model)`n" $PartitionSummary += "总容量: $TotalSizeGB GB`n" $PartitionSummary += "分区表: $PartitionStyle`n" $PartitionSummary += "文件系统: $FileSystem`n" $PartitionSummary += "分配单元: $AllocationUnit`n" $PartitionSummary += "分区方案: $($SchemeComboBox.SelectedItem)`n" $PartitionSummary += "分区数量: $($PartitionSizes.Count)`n" for ($i = 0; $i -lt $PartitionSizes.Count; $i++) { if ($PartitionSizes[$i] -gt 0) { $PartitionSummary += "分区 $($i+1): $($PartitionSizes[$i]) GB`n" } else { $PartitionSummary += "分区 $($i+1): MAX (所有剩余容量)`n" } } $Result = [System.Windows.MessageBox]::Show( "确定要对磁盘 $($SelectedDisk.Number) 执行分区操作吗?`n`n$PartitionSummary`n`n此操作将永久删除磁盘上的所有数据!", "确认分区操作", [System.Windows.MessageBoxButton]::YesNo, [System.Windows.MessageBoxImage]::Warning ) if ($Result -eq 'No') { return } # 执行分区操作,完成后自动刷新 ExecuteOtherDiskPartition -Disk $SelectedDisk -PartitionSizes $PartitionSizes -PartitionStyle $PartitionStyle -FileSystem $FileSystem -AllocationUnit $AllocationUnit -StatusText $StatusText -RefreshCallback $RefreshDiskList }) # 初始化时自动刷新一次 & $RefreshDiskList $CancelButton.Add_Click({ $OtherDiskWindow.Close() }) $OtherDiskWindow.Content = $OtherDiskGrid $OtherDiskWindow.ShowDialog() | Out-Null } # 第四部分:C盘分区工具相关函数 function CreateCPartitionWindow { $PartitionWindow = New-Object System.Windows.Window $PartitionWindow.Title = "系统盘分区工具" $PartitionWindow.Height = 355 # 初始高度降低 $PartitionWindow.Width = 600 $PartitionWindow.WindowStartupLocation = 'CenterOwner' $PartitionWindow.Owner = $MainWindow $PartitionWindow.Topmost = $true $PartitionWindow.ResizeMode = 'NoResize' # 创建主网格 $PartitionGrid = New-Object System.Windows.Controls.Grid $PartitionGrid.Margin = New-Object System.Windows.Thickness(15) # 定义行(增加一行用于折叠说明) for ($i = 0; $i -lt 10; $i++) { $RowDef = New-Object System.Windows.Controls.RowDefinition if ($i -eq 9) { $RowDef.Height = '*' } else { $RowDef.Height = 'Auto' } $PartitionGrid.RowDefinitions.Add($RowDef) } # 定义列 $PartitionGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '150'})) $PartitionGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '*'})) $PartitionGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '30'})) # 标题 $TitleLabel = New-Object System.Windows.Controls.Label $TitleLabel.Content = "系统盘分区设置" $TitleLabel.FontSize = 16 $TitleLabel.FontWeight = 'Bold' $TitleLabel.HorizontalAlignment = 'Center' $TitleLabel.Margin = '0,0,0,15' $TitleLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 0) $TitleLabel.SetValue([System.Windows.Controls.Grid]::ColumnSpanProperty, 3) $PartitionGrid.Children.Add($TitleLabel) # 当前C盘大小显示 $CurrentSizeLabel = New-Object System.Windows.Controls.Label $CVolume = Get-Volume -DriveLetter C $CurrentSizeGB = [math]::Round($CVolume.Size / 1GB, 2) $CurrentSizeLabel.Content = "当前系统盘大小:" $CurrentSizeLabel.VerticalAlignment = 'Center' $CurrentSizeLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 1) $CurrentSizeLabel.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) $PartitionGrid.Children.Add($CurrentSizeLabel) $CurrentSizeValue = New-Object System.Windows.Controls.Label $CurrentSizeValue.Content = "$CurrentSizeGB GB" $CurrentSizeValue.FontWeight = 'Bold' $CurrentSizeValue.Foreground = 'Green' $CurrentSizeValue.VerticalAlignment = 'Center' $CurrentSizeValue.SetValue([System.Windows.Controls.Grid]::RowProperty, 1) $CurrentSizeValue.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) $PartitionGrid.Children.Add($CurrentSizeValue) # 压缩C盘大小输入 $ShrinkLabel = New-Object System.Windows.Controls.Label $ShrinkLabel.Content = "压缩系统盘到 (GB):" $ShrinkLabel.VerticalAlignment = 'Center' $ShrinkLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 2) $ShrinkLabel.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) $PartitionGrid.Children.Add($ShrinkLabel) $ShrinkTextBox = New-Object System.Windows.Controls.TextBox $ShrinkTextBox.Name = "ShrinkSize" $ShrinkTextBox.Margin = '5' $ShrinkTextBox.Height = 25 $ShrinkTextBox.VerticalAlignment = 'Center' $ShrinkTextBox.VerticalContentAlignment = 'Center' # 添加这行 $ShrinkTextBox.SetValue([System.Windows.Controls.Grid]::RowProperty, 2) $ShrinkTextBox.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) $PartitionGrid.Children.Add($ShrinkTextBox) # 第一个新分区大小输入 $NewPartLabel1 = New-Object System.Windows.Controls.Label $NewPartLabel1.Content = "第一个新分区大小 (GB):" $NewPartLabel1.VerticalAlignment = 'Center' $NewPartLabel1.SetValue([System.Windows.Controls.Grid]::RowProperty, 3) $NewPartLabel1.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) $PartitionGrid.Children.Add($NewPartLabel1) $NewPartTextBox1 = New-Object System.Windows.Controls.TextBox $NewPartTextBox1.Name = "NewPartitionSize1" $NewPartTextBox1.Margin = '5' $NewPartTextBox1.Height = 25 $NewPartTextBox1.VerticalAlignment = 'Center' $NewPartTextBox1.VerticalContentAlignment = 'Center' # 添加这行 $NewPartTextBox1.SetValue([System.Windows.Controls.Grid]::RowProperty, 3) $NewPartTextBox1.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) $PartitionGrid.Children.Add($NewPartTextBox1) # 第二个新分区大小输入 $NewPartLabel2 = New-Object System.Windows.Controls.Label $NewPartLabel2.Content = "第二个新分区大小 (GB):" $NewPartLabel2.VerticalAlignment = 'Center' $NewPartLabel2.SetValue([System.Windows.Controls.Grid]::RowProperty, 4) $NewPartLabel2.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) $PartitionGrid.Children.Add($NewPartLabel2) $NewPartTextBox2 = New-Object System.Windows.Controls.TextBox $NewPartTextBox2.Name = "NewPartitionSize2" $NewPartTextBox2.Margin = '5' $NewPartTextBox2.Height = 25 $NewPartTextBox2.VerticalAlignment = 'Center' $NewPartTextBox2.VerticalContentAlignment = 'Center' # 添加这行 $NewPartTextBox2.SetValue([System.Windows.Controls.Grid]::RowProperty, 4) $NewPartTextBox2.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) $PartitionGrid.Children.Add($NewPartTextBox2) # 计算可用空间显示 $AvailableSpaceLabel = New-Object System.Windows.Controls.Label $AvailableSpaceLabel.Content = "剩余可用空间:" $AvailableSpaceLabel.VerticalAlignment = 'Center' $AvailableSpaceLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 5) $AvailableSpaceLabel.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) $PartitionGrid.Children.Add($AvailableSpaceLabel) $AvailableSpaceValue = New-Object System.Windows.Controls.Label $AvailableSpaceValue.Name = "AvailableSpaceValue" $AvailableSpaceValue.Content = "0 GB" $AvailableSpaceValue.FontWeight = 'Bold' $AvailableSpaceValue.Foreground = 'Blue' $AvailableSpaceValue.VerticalAlignment = 'Center' $AvailableSpaceValue.SetValue([System.Windows.Controls.Grid]::RowProperty, 5) $AvailableSpaceValue.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) $PartitionGrid.Children.Add($AvailableSpaceValue) # 按钮区域 $ButtonStack = New-Object System.Windows.Controls.StackPanel $ButtonStack.Orientation = 'Horizontal' $ButtonStack.HorizontalAlignment = 'Center' $ButtonStack.Margin = '0,20,0,10' $ButtonStack.SetValue([System.Windows.Controls.Grid]::RowProperty, 6) $ButtonStack.SetValue([System.Windows.Controls.Grid]::ColumnSpanProperty, 3) $PartitionGrid.Children.Add($ButtonStack) $StartButton = New-Object System.Windows.Controls.Button $StartButton.Content = "开始分区" $StartButton.Width = 100 $StartButton.Height = 35 $StartButton.FontSize = 12 $StartButton.Background = '#4CAF50' $StartButton.Foreground = 'White' $StartButton.Margin = '0,0,10,0' $ButtonStack.Children.Add($StartButton) # 显示说明按钮 $ToggleInstructionsButton = New-Object System.Windows.Controls.Button $ToggleInstructionsButton.Content = "显示说明" $ToggleInstructionsButton.Width = 100 $ToggleInstructionsButton.Height = 35 $ToggleInstructionsButton.FontSize = 12 $ToggleInstructionsButton.Background = '#607D8B' $ToggleInstructionsButton.Foreground = 'White' $ToggleInstructionsButton.Margin = '0,0,10,0' $ButtonStack.Children.Add($ToggleInstructionsButton) $CancelButton = New-Object System.Windows.Controls.Button $CancelButton.Content = "取消" $CancelButton.Width = 100 $CancelButton.Height = 35 $CancelButton.FontSize = 12 $ButtonStack.Children.Add($CancelButton) $InstructionGrid = New-Object System.Windows.Controls.Grid $InstructionGrid.Margin = '10,5,10,5' $InstructionGrid.Visibility = 'Collapsed' $InstructionGrid.SetValue([System.Windows.Controls.Grid]::RowProperty, 7) $InstructionGrid.SetValue([System.Windows.Controls.Grid]::ColumnSpanProperty, 3) # 创建3列 $InstructionGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '*'})) $InstructionGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '*'})) $InstructionGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '*'})) $PartitionGrid.Children.Add($InstructionGrid) # 第一列 - 功能说明 $Col1Text = New-Object System.Windows.Controls.TextBlock $Col1Text.Text = @" 📋 功能说明 • 压缩C盘释放空间 • 创建1-3个新分区 • 自动分配盘符 • 自动格式化 ⚙️ 参数设置 - 必须小于当前大小 - 最少保留50GB+系统空间 - 输入正整数(GB) - 留空表示不创建 - 剩余空间自动分区 "@ $Col1Text.FontSize = 10 $Col1Text.Foreground = 'Gray' $Col1Text.TextWrapping = 'Wrap' $Col1Text.Margin = '5' $Col1Text.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) $InstructionGrid.Children.Add($Col1Text) # 第二列 - 注意事项 $Col2Text = New-Object System.Windows.Controls.TextBlock $Col2Text.Text = @" 🛡️ 注意事项 • 谨慎操作防止数据丢失 • 确保足够可用空间 • 操作期间勿断电 • 关闭运行的程序 📊 示例演示 当前C盘:930GB 压缩到:200GB → 释放730GB空间 - C区:200GB - D区:730GB (自动) "@ $Col2Text.FontSize = 10 $Col2Text.Foreground = 'Gray' $Col2Text.TextWrapping = 'Wrap' $Col2Text.Margin = '5' $Col2Text.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) $InstructionGrid.Children.Add($Col2Text) # 第三列 - 操作提示 $Col3Text = New-Object System.Windows.Controls.TextBlock $Col3Text.Text = @" 🎯 操作提示 1. 输入压缩后大小 2. 设置新分区大小 3. 点击开始分区 4. 等待操作完成 ✅ 完成检查 • 查看新盘符 • 验证分区大小 • 脚本执行完毕请检查 "@ $Col3Text.FontSize = 10 $Col3Text.Foreground = 'Gray' $Col3Text.TextWrapping = 'Wrap' $Col3Text.Margin = '5' $Col3Text.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 2) $InstructionGrid.Children.Add($Col3Text) # 折叠按钮事件 $ToggleInstructionsButton.Add_Click({ if ($InstructionGrid.Visibility -eq 'Visible') { $InstructionGrid.Visibility = 'Collapsed' $ToggleInstructionsButton.Content = "显示说明" $PartitionWindow.Height = 355 } else { $InstructionGrid.Visibility = 'Visible' $ToggleInstructionsButton.Content = "隐藏说明" $PartitionWindow.Height = 530 } }) # 状态显示 $StatusText = New-Object System.Windows.Controls.TextBlock $StatusText.Name = "StatusText" $StatusText.Text = "等待操作..." $StatusText.FontSize = 10 $StatusText.Foreground = 'Blue' $StatusText.TextWrapping = 'Wrap' $StatusText.Margin = '10,5,10,5' $StatusText.SetValue([System.Windows.Controls.Grid]::RowProperty, 8) $StatusText.SetValue([System.Windows.Controls.Grid]::ColumnSpanProperty, 3) $PartitionGrid.Children.Add($StatusText) # 实时计算可用空间的函数 $CalculateAvailableSpace = { $ShrinkSizeText = $ShrinkTextBox.Text $NewPart1Text = $NewPartTextBox1.Text $NewPart2Text = $NewPartTextBox2.Text $CVolume = Get-Volume -DriveLetter C $CurrentSizeGB = [math]::Round($CVolume.Size / 1GB, 2) if ([string]::IsNullOrWhiteSpace($ShrinkSizeText)) { $AvailableSpaceValue.Content = "$CurrentSizeGB GB" return } $ShrinkSizeInt = 0 if ([int]::TryParse($ShrinkSizeText, [ref]$ShrinkSizeInt)) { $AvailableSpace = $CurrentSizeGB - $ShrinkSizeInt $NewPart1Int = 0 if (-not [string]::IsNullOrWhiteSpace($NewPart1Text)) { [int]::TryParse($NewPart1Text, [ref]$NewPart1Int) } $NewPart2Int = 0 if (-not [string]::IsNullOrWhiteSpace($NewPart2Text)) { [int]::TryParse($NewPart2Text, [ref]$NewPart2Int) } $RemainingSpace = $AvailableSpace - $NewPart1Int - $NewPart2Int $AvailableSpaceValue.Content = "$AvailableSpace GB (剩余: $RemainingSpace GB)" if ($RemainingSpace -lt 0) { $AvailableSpaceValue.Foreground = 'Red' } else { $AvailableSpaceValue.Foreground = 'Blue' } } } # 添加文本框变化事件 $ShrinkTextBox.Add_TextChanged({ & $CalculateAvailableSpace }) $NewPartTextBox1.Add_TextChanged({ & $CalculateAvailableSpace }) $NewPartTextBox2.Add_TextChanged({ & $CalculateAvailableSpace }) # 初始化可用空间显示 & $CalculateAvailableSpace # 按钮事件处理 $StartButton.Add_Click({ $ShrinkSize = $ShrinkTextBox.Text.Trim() $NewPartitionSize1 = $NewPartTextBox1.Text.Trim() $NewPartitionSize2 = $NewPartTextBox2.Text.Trim() # 验证输入 if (-not (ValidateCInput -ShrinkSize $ShrinkSize -NewPartitionSize1 $NewPartitionSize1 -NewPartitionSize2 $NewPartitionSize2 -StatusText $StatusText)) { return } # 确认对话框 $PartitionSummary = "压缩系统盘到: $script:ShrinkSizeInt GB`n" if ($script:NewPartitionSize1Int -gt 0) { $PartitionSummary += "第一个新分区: $script:NewPartitionSize1Int GB`n" } if ($script:NewPartitionSize2Int -gt 0) { $PartitionSummary += "第二个新分区: $script:NewPartitionSize2Int GB`n" } $RemainingSpace = ($CurrentSizeGB - $script:ShrinkSizeInt) - $script:NewPartitionSize1Int - $script:NewPartitionSize2Int if ($RemainingSpace -gt 0) { $PartitionSummary += "剩余空间分区: $RemainingSpace GB`n" } $Result = [System.Windows.MessageBox]::Show( "确定要执行分区操作吗?`n`n$PartitionSummary`n此操作可能需要几分钟时间,请勿中断!", "确认分区操作", [System.Windows.MessageBoxButton]::YesNo, [System.Windows.MessageBoxImage]::Warning ) if ($Result -eq 'No') { return } # 禁用按钮防止重复点击 $StartButton.IsEnabled = $false $CancelButton.IsEnabled = $false $ToggleInstructionsButton.IsEnabled = $false $StatusText.Text = "正在执行分区操作,请稍候..." $StatusText.Foreground = 'Orange' # 执行分区操作 ExecuteCPartitionOperation -ShrinkSizeInt $script:ShrinkSizeInt -NewPartitionSize1Int $script:NewPartitionSize1Int -NewPartitionSize2Int $script:NewPartitionSize2Int -StatusText $StatusText -StartButton $StartButton -CancelButton $CancelButton -ToggleButton $ToggleInstructionsButton }) $CancelButton.Add_Click({ $PartitionWindow.Close() }) $PartitionWindow.Content = $PartitionGrid $PartitionWindow.ShowDialog() | Out-Null } function ValidateCInput { param($ShrinkSize, $NewPartitionSize1, $NewPartitionSize2, $StatusText) # 验证压缩大小 if ([string]::IsNullOrWhiteSpace($ShrinkSize)) { $StatusText.Text = "错误:请输入压缩大小" $StatusText.Foreground = 'Red' return $false } $script:ShrinkSizeInt = 0 if (-not ([int]::TryParse($ShrinkSize, [ref]$script:ShrinkSizeInt)) -or $script:ShrinkSizeInt -le 0) { $StatusText.Text = "错误:压缩大小必须是正整数" $StatusText.Foreground = 'Red' return $false } # 获取当前C盘大小 $CVolume = Get-Volume -DriveLetter C $CurrentSizeGB = [math]::Round($CVolume.Size / 1GB, 2) if ($script:ShrinkSizeInt -ge $CurrentSizeGB) { $StatusText.Text = "错误:压缩大小必须小于当前系统盘大小 ($CurrentSizeGB GB)" $StatusText.Foreground = 'Red' return $false } # 验证第一个新分区大小(可选) $script:NewPartitionSize1Int = 0 if (-not [string]::IsNullOrWhiteSpace($NewPartitionSize1)) { if (-not ([int]::TryParse($NewPartitionSize1, [ref]$script:NewPartitionSize1Int)) -or $script:NewPartitionSize1Int -le 0) { $StatusText.Text = "错误:第一个新分区大小必须是正整数" $StatusText.Foreground = 'Red' return $false } } # 验证第二个新分区大小(可选) $script:NewPartitionSize2Int = 0 if (-not [string]::IsNullOrWhiteSpace($NewPartitionSize2)) { if (-not ([int]::TryParse($NewPartitionSize2, [ref]$script:NewPartitionSize2Int)) -or $script:NewPartitionSize2Int -le 0) { $StatusText.Text = "错误:第二个新分区大小必须是正整数" $StatusText.Foreground = 'Red' return $false } } # 检查总分区大小是否合理 $TotalNewPartitionSize = $script:NewPartitionSize1Int + $script:NewPartitionSize2Int $AvailableSize = $CurrentSizeGB - $script:ShrinkSizeInt if ($TotalNewPartitionSize -gt $AvailableSize) { $StatusText.Text = "错误:新分区总大小 ($TotalNewPartitionSize GB) 不能大于可用空间 ($AvailableSize GB)" $StatusText.Foreground = 'Red' return $false } $StatusText.Text = "输入验证通过,准备执行分区操作..." $StatusText.Foreground = 'Green' return $true } function ExecuteCPartitionOperation { param($ShrinkSizeInt, $NewPartitionSize1Int, $NewPartitionSize2Int, $StatusText, $StartButton, $CancelButton, $ToggleButton) try { $StatusText.Text = "正在调整分区大小..." $StatusText.Foreground = 'Orange' # 获取磁盘信息 $Disk = Get-Partition -DriveLetter C | Get-Disk $DiskNumber = $Disk.Number # 调整分区大小 Resize-Partition -DriveLetter C -Size ($ShrinkSizeInt * 1GB) -ErrorAction Stop $StatusText.Text = "分区调整完成,正在创建新分区..." # 获取调整后的C盘大小 $CVolume = Get-Volume -DriveLetter C $NewCSizeGB = [math]::Round($CVolume.Size / 1GB, 2) # 创建第一个新分区(如果需要) if ($NewPartitionSize1Int -gt 0) { $NewPartition1 = New-Partition -DiskNumber $DiskNumber -Size ($NewPartitionSize1Int * 1GB) -AssignDriveLetter -ErrorAction Stop if ($NewPartition1) { Format-Volume -DriveLetter $NewPartition1.DriveLetter -FileSystem NTFS -Confirm:$false -ErrorAction Stop $StatusText.Text = "第一个新分区创建完成,正在创建第二个新分区..." Write-Host "-- 第一个新分区创建成功,盘符: $($NewPartition1.DriveLetter)" -ForegroundColor Green } } # 创建第二个新分区(如果需要) if ($NewPartitionSize2Int -gt 0) { $NewPartition2 = New-Partition -DiskNumber $DiskNumber -Size ($NewPartitionSize2Int * 1GB) -AssignDriveLetter -ErrorAction Stop if ($NewPartition2) { Format-Volume -DriveLetter $NewPartition2.DriveLetter -FileSystem NTFS -Confirm:$false -ErrorAction Stop $StatusText.Text = "第二个新分区创建完成,正在处理剩余空间..." Write-Host "-- 第二个新分区创建成功,盘符: $($NewPartition2.DriveLetter)" -ForegroundColor Green } } # 处理剩余空间 $RemainingSize = (Get-Disk -Number $DiskNumber).Size - (Get-Disk -Number $DiskNumber).AllocatedSize if ($RemainingSize -gt 1GB) { $RemainingPartition = New-Partition -DiskNumber $DiskNumber -UseMaximumSize -AssignDriveLetter -ErrorAction Stop if ($RemainingPartition) { Format-Volume -DriveLetter $RemainingPartition.DriveLetter -FileSystem NTFS -Confirm:$false -ErrorAction Stop $StatusText.Text = "剩余空间分区创建完成" Write-Host "-- 剩余空间分区创建成功,盘符: $($RemainingPartition.DriveLetter)" -ForegroundColor Green } } $StatusText.Text = "分区操作完成!" $StatusText.Foreground = 'Green' [System.Windows.MessageBox]::Show("分区操作已完成!", "完成", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information) } catch { $StatusText.Text = "操作失败: $($_.Exception.Message)" $StatusText.Foreground = 'Red' [System.Windows.MessageBox]::Show("分区操作失败: $($_.Exception.Message)", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) } finally { # 重新启用按钮 $StartButton.IsEnabled = $true $CancelButton.IsEnabled = $true if ($ToggleButton) { $ToggleButton.IsEnabled = $true } } } # 第五部分:盘符理顺相关函数 function ReassignDriveLettersWithUI { $Result = [System.Windows.MessageBox]::Show( "确定要重新分配盘符吗?`n`n此操作将:`n- 保持系统盘符不变`n- 重新分配其他盘符`n- 按磁盘和分区顺序整理盘符", "确认盘符理顺", [System.Windows.MessageBoxButton]::YesNo, [System.Windows.MessageBoxImage]::Question ) if ($Result -eq 'Yes') { # 直接执行盘符理顺操作 try { Write-Host "-- 开始重新分配盘符..." -ForegroundColor Yellow # 获取系统盘符 $systemDriveLetter = (Get-WmiObject -Class Win32_OperatingSystem).SystemDrive.Replace(":", "").Trim() # 获取系统磁盘索引 $systemDiskIndex = (Get-Partition -DriveLetter $systemDriveLetter).DiskNumber # 预定义可用的盘符列表 $driveLetters = @('D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z') # 获取所有有效卷的信息 $volumes = Get-Volume | Where-Object { $_.DriveLetter -ne $null -and $_.DriveLetter -match '[A-Z]' -and $_.HealthStatus -eq 'Healthy' } # 获取所有卷的分区信息并记录 $partitions = @{} foreach ($volume in $volumes) { $partition = Get-Partition -DriveLetter $volume.DriveLetter $partitions[$volume.DriveLetter] = @{ 'DiskNumber' = $partition.DiskNumber 'PartitionNumber' = $partition.PartitionNumber } } # 获取系统磁盘上的卷和其他磁盘上的卷,并按PartitionNumber排序 $volumesOnSystemDisk = $volumes | Where-Object { $partitions[$_.DriveLetter]['DiskNumber'] -eq $systemDiskIndex } | Sort-Object -Property {$partitions[$_.DriveLetter]['PartitionNumber']} $volumesOnOtherDisks = $volumes | Where-Object { $partitions[$_.DriveLetter]['DiskNumber'] -ne $systemDiskIndex } | Sort-Object -Property {$partitions[$_.DriveLetter]['DiskNumber']}, {$partitions[$_.DriveLetter]['PartitionNumber']} # 打印所有有效卷的信息 Write-Host "-- 所有有效卷的信息:" $volumes | Format-Table -Property DriveLetter, DriveType, FileSystemLabel, HealthStatus Write-Host "-- 系统盘 $systemDriveLetter 不会更改或删除盘符" # 删除非系统盘的盘符 foreach ($volume in $volumes) { if ($volume.DriveLetter -eq $systemDriveLetter) { continue } try { $partitionInfo = $partitions[$volume.DriveLetter] Remove-PartitionAccessPath -DiskNumber $partitionInfo.DiskNumber -PartitionNumber $partitionInfo.PartitionNumber -AccessPath ($volume.DriveLetter + ":") -ErrorAction Stop Write-Host "-- 成功删除卷 $($volume.DriveLetter) 的盘符" } catch { Write-Warning "-- 无法删除卷 $($volume.DriveLetter) 的盘符: $($_.Exception.Message)" -ForegroundColor Red } } # 重新分配盘符 $index = 0 $availableDriveLetters = $driveLetters | Where-Object { $_ -notin @($systemDriveLetter) } # 先处理系统磁盘上的卷 foreach ($volume in $volumesOnSystemDisk) { if ($volume.DriveLetter -eq $systemDriveLetter) { continue } if ($index -lt $availableDriveLetters.Length) { $newLetter = $availableDriveLetters[$index] try { $partitionInfo = $partitions[$volume.DriveLetter] Add-PartitionAccessPath -DiskNumber $partitionInfo.DiskNumber -PartitionNumber $partitionInfo.PartitionNumber -AccessPath ($newLetter + ":") -ErrorAction Stop Write-Host "-- 成功将系统磁盘上的卷 $($volume.DriveLetter) 更改为盘符 $newLetter" -ForegroundColor Green } catch { Write-Warning "-- 无法更改系统磁盘上的卷 $($volume.DriveLetter) 的盘符: $($_.Exception.Message)" -ForegroundColor Red } $index++ } else { Write-Warning "-- 没有足够的可用盘符" -ForegroundColor Red } } # 再处理其他磁盘上的卷,按正确顺序分配盘符 foreach ($volume in $volumesOnOtherDisks) { if ($index -lt $availableDriveLetters.Length) { $newLetter = $availableDriveLetters[$index] try { $partitionInfo = $partitions[$volume.DriveLetter] Add-PartitionAccessPath -DiskNumber $partitionInfo.DiskNumber -PartitionNumber $partitionInfo.PartitionNumber -AccessPath ($newLetter + ":") -ErrorAction Stop Write-Host "-- 成功将其他磁盘上的卷 $($volume.DriveLetter) 更改为盘符 $newLetter" -ForegroundColor Yellow } catch { Write-Warning "-- 无法更改其他磁盘上的卷 $($volume.DriveLetter) 的盘符: $($_.Exception.Message)" -ForegroundColor Red } $index++ } else { Write-Warning "-- 没有足够的可用盘符" -ForegroundColor Red } } Write-Host "-- 盘符重新分配完成。" -ForegroundColor Green [System.Windows.MessageBox]::Show("盘符理顺操作已完成!", "完成", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information) } catch { Write-Host "-- 盘符重新分配时出错: $($_.Exception.Message)" -ForegroundColor Red [System.Windows.MessageBox]::Show("盘符理顺操作失败:$($_.Exception.Message)", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) } } } function ReassignDriveLetters { Write-Host "-- 开始重新分配盘符..." -ForegroundColor Yellow try { $SystemDriveLetter = (Get-WmiObject -Class Win32_OperatingSystem).SystemDrive.Replace(":", "").Trim() Write-Host "-- 系统盘符: $SystemDriveLetter" -ForegroundColor Green # 获取所有磁盘和分区 $Disks = Get-Disk | Where-Object { $_.OperationalStatus -eq 'Online' } foreach ($Disk in $Disks) { $Partitions = Get-Partition -DiskNumber $Disk.Number -ErrorAction SilentlyContinue $PartitionCount = if ($Partitions -and $Partitions.Count -gt 0) { $Partitions.Count } else { 0 } $PartitionStyle = if ($Disk.PartitionStyle -eq "RAW") { "未初始化" } else { $Disk.PartitionStyle } $DiskInfo = "磁盘 $($Disk.Number) - $($Disk.Model) - $([math]::Round($Disk.Size / 1GB, 2)) GB - $PartitionStyle - $PartitionCount 个分区" Write-Host "-- $DiskInfo" -ForegroundColor Cyan } Write-Host "-- 盘符重新分配完成。" -ForegroundColor Green } catch { Write-Host "-- 盘符重新分配时出错: $($_.Exception.Message)" -ForegroundColor Red } } # 保留原始函数供其他部分使用 function ReassignDriveLetters { Write-Host "-- 开始重新分配盘符..." -ForegroundColor Yellow # 获取系统盘符 $systemDriveLetter = (Get-WmiObject -Class Win32_OperatingSystem).SystemDrive.Replace(":", "").Trim() # 获取系统磁盘索引 $systemDiskIndex = (Get-Partition -DriveLetter $systemDriveLetter).DiskNumber # 预定义可用的盘符列表 $driveLetters = @('D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z') # 获取所有有效卷的信息 $volumes = Get-Volume | Where-Object { $_.DriveLetter -ne $null -and $_.DriveLetter -match '[A-Z]' -and $_.HealthStatus -eq 'Healthy' } # 获取所有卷的分区信息并记录 $partitions = @{} foreach ($volume in $volumes) { $partition = Get-Partition -DriveLetter $volume.DriveLetter $partitions[$volume.DriveLetter] = @{ 'DiskNumber' = $partition.DiskNumber 'PartitionNumber' = $partition.PartitionNumber } } # 获取系统磁盘上的卷和其他磁盘上的卷,并按PartitionNumber排序 $volumesOnSystemDisk = $volumes | Where-Object { $partitions[$_.DriveLetter]['DiskNumber'] -eq $systemDiskIndex } | Sort-Object -Property {$partitions[$_.DriveLetter]['PartitionNumber']} $volumesOnOtherDisks = $volumes | Where-Object { $partitions[$_.DriveLetter]['DiskNumber'] -ne $systemDiskIndex } | Sort-Object -Property {$partitions[$_.DriveLetter]['DiskNumber']}, {$partitions[$_.DriveLetter]['PartitionNumber']} # 打印所有有效卷的信息 Write-Host "-- 所有有效卷的信息:" $volumes | Format-Table -Property DriveLetter, DriveType, FileSystemLabel, HealthStatus Write-Host "-- 系统盘 $systemDriveLetter 不会更改或删除盘符" # 删除非系统盘的盘符 foreach ($volume in $volumes) { if ($volume.DriveLetter -eq $systemDriveLetter) { continue } try { $partitionInfo = $partitions[$volume.DriveLetter] Remove-PartitionAccessPath -DiskNumber $partitionInfo.DiskNumber -PartitionNumber $partitionInfo.PartitionNumber -AccessPath ($volume.DriveLetter + ":") -ErrorAction Stop Write-Host "-- 成功删除卷 $($volume.DriveLetter) 的盘符" } catch { Write-Warning "-- 无法删除卷 $($volume.DriveLetter) 的盘符: $($_.Exception.Message)" -ForegroundColor Red } } # 重新分配盘符 $index = 0 $availableDriveLetters = $driveLetters | Where-Object { $_ -notin @($systemDriveLetter) } # 先处理系统磁盘上的卷 foreach ($volume in $volumesOnSystemDisk) { if ($volume.DriveLetter -eq $systemDriveLetter) { continue } if ($index -lt $availableDriveLetters.Length) { $newLetter = $availableDriveLetters[$index] try { $partitionInfo = $partitions[$volume.DriveLetter] Add-PartitionAccessPath -DiskNumber $partitionInfo.DiskNumber -PartitionNumber $partitionInfo.PartitionNumber -AccessPath ($newLetter + ":") -ErrorAction Stop Write-Host "-- 成功将系统磁盘上的卷 $($volume.DriveLetter) 更改为盘符 $newLetter" -ForegroundColor Green } catch { Write-Warning "-- 无法更改系统磁盘上的卷 $($volume.DriveLetter) 的盘符: $($_.Exception.Message)" -ForegroundColor Red } $index++ } else { Write-Warning "-- 没有足够的可用盘符" -ForegroundColor Red } } # 再处理其他磁盘上的卷,按正确顺序分配盘符 foreach ($volume in $volumesOnOtherDisks) { if ($index -lt $availableDriveLetters.Length) { $newLetter = $availableDriveLetters[$index] try { $partitionInfo = $partitions[$volume.DriveLetter] Add-PartitionAccessPath -DiskNumber $partitionInfo.DiskNumber -PartitionNumber $partitionInfo.PartitionNumber -AccessPath ($newLetter + ":") -ErrorAction Stop Write-Host "-- 成功将其他磁盘上的卷 $($volume.DriveLetter) 更改为盘符 $newLetter" -ForegroundColor Yellow } catch { Write-Warning "-- 无法更改其他磁盘上的卷 $($volume.DriveLetter) 的盘符: $($_.Exception.Message)" -ForegroundColor Red } $index++ } else { Write-Warning "-- 没有足够的可用盘符" -ForegroundColor Red } } Write-Host "-- 盘符重新分配完成。" } # GUI 关闭回调 $MainWindow.Add_Closed({ # 创建退出标志文件 New-Item -Path "$env:TEMP\PartitionTool.done" -ItemType File -Force | Out-Null }) # 第六部分:主窗口和事件处理 # 创建主窗口 $MainWindow = New-Object System.Windows.Window # === Added: GUI close callback === $MainWindow.Add_Closed({ try { New-Item -Path "$env:TEMP\PartitionTool.done" -ItemType File -Force | Out-Null } catch {} }) $MainWindow.Title = "磁盘分区工具集 - 主界面" $MainWindow.Width = 500 $MainWindow.Height = 450 $MainWindow.WindowStartupLocation = 'CenterScreen' $MainWindow.ResizeMode = 'NoResize' # 创建主界面布局 $MainGrid = New-Object System.Windows.Controls.Grid $MainGrid.Margin = New-Object System.Windows.Thickness(20) # 添加行定义 $MainGrid.RowDefinitions.Add((New-Object System.Windows.Controls.RowDefinition -Property @{Height = 'Auto'})) $MainGrid.RowDefinitions.Add((New-Object System.Windows.Controls.RowDefinition -Property @{Height = 'Auto'})) $MainGrid.RowDefinitions.Add((New-Object System.Windows.Controls.RowDefinition -Property @{Height = '*'})) $MainGrid.RowDefinitions.Add((New-Object System.Windows.Controls.RowDefinition -Property @{Height = 'Auto'})) $MainGrid.RowDefinitions.Add((New-Object System.Windows.Controls.RowDefinition -Property @{Height = 'Auto'})) $MainGrid.RowDefinitions.Add((New-Object System.Windows.Controls.RowDefinition -Property @{Height = 'Auto'})) # 添加标题 $TitleLabel = New-Object System.Windows.Controls.Label $TitleLabel.Content = "磁盘分区工具集" $TitleLabel.FontSize = 20 $TitleLabel.FontWeight = 'Bold' $TitleLabel.HorizontalAlignment = 'Center' $TitleLabel.Margin = '0,0,0,20' $TitleLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 0) $MainGrid.Children.Add($TitleLabel) # 添加系统信息 $InfoLabel = New-Object System.Windows.Controls.Label $CVolume = Get-Volume -DriveLetter C -ErrorAction SilentlyContinue if ($CVolume) { $CurrentSizeGB = [math]::Round($CVolume.Size / 1GB, 2) # 获取磁盘信息 $CDisk = $null try { $CDisk = Get-Partition -DriveLetter C | Get-Disk -ErrorAction Stop } catch { $CDisk = $null } # 获取分区表类型 $PartitionStyle = if ($CDisk) { $CDisk.PartitionStyle } else { "未知" } # 检查BitLocker状态(简化显示) $BitLockerStatus = "关" try { $BitLockerInfo = Get-BitLockerVolume -MountPoint "C:" -ErrorAction SilentlyContinue if ($BitLockerInfo -and $BitLockerInfo.VolumeStatus -eq "FullyEncrypted") { $BitLockerStatus = "开" } } catch { $BitLockerStatus = "?" } $InfoLabel.Content = "当前 C 盘大小: $CurrentSizeGB GB | $PartitionStyle | BitLocker: $BitLockerStatus" } else { $InfoLabel.Content = "无法获取 C 盘信息" } $InfoLabel.FontSize = 12 $InfoLabel.Foreground = 'Blue' $InfoLabel.HorizontalAlignment = 'Center' $InfoLabel.Margin = '0,0,0,10' $InfoLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 1) $MainGrid.Children.Add($InfoLabel) # 添加磁盘信息 $DiskInfoLabel = New-Object System.Windows.Controls.Label try { $Disk = Get-Partition -DriveLetter C | Get-Disk -ErrorAction Stop $DiskInfoLabel.Content = "系统磁盘: $($Disk.Model) | 总大小: $([math]::Round($Disk.Size / 1GB, 2)) GB" } catch { $DiskInfoLabel.Content = "无法获取磁盘信息" } $DiskInfoLabel.FontSize = 11 $DiskInfoLabel.Foreground = 'DarkGreen' $DiskInfoLabel.HorizontalAlignment = 'Center' $DiskInfoLabel.Margin = '0,0,0,10' $DiskInfoLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 2) $MainGrid.Children.Add($DiskInfoLabel) # 创建工具选择区域 $ToolsStack = New-Object System.Windows.Controls.StackPanel $ToolsStack.Orientation = 'Vertical' $ToolsStack.HorizontalAlignment = 'Center' $ToolsStack.Margin = '0,20,0,10' $ToolsStack.SetValue([System.Windows.Controls.Grid]::RowProperty, 3) $MainGrid.Children.Add($ToolsStack) # C盘分区工具按钮 $CPartitionButton = New-Object System.Windows.Controls.Button $CPartitionButton.Name = "CPartitionButton" $CPartitionButton.Content = "系统盘分区工具" $CPartitionButton.FontSize = 14 $CPartitionButton.Width = 200 $CPartitionButton.Height = 45 $CPartitionButton.Background = '#2196F3' $CPartitionButton.Foreground = 'White' $CPartitionButton.Margin = '0,0,0,15' $CPartitionButton.ToolTip = "压缩系统盘并创建新分区" $ToolsStack.Children.Add($CPartitionButton) # 其他硬盘分区工具按钮 $OtherDiskButton = New-Object System.Windows.Controls.Button $OtherDiskButton.Name = "OtherDiskButton" $OtherDiskButton.Content = "其他硬盘分区工具" $OtherDiskButton.FontSize = 14 $OtherDiskButton.Width = 200 $OtherDiskButton.Height = 45 $OtherDiskButton.Background = '#FF9800' $OtherDiskButton.Foreground = 'White' $OtherDiskButton.Margin = '0,0,0,15' $OtherDiskButton.ToolTip = "对其他硬盘进行分区操作" $ToolsStack.Children.Add($OtherDiskButton) # 盘符理顺工具按钮 $DriveLetterButton = New-Object System.Windows.Controls.Button $DriveLetterButton.Name = "DriveLetterButton" $DriveLetterButton.Content = "盘符理顺工具" $DriveLetterButton.FontSize = 14 $DriveLetterButton.Width = 200 $DriveLetterButton.Height = 45 $DriveLetterButton.Background = '#4CAF50' $DriveLetterButton.Foreground = 'White' $DriveLetterButton.ToolTip = "重新分配和理顺所有盘符" $ToolsStack.Children.Add($DriveLetterButton) # 添加说明文本 $NoteText = New-Object System.Windows.Controls.TextBlock $NoteText.Text = "注意:分区操作有风险,请确保已备份重要数据" $NoteText.FontSize = 10 $NoteText.Foreground = 'Red' $NoteText.TextWrapping = 'Wrap' $NoteText.HorizontalAlignment = 'Center' $NoteText.Margin = '0,20,0,0' $NoteText.SetValue([System.Windows.Controls.Grid]::RowProperty, 4) $MainGrid.Children.Add($NoteText) # 版本信息 $VersionText = New-Object System.Windows.Controls.TextBlock $VersionText.Text = "版本 2.0 | 支持多磁盘分区 | 玩家国度 - 丸子装机" $VersionText.FontSize = 9 $VersionText.Foreground = 'Gray' $VersionText.HorizontalAlignment = 'Center' $VersionText.Margin = '0,5,0,0' $VersionText.SetValue([System.Windows.Controls.Grid]::RowProperty, 5) $MainGrid.Children.Add($VersionText) $MainWindow.Content = $MainGrid # C盘分区工具按钮点击事件 $CPartitionButton.Add_Click({ # 获取C盘信息 $CVolume = Get-Volume -DriveLetter C -ErrorAction SilentlyContinue if (-not $CVolume) { [System.Windows.MessageBox]::Show("无法找到 C 盘,请检查系统配置。", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) return } $CurrentSizeGB = [math]::Round($CVolume.Size / 1GB, 2) Write-Host "-- 当前 C: 卷的总大小是 $CurrentSizeGB GB。" -ForegroundColor Green # 获取硬盘信息 try { $Disk = Get-Partition -DriveLetter C | Get-Disk $DiskNumber = $Disk.Number } catch { [System.Windows.MessageBox]::Show("无法获取磁盘信息。", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) return } # 检查是否已有分区 $Partitions = Get-Partition -DiskNumber $DiskNumber | Where-Object { $_.Type -eq 'Basic' } if ($Partitions.Count -ge 2) { Write-Host "-- 磁盘上已经存在分区,跳过分区创建。" -ForegroundColor Yellow [System.Windows.MessageBox]::Show("检测到已有分区,操作终止。", "分区检测", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) return } # 创建分区工具窗口 CreateCPartitionWindow }) # 其他硬盘分区工具按钮点击事件 $OtherDiskButton.Add_Click({ CreateOtherDiskPartitionWindow }) # 盘符理顺工具按钮点击事件 $DriveLetterButton.Add_Click({ ReassignDriveLettersWithUI }) # 显示主窗口 try { $null = $MainWindow.ShowDialog() } catch { Write-Host "启动错误: $($_.Exception.Message)" -ForegroundColor Red [System.Windows.MessageBox]::Show("程序启动失败: $($_.Exception.Message)", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) }