Partition_Tool
· 81 KiB · Text
Неформатований
# 第一部分:初始化和管理员检查
# 添加必要的程序集
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)
}
| 1 | # 第一部分:初始化和管理员检查 |
| 2 | # 添加必要的程序集 |
| 3 | Add-Type -AssemblyName PresentationFramework |
| 4 | Add-Type -AssemblyName System.Windows.Forms |
| 5 | Add-Type -AssemblyName PresentationCore |
| 6 | |
| 7 | # 检查管理员权限 |
| 8 | if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { |
| 9 | Write-Host "需要管理员权限运行此脚本!" -ForegroundColor Red |
| 10 | $result = [System.Windows.MessageBox]::Show("此工具需要管理员权限才能执行分区操作。是否以管理员身份重新启动?", "需要管理员权限", [System.Windows.MessageBoxButton]::YesNo, [System.Windows.MessageBoxImage]::Warning) |
| 11 | if ($result -eq 'Yes') { |
| 12 | Start-Process PowerShell -Verb RunAs -ArgumentList "-File `"$PSCommandPath`"" |
| 13 | } |
| 14 | exit |
| 15 | } |
| 16 | |
| 17 | |
| 18 | |
| 19 | |
| 20 | |
| 21 | # 第二部分:辅助函数定义 |
| 22 | # 函数定义 |
| 23 | |
| 24 | function ShowDiskPartitionInfo { |
| 25 | param($Disk) |
| 26 | |
| 27 | try { |
| 28 | $Partitions = Get-Partition -DiskNumber $Disk.Number -ErrorAction SilentlyContinue |
| 29 | |
| 30 | $PartitionInfo = "磁盘 $($Disk.Number) 分区信息:`n" |
| 31 | $PartitionInfo += "型号: $($Disk.Model)`n" |
| 32 | $PartitionInfo += "总容量: $([math]::Round($Disk.Size / 1GB, 2)) GB`n" |
| 33 | $PartitionInfo += "分区表: $($Disk.PartitionStyle)`n" |
| 34 | $PartitionInfo += "状态: $($Disk.OperationalStatus)`n`n" |
| 35 | |
| 36 | if ($Partitions) { |
| 37 | $PartitionInfo += "现有分区列表:`n" |
| 38 | $PartitionInfo += "------------------------`n" |
| 39 | |
| 40 | foreach ($Partition in $Partitions) { |
| 41 | $SizeGB = [math]::Round($Partition.Size / 1GB, 2) |
| 42 | $DriveLetter = if ($Partition.DriveLetter) { $Partition.DriveLetter } else { "无" } |
| 43 | $Type = $Partition.Type |
| 44 | $PartitionInfo += "分区 $($Partition.PartitionNumber):`n" |
| 45 | $PartitionInfo += " 盘符: $DriveLetter`n" |
| 46 | $PartitionInfo += " 大小: $SizeGB GB`n" |
| 47 | $PartitionInfo += " 类型: $Type`n" |
| 48 | $PartitionInfo += "------------------------`n" |
| 49 | } |
| 50 | } else { |
| 51 | $PartitionInfo += "无分区或磁盘未初始化" |
| 52 | } |
| 53 | |
| 54 | [System.Windows.MessageBox]::Show($PartitionInfo, "磁盘分区信息", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information) |
| 55 | } catch { |
| 56 | [System.Windows.MessageBox]::Show("获取分区信息失败: $($_.Exception.Message)", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | function DeleteAllPartitions { |
| 61 | param($Disk, $StatusText, $RefreshCallback) |
| 62 | |
| 63 | try { |
| 64 | # 获取分区信息用于确认 |
| 65 | $Partitions = Get-Partition -DiskNumber $Disk.Number -ErrorAction SilentlyContinue |
| 66 | |
| 67 | if (-not $Partitions -or $Partitions.Count -eq 0) { |
| 68 | [System.Windows.MessageBox]::Show("磁盘 $($Disk.Number) 上没有找到分区。", "信息", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information) |
| 69 | return |
| 70 | } |
| 71 | |
| 72 | # 显示分区列表用于确认 |
| 73 | $PartitionList = "即将删除以下分区:`n`n" |
| 74 | foreach ($Partition in $Partitions) { |
| 75 | $SizeGB = [math]::Round($Partition.Size / 1GB, 2) |
| 76 | $DriveLetter = if ($Partition.DriveLetter) { $Partition.DriveLetter } else { "无盘符" } |
| 77 | $PartitionList += "分区 $($Partition.PartitionNumber) - $DriveLetter - $SizeGB GB`n" |
| 78 | } |
| 79 | |
| 80 | $Result = [System.Windows.MessageBox]::Show( |
| 81 | "确定要删除磁盘 $($Disk.Number) 的所有分区吗?`n`n$PartitionList`n此操作将永久删除分区上的所有数据!", |
| 82 | "确认删除分区", |
| 83 | [System.Windows.MessageBoxButton]::YesNo, |
| 84 | [System.Windows.MessageBoxImage]::Warning |
| 85 | ) |
| 86 | |
| 87 | if ($Result -eq 'No') { |
| 88 | return |
| 89 | } |
| 90 | |
| 91 | $StatusText.Text = "正在删除所有分区..." |
| 92 | $StatusText.Foreground = 'Orange' |
| 93 | |
| 94 | # 清除磁盘所有分区 |
| 95 | Clear-Disk -Number $Disk.Number -RemoveData -RemoveOEM -Confirm:$false -ErrorAction Stop |
| 96 | |
| 97 | # 等待操作完成 |
| 98 | Start-Sleep -Seconds 2 |
| 99 | |
| 100 | $StatusText.Text = "分区删除完成!磁盘现在为空。" |
| 101 | $StatusText.Foreground = 'Green' |
| 102 | |
| 103 | [System.Windows.MessageBox]::Show("所有分区已成功删除!", "完成", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information) |
| 104 | |
| 105 | # 执行刷新回调 |
| 106 | if ($RefreshCallback) { |
| 107 | & $RefreshCallback |
| 108 | } |
| 109 | |
| 110 | } catch { |
| 111 | $StatusText.Text = "删除分区失败: $($_.Exception.Message)" |
| 112 | $StatusText.Foreground = 'Red' |
| 113 | [System.Windows.MessageBox]::Show("删除分区失败: $($_.Exception.Message)", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | function ExecuteOtherDiskPartition { |
| 118 | param($Disk, $PartitionSizes, $PartitionStyle, $FileSystem, $AllocationUnit, $StatusText, $RefreshCallback) |
| 119 | |
| 120 | try { |
| 121 | $StatusText.Text = "正在准备磁盘..." |
| 122 | $StatusText.Foreground = 'Orange' |
| 123 | |
| 124 | # 强制刷新磁盘信息 |
| 125 | $CurrentDisk = $null |
| 126 | $retryCount = 0 |
| 127 | while (-not $CurrentDisk -and $retryCount -lt 3) { |
| 128 | try { |
| 129 | $CurrentDisk = Get-Disk -Number $Disk.Number -ErrorAction Stop |
| 130 | } catch { |
| 131 | $retryCount++ |
| 132 | Start-Sleep -Seconds 1 |
| 133 | } |
| 134 | } |
| 135 | |
| 136 | if (-not $CurrentDisk) { |
| 137 | [System.Windows.MessageBox]::Show("无法访问磁盘 $($Disk.Number),请检查磁盘是否存在或是否被其他程序占用。", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) |
| 138 | return |
| 139 | } |
| 140 | |
| 141 | Write-Host "磁盘当前状态: $($CurrentDisk.PartitionStyle), 操作状态: $($CurrentDisk.OperationalStatus)" -ForegroundColor Yellow |
| 142 | |
| 143 | # 检查并清除现有分区 |
| 144 | $Partitions = Get-Partition -DiskNumber $Disk.Number -ErrorAction SilentlyContinue |
| 145 | if ($Partitions -and $Partitions.Count -gt 0) { |
| 146 | $StatusText.Text = "正在清除磁盘所有分区和数据..." |
| 147 | Write-Host "发现 $($Partitions.Count) 个分区,正在清除..." -ForegroundColor Yellow |
| 148 | |
| 149 | # 使用更彻底的清除方法 |
| 150 | Clear-Disk -Number $Disk.Number -RemoveData -RemoveOEM -Confirm:$false -ErrorAction Stop |
| 151 | Write-Host "磁盘清除完成" -ForegroundColor Green |
| 152 | |
| 153 | # 等待磁盘状态更新 |
| 154 | Start-Sleep -Seconds 2 |
| 155 | } |
| 156 | |
| 157 | # 重新获取磁盘状态 |
| 158 | $CurrentDisk = Get-Disk -Number $Disk.Number -ErrorAction Stop |
| 159 | Write-Host "清除后磁盘状态: $($CurrentDisk.PartitionStyle)" -ForegroundColor Yellow |
| 160 | |
| 161 | # 强制初始化磁盘(无论当前状态如何) |
| 162 | $StatusText.Text = "正在初始化磁盘为 $PartitionStyle 格式..." |
| 163 | Write-Host "正在初始化磁盘为 $PartitionStyle 格式..." -ForegroundColor Yellow |
| 164 | |
| 165 | # 如果磁盘已经有分区表但不是我们需要的类型,先清除 |
| 166 | if ($CurrentDisk.PartitionStyle -ne "RAW" -and $CurrentDisk.PartitionStyle -ne $PartitionStyle) { |
| 167 | Write-Host "磁盘分区表类型不匹配,重新初始化..." -ForegroundColor Yellow |
| 168 | Clear-Disk -Number $Disk.Number -RemoveData -RemoveOEM -Confirm:$false -ErrorAction Stop |
| 169 | Start-Sleep -Seconds 1 |
| 170 | } |
| 171 | |
| 172 | # 初始化磁盘 |
| 173 | if ($CurrentDisk.PartitionStyle -eq "RAW" -or $CurrentDisk.PartitionStyle -ne $PartitionStyle) { |
| 174 | Initialize-Disk -Number $Disk.Number -PartitionStyle $PartitionStyle -ErrorAction Stop |
| 175 | Write-Host "磁盘初始化完成" -ForegroundColor Green |
| 176 | } |
| 177 | |
| 178 | # 再次等待确保初始化完成 |
| 179 | Start-Sleep -Seconds 2 |
| 180 | |
| 181 | # 验证磁盘初始化状态 |
| 182 | $FinalDisk = Get-Disk -Number $Disk.Number -ErrorAction Stop |
| 183 | if ($FinalDisk.PartitionStyle -ne $PartitionStyle) { |
| 184 | throw "磁盘初始化失败,当前分区表类型: $($FinalDisk.PartitionStyle),期望: $PartitionStyle" |
| 185 | } |
| 186 | |
| 187 | $StatusText.Text = "磁盘已初始化为 $PartitionStyle 格式,正在创建分区..." |
| 188 | Write-Host "磁盘初始化验证通过,开始创建分区..." -ForegroundColor Green |
| 189 | |
| 190 | # 设置分配单元大小 |
| 191 | $FormatParams = @{ |
| 192 | FileSystem = $FileSystem |
| 193 | Confirm = $false |
| 194 | } |
| 195 | |
| 196 | if ($AllocationUnit -ne "默认") { |
| 197 | $UnitSize = switch ($AllocationUnit) { |
| 198 | "4096 字节 (4K)" { 4096 } |
| 199 | "8192 字节 (8K)" { 8192 } |
| 200 | "16384 字节 (16K)" { 16384 } |
| 201 | "32768 字节 (32K)" { 32768 } |
| 202 | "65536 字节 (64K)" { 65536 } |
| 203 | default { 4096 } |
| 204 | } |
| 205 | $FormatParams.AllocationUnitSize = $UnitSize |
| 206 | } |
| 207 | |
| 208 | # 创建分区 |
| 209 | $CreatedPartitions = @() |
| 210 | $TotalPartitions = $PartitionSizes.Count |
| 211 | |
| 212 | for ($i = 0; $i -lt $TotalPartitions; $i++) { |
| 213 | $PartitionSize = $PartitionSizes[$i] |
| 214 | |
| 215 | $StatusText.Text = "正在创建分区 $($i+1)/$TotalPartitions..." |
| 216 | Write-Host "创建分区 $($i+1)/$TotalPartitions,大小: $PartitionSize GB" -ForegroundColor Cyan |
| 217 | |
| 218 | if ($PartitionSize -eq 0 -and $i -eq $TotalPartitions - 1) { |
| 219 | # 最后一个分区使用剩余空间 |
| 220 | $NewPartition = New-Partition -DiskNumber $Disk.Number -UseMaximumSize -AssignDriveLetter -ErrorAction Stop |
| 221 | } else { |
| 222 | # 指定大小的分区 |
| 223 | $SizeInBytes = $PartitionSize * 1GB |
| 224 | $NewPartition = New-Partition -DiskNumber $Disk.Number -Size $SizeInBytes -AssignDriveLetter -ErrorAction Stop |
| 225 | } |
| 226 | |
| 227 | if ($NewPartition) { |
| 228 | # 等待分区创建完成 |
| 229 | Start-Sleep -Seconds 1 |
| 230 | |
| 231 | # 格式化分区 |
| 232 | $StatusText.Text = "正在格式化分区 $($i+1)..." |
| 233 | Write-Host "格式化分区,盘符: $($NewPartition.DriveLetter)" -ForegroundColor Cyan |
| 234 | |
| 235 | $FormatResult = Format-Volume -DriveLetter $NewPartition.DriveLetter @FormatParams -ErrorAction Stop |
| 236 | |
| 237 | $CreatedPartitions += @{ |
| 238 | Number = $i + 1 |
| 239 | DriveLetter = $NewPartition.DriveLetter |
| 240 | SizeGB = [math]::Round($NewPartition.Size / 1GB, 2) |
| 241 | } |
| 242 | |
| 243 | $StatusText.Text = "分区 $($i+1) 创建完成 (盘符: $($NewPartition.DriveLetter))..." |
| 244 | Write-Host "-- 分区 $($i+1) 创建成功,盘符: $($NewPartition.DriveLetter), 大小: $([math]::Round($NewPartition.Size / 1GB, 2)) GB, 文件系统: $FileSystem" -ForegroundColor Green |
| 245 | } |
| 246 | } |
| 247 | |
| 248 | # 显示分区结果摘要 |
| 249 | $PartitionSummary = "分区操作完成!`n`n创建的分区:`n" |
| 250 | foreach ($Part in $CreatedPartitions) { |
| 251 | $PartitionSummary += "分区 $($Part.Number): 盘符 $($Part.DriveLetter) - $($Part.SizeGB) GB`n" |
| 252 | } |
| 253 | |
| 254 | $StatusText.Text = "磁盘分区完成!" |
| 255 | $StatusText.Foreground = 'Green' |
| 256 | |
| 257 | [System.Windows.MessageBox]::Show($PartitionSummary, "分区完成", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information) |
| 258 | |
| 259 | # 执行刷新回调 |
| 260 | if ($RefreshCallback) { |
| 261 | & $RefreshCallback |
| 262 | } |
| 263 | |
| 264 | } catch { |
| 265 | $ErrorMessage = $_.Exception.Message |
| 266 | $StatusText.Text = "操作失败: $ErrorMessage" |
| 267 | $StatusText.Foreground = 'Red' |
| 268 | |
| 269 | Write-Host "分区操作失败: $ErrorMessage" -ForegroundColor Red |
| 270 | |
| 271 | # 提供更详细的错误信息 |
| 272 | $DetailedError = "分区操作失败!`n`n错误信息: $ErrorMessage`n`n建议:`n- 检查磁盘是否被其他程序占用`n- 尝试重新启动计算机后重试`n- 检查磁盘硬件状态`n- 确保有足够的管理员权限" |
| 273 | |
| 274 | [System.Windows.MessageBox]::Show($DetailedError, "分区操作失败", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) |
| 275 | } |
| 276 | } |
| 277 | |
| 278 | |
| 279 | |
| 280 | |
| 281 | |
| 282 | |
| 283 | |
| 284 | |
| 285 | # 第三部分:其他硬盘分区工具窗口 |
| 286 | |
| 287 | |
| 288 | function CreateOtherDiskPartitionWindow { |
| 289 | $OtherDiskWindow = New-Object System.Windows.Window |
| 290 | $OtherDiskWindow.Title = "其他硬盘分区工具" |
| 291 | $OtherDiskWindow.Height = 380 # 设置初始高度为380 |
| 292 | $OtherDiskWindow.Width = 750 |
| 293 | $OtherDiskWindow.WindowStartupLocation = 'CenterOwner' |
| 294 | $OtherDiskWindow.Owner = $MainWindow |
| 295 | $OtherDiskWindow.Topmost = $true |
| 296 | $OtherDiskWindow.ResizeMode = 'NoResize' |
| 297 | |
| 298 | # 创建主网格 |
| 299 | $OtherDiskGrid = New-Object System.Windows.Controls.Grid |
| 300 | $OtherDiskGrid.Margin = New-Object System.Windows.Thickness(15) |
| 301 | |
| 302 | # 定义行(减少一行,因为自定义分区改为折叠) |
| 303 | for ($i = 0; $i -lt 10; $i++) { |
| 304 | $RowDef = New-Object System.Windows.Controls.RowDefinition |
| 305 | if ($i -eq 9) { |
| 306 | $RowDef.Height = '*' |
| 307 | } else { |
| 308 | $RowDef.Height = 'Auto' |
| 309 | } |
| 310 | $OtherDiskGrid.RowDefinitions.Add($RowDef) |
| 311 | } |
| 312 | |
| 313 | # 定义列 |
| 314 | $OtherDiskGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '110'})) |
| 315 | $OtherDiskGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '*'})) |
| 316 | $OtherDiskGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '30'})) |
| 317 | |
| 318 | # 标题 |
| 319 | $TitleLabel = New-Object System.Windows.Controls.Label |
| 320 | $TitleLabel.Content = "其他硬盘分区工具" |
| 321 | $TitleLabel.FontSize = 16 |
| 322 | $TitleLabel.FontWeight = 'Bold' |
| 323 | $TitleLabel.HorizontalAlignment = 'Center' |
| 324 | $TitleLabel.Margin = '0,0,0,15' |
| 325 | $TitleLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 0) |
| 326 | $TitleLabel.SetValue([System.Windows.Controls.Grid]::ColumnSpanProperty, 3) |
| 327 | $OtherDiskGrid.Children.Add($TitleLabel) |
| 328 | |
| 329 | # 获取所有磁盘(排除系统磁盘) |
| 330 | $SystemDisk = Get-Partition -DriveLetter C | Get-Disk |
| 331 | $Disks = Get-Disk | Where-Object { |
| 332 | $_.OperationalStatus -eq 'Online' -and |
| 333 | $_.Number -ne $SystemDisk.Number |
| 334 | } |
| 335 | |
| 336 | if ($Disks.Count -eq 0) { |
| 337 | [System.Windows.MessageBox]::Show("未找到可用的其他硬盘。", "信息", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information) |
| 338 | return |
| 339 | } |
| 340 | |
| 341 | # 磁盘选择 |
| 342 | $DiskLabel = New-Object System.Windows.Controls.Label |
| 343 | $DiskLabel.Content = "选择磁盘:" |
| 344 | $DiskLabel.VerticalAlignment = 'Center' |
| 345 | $DiskLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 1) |
| 346 | $DiskLabel.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) |
| 347 | $OtherDiskGrid.Children.Add($DiskLabel) |
| 348 | |
| 349 | $DiskComboBox = New-Object System.Windows.Controls.ComboBox |
| 350 | $DiskComboBox.Name = "DiskComboBox" |
| 351 | $DiskComboBox.Margin = '5' |
| 352 | $DiskComboBox.Height = 25 |
| 353 | $DiskComboBox.VerticalAlignment = 'Center' |
| 354 | $DiskComboBox.SetValue([System.Windows.Controls.Grid]::RowProperty, 1) |
| 355 | $DiskComboBox.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) |
| 356 | |
| 357 | foreach ($Disk in $Disks) { |
| 358 | $Partitions = Get-Partition -DiskNumber $Disk.Number -ErrorAction SilentlyContinue |
| 359 | # 修复分区计数问题 |
| 360 | $PartitionCount = if ($Partitions) { @($Partitions).Count } else { 0 } |
| 361 | $PartitionStyle = if ($Disk.PartitionStyle -eq "RAW") { "未初始化" } else { $Disk.PartitionStyle } |
| 362 | $DiskInfo = "磁盘 $($Disk.Number) - $($Disk.Model) - $([math]::Round($Disk.Size / 1GB, 2)) GB - $PartitionStyle - $PartitionCount 个分区" |
| 363 | $DiskComboBox.Items.Add($DiskInfo) | Out-Null |
| 364 | } |
| 365 | $DiskComboBox.SelectedIndex = 0 |
| 366 | $OtherDiskGrid.Children.Add($DiskComboBox) |
| 367 | |
| 368 | # 分区表类型 |
| 369 | $PartitionStyleLabel = New-Object System.Windows.Controls.Label |
| 370 | $PartitionStyleLabel.Content = "分区表类型:" |
| 371 | $PartitionStyleLabel.VerticalAlignment = 'Center' |
| 372 | $PartitionStyleLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 2) |
| 373 | $PartitionStyleLabel.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) |
| 374 | $OtherDiskGrid.Children.Add($PartitionStyleLabel) |
| 375 | |
| 376 | $PartitionStyleComboBox = New-Object System.Windows.Controls.ComboBox |
| 377 | $PartitionStyleComboBox.Name = "PartitionStyleComboBox" |
| 378 | $PartitionStyleComboBox.Margin = '5' |
| 379 | $PartitionStyleComboBox.Height = 25 |
| 380 | $PartitionStyleComboBox.VerticalAlignment = 'Center' |
| 381 | $PartitionStyleComboBox.SetValue([System.Windows.Controls.Grid]::RowProperty, 2) |
| 382 | $PartitionStyleComboBox.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) |
| 383 | |
| 384 | $PartitionStyleComboBox.Items.Add("GPT (GUID 分区表) - 推荐") | Out-Null |
| 385 | $PartitionStyleComboBox.Items.Add("MBR (主引导记录)") | Out-Null |
| 386 | $PartitionStyleComboBox.SelectedIndex = 0 |
| 387 | $OtherDiskGrid.Children.Add($PartitionStyleComboBox) |
| 388 | |
| 389 | # 文件系统类型 |
| 390 | $FileSystemLabel = New-Object System.Windows.Controls.Label |
| 391 | $FileSystemLabel.Content = "文件系统:" |
| 392 | $FileSystemLabel.VerticalAlignment = 'Center' |
| 393 | $FileSystemLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 3) |
| 394 | $FileSystemLabel.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) |
| 395 | $OtherDiskGrid.Children.Add($FileSystemLabel) |
| 396 | |
| 397 | $FileSystemComboBox = New-Object System.Windows.Controls.ComboBox |
| 398 | $FileSystemComboBox.Name = "FileSystemComboBox" |
| 399 | $FileSystemComboBox.Margin = '5' |
| 400 | $FileSystemComboBox.Height = 25 |
| 401 | $FileSystemComboBox.VerticalAlignment = 'Center' |
| 402 | $FileSystemComboBox.SetValue([System.Windows.Controls.Grid]::RowProperty, 3) |
| 403 | $FileSystemComboBox.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) |
| 404 | |
| 405 | $FileSystemComboBox.Items.Add("NTFS (Windows)") | Out-Null |
| 406 | $FileSystemComboBox.Items.Add("FAT32 (兼容性)") | Out-Null |
| 407 | $FileSystemComboBox.Items.Add("exFAT (大文件支持)") | Out-Null |
| 408 | $FileSystemComboBox.SelectedIndex = 0 |
| 409 | $OtherDiskGrid.Children.Add($FileSystemComboBox) |
| 410 | |
| 411 | # 分配单元大小 |
| 412 | $AllocationUnitLabel = New-Object System.Windows.Controls.Label |
| 413 | $AllocationUnitLabel.Content = "分配单元大小:" |
| 414 | $AllocationUnitLabel.VerticalAlignment = 'Center' |
| 415 | $AllocationUnitLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 4) |
| 416 | $AllocationUnitLabel.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) |
| 417 | $OtherDiskGrid.Children.Add($AllocationUnitLabel) |
| 418 | |
| 419 | $AllocationUnitComboBox = New-Object System.Windows.Controls.ComboBox |
| 420 | $AllocationUnitComboBox.Name = "AllocationUnitComboBox" |
| 421 | $AllocationUnitComboBox.Margin = '5' |
| 422 | $AllocationUnitComboBox.Height = 25 |
| 423 | $AllocationUnitComboBox.VerticalAlignment = 'Center' |
| 424 | $AllocationUnitComboBox.SetValue([System.Windows.Controls.Grid]::RowProperty, 4) |
| 425 | $AllocationUnitComboBox.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) |
| 426 | |
| 427 | $AllocationUnitComboBox.Items.Add("默认") | Out-Null |
| 428 | $AllocationUnitComboBox.Items.Add("4096 字节 (4K)") | Out-Null |
| 429 | $AllocationUnitComboBox.Items.Add("8192 字节 (8K)") | Out-Null |
| 430 | $AllocationUnitComboBox.Items.Add("16384 字节 (16K)") | Out-Null |
| 431 | $AllocationUnitComboBox.Items.Add("32768 字节 (32K)") | Out-Null |
| 432 | $AllocationUnitComboBox.Items.Add("65536 字节 (64K)") | Out-Null |
| 433 | $AllocationUnitComboBox.SelectedIndex = 0 |
| 434 | $OtherDiskGrid.Children.Add($AllocationUnitComboBox) |
| 435 | |
| 436 | # 分区方案选择 |
| 437 | $SchemeLabel = New-Object System.Windows.Controls.Label |
| 438 | $SchemeLabel.Content = "分区方案:" |
| 439 | $SchemeLabel.VerticalAlignment = 'Center' |
| 440 | $SchemeLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 5) |
| 441 | $SchemeLabel.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) |
| 442 | $OtherDiskGrid.Children.Add($SchemeLabel) |
| 443 | |
| 444 | $SchemeComboBox = New-Object System.Windows.Controls.ComboBox |
| 445 | $SchemeComboBox.Name = "SchemeComboBox" |
| 446 | $SchemeComboBox.Margin = '5' |
| 447 | $SchemeComboBox.Height = 25 |
| 448 | $SchemeComboBox.VerticalAlignment = 'Center' |
| 449 | $SchemeComboBox.SetValue([System.Windows.Controls.Grid]::RowProperty, 5) |
| 450 | $SchemeComboBox.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) |
| 451 | |
| 452 | $SchemeComboBox.Items.Add("2个分区 (各50%)") | Out-Null |
| 453 | $SchemeComboBox.Items.Add("3个分区 (33% 每个)") | Out-Null |
| 454 | $SchemeComboBox.Items.Add("4个分区 (25% 每个)") | Out-Null |
| 455 | $SchemeComboBox.Items.Add("单个分区 (使用全部空间)") | Out-Null |
| 456 | $SchemeComboBox.Items.Add("自定义分区") | Out-Null |
| 457 | $SchemeComboBox.SelectedIndex = 0 |
| 458 | $OtherDiskGrid.Children.Add($SchemeComboBox) |
| 459 | |
| 460 | # 自定义分区大小输入(默认折叠) |
| 461 | $CustomPartitionStack = New-Object System.Windows.Controls.StackPanel |
| 462 | $CustomPartitionStack.Orientation = 'Vertical' |
| 463 | $CustomPartitionStack.Margin = '0,10,0,0' |
| 464 | $CustomPartitionStack.Visibility = 'Collapsed' |
| 465 | $CustomPartitionStack.SetValue([System.Windows.Controls.Grid]::RowProperty, 6) |
| 466 | $CustomPartitionStack.SetValue([System.Windows.Controls.Grid]::ColumnSpanProperty, 3) |
| 467 | $OtherDiskGrid.Children.Add($CustomPartitionStack) |
| 468 | |
| 469 | $CustomLabel = New-Object System.Windows.Controls.Label |
| 470 | $CustomLabel.Content = "自定义分区容量 (GB,用逗号分隔):" |
| 471 | $CustomLabel.Margin = '0,5,0,5' |
| 472 | $CustomPartitionStack.Children.Add($CustomLabel) |
| 473 | |
| 474 | $CustomTextBox = New-Object System.Windows.Controls.TextBox |
| 475 | $CustomTextBox.Name = "CustomTextBox" |
| 476 | $CustomTextBox.Margin = '5' |
| 477 | $CustomTextBox.Height = 25 |
| 478 | $CustomTextBox.VerticalContentAlignment = 'Center' |
| 479 | $CustomTextBox.Text = "100,200,MAX" |
| 480 | $CustomPartitionStack.Children.Add($CustomTextBox) |
| 481 | |
| 482 | # 显示方案选择变化 - 修改为自动展开/折叠自定义分区输入 |
| 483 | $SchemeComboBox.Add_SelectionChanged({ |
| 484 | if ($SchemeComboBox.SelectedIndex -eq 4) { |
| 485 | # 选择自定义分区时展开 |
| 486 | $CustomPartitionStack.Visibility = 'Visible' |
| 487 | $OtherDiskWindow.Height = 465 # 增加窗口高度以显示自定义分区输入 |
| 488 | } else { |
| 489 | # 选择其他方案时折叠 |
| 490 | $CustomPartitionStack.Visibility = 'Collapsed' |
| 491 | $OtherDiskWindow.Height = 380 # 恢复初始高度 |
| 492 | } |
| 493 | }) |
| 494 | |
| 495 | # 按钮区域 |
| 496 | $ButtonStack = New-Object System.Windows.Controls.StackPanel |
| 497 | $ButtonStack.Orientation = 'Horizontal' |
| 498 | $ButtonStack.HorizontalAlignment = 'Center' |
| 499 | $ButtonStack.Margin = '0,20,0,10' |
| 500 | $ButtonStack.SetValue([System.Windows.Controls.Grid]::RowProperty, 7) |
| 501 | $ButtonStack.SetValue([System.Windows.Controls.Grid]::ColumnSpanProperty, 3) |
| 502 | $OtherDiskGrid.Children.Add($ButtonStack) |
| 503 | |
| 504 | # 查看分区按钮 |
| 505 | $DiskInfoButton = New-Object System.Windows.Controls.Button |
| 506 | $DiskInfoButton.Content = "查看分区" |
| 507 | $DiskInfoButton.Width = 95 |
| 508 | $DiskInfoButton.Height = 35 |
| 509 | $DiskInfoButton.FontSize = 11 |
| 510 | $DiskInfoButton.Background = '#2196F3' |
| 511 | $DiskInfoButton.Foreground = 'White' |
| 512 | $DiskInfoButton.Margin = '0,0,3,0' |
| 513 | $ButtonStack.Children.Add($DiskInfoButton) |
| 514 | |
| 515 | # 删除分区按钮 |
| 516 | $DeletePartitionsButton = New-Object System.Windows.Controls.Button |
| 517 | $DeletePartitionsButton.Content = "删除分区" |
| 518 | $DeletePartitionsButton.Width = 95 |
| 519 | $DeletePartitionsButton.Height = 35 |
| 520 | $DeletePartitionsButton.FontSize = 11 |
| 521 | $DeletePartitionsButton.Background = '#F44336' |
| 522 | $DeletePartitionsButton.Foreground = 'White' |
| 523 | $DeletePartitionsButton.Margin = '0,0,3,0' |
| 524 | $DeletePartitionsButton.ToolTip = "删除此磁盘的所有分区" |
| 525 | $ButtonStack.Children.Add($DeletePartitionsButton) |
| 526 | |
| 527 | # 刷新磁盘按钮 |
| 528 | $RefreshButton = New-Object System.Windows.Controls.Button |
| 529 | $RefreshButton.Content = "刷新" |
| 530 | $RefreshButton.Width = 95 |
| 531 | $RefreshButton.Height = 35 |
| 532 | $RefreshButton.FontSize = 11 |
| 533 | $RefreshButton.Background = '#FF9800' |
| 534 | $RefreshButton.Foreground = 'White' |
| 535 | $RefreshButton.Margin = '0,0,3,0' |
| 536 | $RefreshButton.ToolTip = "刷新磁盘列表和状态" |
| 537 | $ButtonStack.Children.Add($RefreshButton) |
| 538 | |
| 539 | # 开始分区按钮 |
| 540 | $StartButton = New-Object System.Windows.Controls.Button |
| 541 | $StartButton.Content = "开始分区" |
| 542 | $StartButton.Width = 95 |
| 543 | $StartButton.Height = 35 |
| 544 | $StartButton.FontSize = 12 |
| 545 | $StartButton.Background = '#4CAF50' |
| 546 | $StartButton.Foreground = 'White' |
| 547 | $StartButton.Margin = '0,0,3,0' |
| 548 | $ButtonStack.Children.Add($StartButton) |
| 549 | |
| 550 | # 显示详细说明按钮 |
| 551 | $ToggleInstructionsButton = New-Object System.Windows.Controls.Button |
| 552 | $ToggleInstructionsButton.Content = "显示说明" |
| 553 | $ToggleInstructionsButton.Width = 95 |
| 554 | $ToggleInstructionsButton.Height = 35 |
| 555 | $ToggleInstructionsButton.FontSize = 11 |
| 556 | $ToggleInstructionsButton.Background = '#607D8B' |
| 557 | $ToggleInstructionsButton.Foreground = 'White' |
| 558 | $ToggleInstructionsButton.Margin = '0,0,3,0' |
| 559 | $ButtonStack.Children.Add($ToggleInstructionsButton) |
| 560 | |
| 561 | # 取消按钮 |
| 562 | $CancelButton = New-Object System.Windows.Controls.Button |
| 563 | $CancelButton.Content = "取消" |
| 564 | $CancelButton.Width = 95 |
| 565 | $CancelButton.Height = 35 |
| 566 | $CancelButton.FontSize = 12 |
| 567 | $ButtonStack.Children.Add($CancelButton) |
| 568 | |
| 569 | # 说明区域(默认折叠) |
| 570 | $InstructionGrid = New-Object System.Windows.Controls.Grid |
| 571 | $InstructionGrid.Margin = '10,5,10,5' |
| 572 | $InstructionGrid.Visibility = 'Collapsed' |
| 573 | $InstructionGrid.SetValue([System.Windows.Controls.Grid]::RowProperty, 8) |
| 574 | $InstructionGrid.SetValue([System.Windows.Controls.Grid]::ColumnSpanProperty, 3) |
| 575 | |
| 576 | # 创建4列 |
| 577 | $InstructionGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '*'})) |
| 578 | $InstructionGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '*'})) |
| 579 | $InstructionGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '*'})) |
| 580 | $InstructionGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '*'})) |
| 581 | $OtherDiskGrid.Children.Add($InstructionGrid) |
| 582 | |
| 583 | # 第一列 - 分区表类型 |
| 584 | $Col1Text = New-Object System.Windows.Controls.TextBlock |
| 585 | $Col1Text.Text = @" |
| 586 | 🔧 分区表类型 |
| 587 | |
| 588 | GPT (推荐) |
| 589 | ✓ 支持>2TB磁盘 |
| 590 | ✓ 最多128分区 |
| 591 | ✓ 更安全可靠 |
| 592 | ✓ 现代标准 |
| 593 | |
| 594 | MBR (传统) |
| 595 | ✓ 兼容性好 |
| 596 | ✓ 传统系统支持 |
| 597 | ✗ 限4主分区 |
| 598 | ✗ 单分区2TB |
| 599 | "@ |
| 600 | $Col1Text.FontSize = 9 |
| 601 | $Col1Text.Foreground = 'Gray' |
| 602 | $Col1Text.TextWrapping = 'Wrap' |
| 603 | $Col1Text.Margin = '3' |
| 604 | $Col1Text.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) |
| 605 | $InstructionGrid.Children.Add($Col1Text) |
| 606 | |
| 607 | # 第二列 - 文件系统 |
| 608 | $Col2Text = New-Object System.Windows.Controls.TextBlock |
| 609 | $Col2Text.Text = @" |
| 610 | 💾 文件系统 |
| 611 | |
| 612 | NTFS |
| 613 | ✓ Windows标准 |
| 614 | ✓ 权限管理 |
| 615 | ✓ 大文件支持 |
| 616 | ✓ 单个文件16TB |
| 617 | |
| 618 | FAT32 |
| 619 | ✓ 兼容性好 |
| 620 | ✓ 适合U盘 |
| 621 | ✗ 单文件4GB |
| 622 | ✗ 无权限管理 |
| 623 | |
| 624 | exFAT |
| 625 | ✓ 跨平台 |
| 626 | ✓ 大文件支持 |
| 627 | ✓ 移动设备 |
| 628 | "@ |
| 629 | $Col2Text.FontSize = 9 |
| 630 | $Col2Text.Foreground = 'Gray' |
| 631 | $Col2Text.TextWrapping = 'Wrap' |
| 632 | $Col2Text.Margin = '3' |
| 633 | $Col2Text.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) |
| 634 | $InstructionGrid.Children.Add($Col2Text) |
| 635 | |
| 636 | # 第三列 - 分区方案 |
| 637 | $Col3Text = New-Object System.Windows.Controls.TextBlock |
| 638 | $Col3Text.Text = @" |
| 639 | 📊 分区方案 |
| 640 | |
| 641 | 预设方案 |
| 642 | • 2分区(各50%) |
| 643 | • 3分区(33%每个) |
| 644 | • 4分区(25%每个) |
| 645 | • 单分区(全部) |
| 646 | |
| 647 | 自定义分区 |
| 648 | 格式:100,200,MAX |
| 649 | • 数字=固定容量(GB) |
| 650 | • MAX=剩余所有空间 |
| 651 | • 只能有一个MAX |
| 652 | |
| 653 | 示例: |
| 654 | 100,200,MAX |
| 655 | =100GB+200GB+剩余 |
| 656 | "@ |
| 657 | $Col3Text.FontSize = 9 |
| 658 | $Col3Text.Foreground = 'Gray' |
| 659 | $Col3Text.TextWrapping = 'Wrap' |
| 660 | $Col3Text.Margin = '3' |
| 661 | $Col3Text.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 2) |
| 662 | $InstructionGrid.Children.Add($Col3Text) |
| 663 | |
| 664 | # 第四列 - 警告提示 |
| 665 | $Col4Text = New-Object System.Windows.Controls.TextBlock |
| 666 | $Col4Text.Text = @" |
| 667 | ⚠️ 重要警告 |
| 668 | |
| 669 | 数据安全 |
| 670 | • 永久删除所有数据 |
| 671 | • 操作前备份文件 |
| 672 | • 确认目标磁盘 |
| 673 | • 谨慎操作谨防数据丢失 |
| 674 | |
| 675 | 操作提示 |
| 676 | • 选择正确磁盘 |
| 677 | • 勿中断操作 |
| 678 | • 等待完成提示 |
| 679 | |
| 680 | |
| 681 | "@ |
| 682 | $Col4Text.FontSize = 9 |
| 683 | $Col4Text.Foreground = 'Gray' |
| 684 | $Col4Text.TextWrapping = 'Wrap' |
| 685 | $Col4Text.Margin = '3' |
| 686 | $Col4Text.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 3) |
| 687 | $InstructionGrid.Children.Add($Col4Text) |
| 688 | |
| 689 | # 折叠按钮事件 |
| 690 | $ToggleInstructionsButton.Add_Click({ |
| 691 | if ($InstructionGrid.Visibility -eq 'Visible') { |
| 692 | $InstructionGrid.Visibility = 'Collapsed' |
| 693 | $ToggleInstructionsButton.Content = "显示说明" |
| 694 | if ($CustomPartitionStack.Visibility -eq 'Visible') { |
| 695 | $OtherDiskWindow.Height = 465 |
| 696 | } else { |
| 697 | $OtherDiskWindow.Height = 380 |
| 698 | } |
| 699 | } else { |
| 700 | $InstructionGrid.Visibility = 'Visible' |
| 701 | $ToggleInstructionsButton.Content = "隐藏说明" |
| 702 | if ($CustomPartitionStack.Visibility -eq 'Visible') { |
| 703 | $OtherDiskWindow.Height = 680 |
| 704 | } else { |
| 705 | $OtherDiskWindow.Height = 600 |
| 706 | } |
| 707 | } |
| 708 | }) |
| 709 | |
| 710 | # 状态显示 |
| 711 | $StatusText = New-Object System.Windows.Controls.TextBlock |
| 712 | $StatusText.Name = "StatusText" |
| 713 | $StatusText.Text = "选择磁盘和配置分区参数..." |
| 714 | $StatusText.FontSize = 10 |
| 715 | $StatusText.Foreground = 'Blue' |
| 716 | $StatusText.TextWrapping = 'Wrap' |
| 717 | $StatusText.Margin = '10,5,10,5' |
| 718 | $StatusText.SetValue([System.Windows.Controls.Grid]::RowProperty, 9) |
| 719 | $StatusText.SetValue([System.Windows.Controls.Grid]::ColumnSpanProperty, 3) |
| 720 | $OtherDiskGrid.Children.Add($StatusText) |
| 721 | |
| 722 | # 刷新磁盘列表函数 |
| 723 | $RefreshDiskList = { |
| 724 | $StatusText.Text = "正在刷新磁盘列表..." |
| 725 | $StatusText.Foreground = 'Blue' |
| 726 | |
| 727 | # 保存当前选择的磁盘 |
| 728 | $PreviouslySelectedIndex = $DiskComboBox.SelectedIndex |
| 729 | $PreviouslySelectedDiskNumber = -1 |
| 730 | if ($PreviouslySelectedIndex -ge 0 -and $PreviouslySelectedIndex -lt $Disks.Count) { |
| 731 | $PreviouslySelectedDiskNumber = $Disks[$PreviouslySelectedIndex].Number |
| 732 | } |
| 733 | |
| 734 | # 重新获取磁盘列表 |
| 735 | $SystemDisk = Get-Partition -DriveLetter C | Get-Disk |
| 736 | $script:Disks = Get-Disk | Where-Object { |
| 737 | $_.OperationalStatus -eq 'Online' -and |
| 738 | $_.Number -ne $SystemDisk.Number |
| 739 | } |
| 740 | |
| 741 | # 清空并重新填充下拉框 |
| 742 | $DiskComboBox.Items.Clear() |
| 743 | $NewSelectedIndex = -1 |
| 744 | |
| 745 | foreach ($Disk in $script:Disks) { |
| 746 | # 获取过滤后的分区信息(保留无盘符的数据分区) |
| 747 | $Partitions = Get-Partition -DiskNumber $Disk.Number -ErrorAction SilentlyContinue | Where-Object { |
| 748 | # 保留条件:有盘符的数据分区 或 无盘符但类型是Basic/IFS的分区 |
| 749 | ($_.DriveLetter -ne $null -and $_.DriveLetter -ne '' -and $_.DriveLetter -match '[A-Z]') -or |
| 750 | (($_.Type -eq 'Basic' -or $_.Type -eq 'IFS') -and ($_.DriveLetter -eq $null -or $_.DriveLetter -eq '')) |
| 751 | } |
| 752 | $PartitionCount = if ($Partitions) { @($Partitions).Count } else { 0 } |
| 753 | $PartitionStyle = if ($Disk.PartitionStyle -eq "RAW") { "未初始化" } else { $Disk.PartitionStyle } |
| 754 | |
| 755 | # 构建更详细的磁盘信息 |
| 756 | $DiskInfo = "磁盘 $($Disk.Number) - $($Disk.Model) - $([math]::Round($Disk.Size / 1GB, 2)) GB - $PartitionStyle - $PartitionCount 个分区" |
| 757 | $DiskComboBox.Items.Add($DiskInfo) | Out-Null |
| 758 | |
| 759 | # 检查是否是之前选择的磁盘 |
| 760 | if ($Disk.Number -eq $PreviouslySelectedDiskNumber) { |
| 761 | $NewSelectedIndex = $DiskComboBox.Items.Count - 1 |
| 762 | } |
| 763 | |
| 764 | # === 调试信息开始 === |
| 765 | Write-Host "=== 调试信息 - 磁盘 $($Disk.Number) ===" -ForegroundColor Yellow |
| 766 | Write-Host "磁盘型号: $($Disk.Model)" -ForegroundColor Cyan |
| 767 | Write-Host "分区表类型: $($Disk.PartitionStyle)" -ForegroundColor Cyan |
| 768 | |
| 769 | if ($Partitions) { |
| 770 | Write-Host "找到 $($Partitions.Count) 个分区:" -ForegroundColor Green |
| 771 | foreach ($Part in $Partitions) { |
| 772 | $SizeGB = [math]::Round($Part.Size / 1GB, 2) |
| 773 | $DriveLetter = if ($Part.DriveLetter) { $Part.DriveLetter } else { "无" } |
| 774 | Write-Host " 分区 $($Part.PartitionNumber): 类型=$($Part.Type), 大小=$SizeGB GB, 盘符=$DriveLetter" -ForegroundColor White |
| 775 | } |
| 776 | } else { |
| 777 | Write-Host "没有找到分区" -ForegroundColor Red |
| 778 | } |
| 779 | Write-Host "=== 调试信息结束 ===" -ForegroundColor Yellow |
| 780 | # === 调试信息结束 === |
| 781 | } |
| 782 | |
| 783 | # 设置选择 |
| 784 | if ($NewSelectedIndex -ge 0) { |
| 785 | $DiskComboBox.SelectedIndex = $NewSelectedIndex |
| 786 | } elseif ($script:Disks.Count -gt 0) { |
| 787 | $DiskComboBox.SelectedIndex = 0 |
| 788 | } else { |
| 789 | $DiskComboBox.SelectedIndex = -1 |
| 790 | } |
| 791 | |
| 792 | # 更新状态显示 |
| 793 | $DiskCount = $script:Disks.Count |
| 794 | if ($DiskCount -eq 0) { |
| 795 | $StatusText.Text = "刷新完成!未找到可用的其他硬盘。" |
| 796 | $StatusText.Foreground = 'Orange' |
| 797 | } else { |
| 798 | $StatusText.Text = "刷新完成!找到 $DiskCount 个可用磁盘。" |
| 799 | $StatusText.Foreground = 'Green' |
| 800 | |
| 801 | # 显示当前选择的磁盘信息(使用过滤后的分区计数) |
| 802 | $CurrentIndex = $DiskComboBox.SelectedIndex |
| 803 | if ($CurrentIndex -ge 0) { |
| 804 | $CurrentDisk = $script:Disks[$CurrentIndex] |
| 805 | $Partitions = Get-Partition -DiskNumber $CurrentDisk.Number -ErrorAction SilentlyContinue | Where-Object { |
| 806 | ($_.DriveLetter -ne $null -and $_.DriveLetter -ne '' -and $_.DriveLetter -match '[A-Z]') -or |
| 807 | (($_.Type -eq 'Basic' -or $_.Type -eq 'IFS') -and ($_.DriveLetter -eq $null -or $_.DriveLetter -eq '')) |
| 808 | } |
| 809 | $PartitionCount = if ($Partitions) { @($Partitions).Count } else { 0 } |
| 810 | $StatusText.Text += " 当前选择: 磁盘 $($CurrentDisk.Number) ($PartitionCount 个分区)" |
| 811 | } |
| 812 | } |
| 813 | |
| 814 | Write-Host "刷新完成,找到 $DiskCount 个可用磁盘" -ForegroundColor Green |
| 815 | |
| 816 | # 如果有磁盘,显示详细信息 |
| 817 | if ($DiskCount -gt 0) { |
| 818 | Write-Host "可用磁盘列表:" -ForegroundColor Cyan |
| 819 | foreach ($Disk in $script:Disks) { |
| 820 | $Partitions = Get-Partition -DiskNumber $Disk.Number -ErrorAction SilentlyContinue | Where-Object { |
| 821 | ($_.DriveLetter -ne $null -and $_.DriveLetter -ne '' -and $_.DriveLetter -match '[A-Z]') -or |
| 822 | (($_.Type -eq 'Basic' -or $_.Type -eq 'IFS') -and ($_.DriveLetter -eq $null -or $_.DriveLetter -eq '')) |
| 823 | } |
| 824 | $PartitionCount = if ($Partitions) { @($Partitions).Count } else { 0 } |
| 825 | Write-Host " 磁盘 $($Disk.Number): $($Disk.Model) - $([math]::Round($Disk.Size / 1GB, 2)) GB - $($Disk.PartitionStyle) - $PartitionCount 个分区" -ForegroundColor White |
| 826 | } |
| 827 | } |
| 828 | } |
| 829 | |
| 830 | |
| 831 | # 刷新按钮事件 |
| 832 | $RefreshButton.Add_Click({ |
| 833 | & $RefreshDiskList |
| 834 | }) |
| 835 | |
| 836 | # 查看分区信息按钮事件 |
| 837 | $DiskInfoButton.Add_Click({ |
| 838 | $SelectedDiskIndex = $DiskComboBox.SelectedIndex |
| 839 | if ($SelectedDiskIndex -eq -1) { |
| 840 | [System.Windows.MessageBox]::Show("请先选择磁盘。", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) |
| 841 | return |
| 842 | } |
| 843 | |
| 844 | $SelectedDisk = $Disks[$SelectedDiskIndex] |
| 845 | ShowDiskPartitionInfo -Disk $SelectedDisk |
| 846 | }) |
| 847 | |
| 848 | # 删除分区按钮事件 |
| 849 | $DeletePartitionsButton.Add_Click({ |
| 850 | $SelectedDiskIndex = $DiskComboBox.SelectedIndex |
| 851 | if ($SelectedDiskIndex -eq -1) { |
| 852 | [System.Windows.MessageBox]::Show("请先选择磁盘。", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) |
| 853 | return |
| 854 | } |
| 855 | |
| 856 | $SelectedDisk = $Disks[$SelectedDiskIndex] |
| 857 | DeleteAllPartitions -Disk $SelectedDisk -StatusText $StatusText -RefreshCallback $RefreshDiskList |
| 858 | }) |
| 859 | |
| 860 | # 开始分区按钮事件 |
| 861 | $StartButton.Add_Click({ |
| 862 | $SelectedDiskIndex = $DiskComboBox.SelectedIndex |
| 863 | if ($SelectedDiskIndex -eq -1) { |
| 864 | [System.Windows.MessageBox]::Show("请选择要分区的磁盘。", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) |
| 865 | return |
| 866 | } |
| 867 | |
| 868 | $SelectedDisk = $Disks[$SelectedDiskIndex] |
| 869 | $TotalSizeGB = [math]::Round($SelectedDisk.Size / 1GB, 2) |
| 870 | |
| 871 | # 获取配置参数 |
| 872 | $PartitionStyle = if ($PartitionStyleComboBox.SelectedIndex -eq 0) { "GPT" } else { "MBR" } |
| 873 | $FileSystem = @("NTFS", "FAT32", "exFAT")[$FileSystemComboBox.SelectedIndex] |
| 874 | $AllocationUnit = $AllocationUnitComboBox.SelectedItem |
| 875 | |
| 876 | # 根据选择的方案计算分区大小 |
| 877 | $PartitionSizes = @() |
| 878 | $SchemeIndex = $SchemeComboBox.SelectedIndex |
| 879 | |
| 880 | switch ($SchemeIndex) { |
| 881 | 0 { # 2个分区 |
| 882 | $Size = [math]::Round($TotalSizeGB / 2) |
| 883 | $PartitionSizes = @($Size, 0) |
| 884 | } |
| 885 | 1 { # 3个分区 |
| 886 | $Size = [math]::Round($TotalSizeGB / 3) |
| 887 | $PartitionSizes = @($Size, $Size, 0) |
| 888 | } |
| 889 | 2 { # 4个分区 |
| 890 | $Size = [math]::Round($TotalSizeGB / 4) |
| 891 | $PartitionSizes = @($Size, $Size, $Size, 0) |
| 892 | } |
| 893 | 3 { # 单个分区 |
| 894 | $PartitionSizes = @(0) |
| 895 | } |
| 896 | 4 { # 自定义分区 |
| 897 | $CustomText = $CustomTextBox.Text.Trim() |
| 898 | if ([string]::IsNullOrWhiteSpace($CustomText)) { |
| 899 | [System.Windows.MessageBox]::Show("请输入自定义分区容量。", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) |
| 900 | return |
| 901 | } |
| 902 | |
| 903 | $SizeStrings = $CustomText.Split(',') |
| 904 | $hasRemainingSpaceMarker = $false |
| 905 | foreach ($SizeStr in $SizeStrings) { |
| 906 | $TrimmedSize = $SizeStr.Trim() |
| 907 | if ($TrimmedSize -eq "MAX" -or $TrimmedSize -eq "0") { |
| 908 | if ($hasRemainingSpaceMarker) { |
| 909 | [System.Windows.MessageBox]::Show("错误:只能有一个分区标记为 MAX(剩余容量)。", "配置错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) |
| 910 | return |
| 911 | } |
| 912 | $PartitionSizes += 0 |
| 913 | $hasRemainingSpaceMarker = $true |
| 914 | } else { |
| 915 | $SizeInt = 0 |
| 916 | if ([int]::TryParse($TrimmedSize, [ref]$SizeInt) -and $SizeInt -gt 0) { |
| 917 | $PartitionSizes += $SizeInt |
| 918 | } else { |
| 919 | [System.Windows.MessageBox]::Show("分区容量必须是正整数或'MAX'。", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) |
| 920 | return |
| 921 | } |
| 922 | } |
| 923 | } |
| 924 | } |
| 925 | } |
| 926 | |
| 927 | # 确认对话框 |
| 928 | $PartitionSummary = "磁盘: $($SelectedDisk.Model)`n" |
| 929 | $PartitionSummary += "总容量: $TotalSizeGB GB`n" |
| 930 | $PartitionSummary += "分区表: $PartitionStyle`n" |
| 931 | $PartitionSummary += "文件系统: $FileSystem`n" |
| 932 | $PartitionSummary += "分配单元: $AllocationUnit`n" |
| 933 | $PartitionSummary += "分区方案: $($SchemeComboBox.SelectedItem)`n" |
| 934 | $PartitionSummary += "分区数量: $($PartitionSizes.Count)`n" |
| 935 | for ($i = 0; $i -lt $PartitionSizes.Count; $i++) { |
| 936 | if ($PartitionSizes[$i] -gt 0) { |
| 937 | $PartitionSummary += "分区 $($i+1): $($PartitionSizes[$i]) GB`n" |
| 938 | } else { |
| 939 | $PartitionSummary += "分区 $($i+1): MAX (所有剩余容量)`n" |
| 940 | } |
| 941 | } |
| 942 | |
| 943 | $Result = [System.Windows.MessageBox]::Show( |
| 944 | "确定要对磁盘 $($SelectedDisk.Number) 执行分区操作吗?`n`n$PartitionSummary`n`n此操作将永久删除磁盘上的所有数据!", |
| 945 | "确认分区操作", |
| 946 | [System.Windows.MessageBoxButton]::YesNo, |
| 947 | [System.Windows.MessageBoxImage]::Warning |
| 948 | ) |
| 949 | |
| 950 | if ($Result -eq 'No') { |
| 951 | return |
| 952 | } |
| 953 | |
| 954 | # 执行分区操作,完成后自动刷新 |
| 955 | ExecuteOtherDiskPartition -Disk $SelectedDisk -PartitionSizes $PartitionSizes -PartitionStyle $PartitionStyle -FileSystem $FileSystem -AllocationUnit $AllocationUnit -StatusText $StatusText -RefreshCallback $RefreshDiskList |
| 956 | }) |
| 957 | |
| 958 | # 初始化时自动刷新一次 |
| 959 | & $RefreshDiskList |
| 960 | |
| 961 | $CancelButton.Add_Click({ |
| 962 | $OtherDiskWindow.Close() |
| 963 | }) |
| 964 | |
| 965 | $OtherDiskWindow.Content = $OtherDiskGrid |
| 966 | $OtherDiskWindow.ShowDialog() | Out-Null |
| 967 | } |
| 968 | |
| 969 | |
| 970 | |
| 971 | |
| 972 | |
| 973 | |
| 974 | |
| 975 | |
| 976 | # 第四部分:C盘分区工具相关函数 |
| 977 | |
| 978 | |
| 979 | function CreateCPartitionWindow { |
| 980 | $PartitionWindow = New-Object System.Windows.Window |
| 981 | $PartitionWindow.Title = "系统盘分区工具" |
| 982 | $PartitionWindow.Height = 355 # 初始高度降低 |
| 983 | $PartitionWindow.Width = 600 |
| 984 | $PartitionWindow.WindowStartupLocation = 'CenterOwner' |
| 985 | $PartitionWindow.Owner = $MainWindow |
| 986 | $PartitionWindow.Topmost = $true |
| 987 | $PartitionWindow.ResizeMode = 'NoResize' |
| 988 | |
| 989 | # 创建主网格 |
| 990 | $PartitionGrid = New-Object System.Windows.Controls.Grid |
| 991 | $PartitionGrid.Margin = New-Object System.Windows.Thickness(15) |
| 992 | |
| 993 | # 定义行(增加一行用于折叠说明) |
| 994 | for ($i = 0; $i -lt 10; $i++) { |
| 995 | $RowDef = New-Object System.Windows.Controls.RowDefinition |
| 996 | if ($i -eq 9) { |
| 997 | $RowDef.Height = '*' |
| 998 | } else { |
| 999 | $RowDef.Height = 'Auto' |
| 1000 | } |
| 1001 | $PartitionGrid.RowDefinitions.Add($RowDef) |
| 1002 | } |
| 1003 | |
| 1004 | # 定义列 |
| 1005 | $PartitionGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '150'})) |
| 1006 | $PartitionGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '*'})) |
| 1007 | $PartitionGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '30'})) |
| 1008 | |
| 1009 | # 标题 |
| 1010 | $TitleLabel = New-Object System.Windows.Controls.Label |
| 1011 | $TitleLabel.Content = "系统盘分区设置" |
| 1012 | $TitleLabel.FontSize = 16 |
| 1013 | $TitleLabel.FontWeight = 'Bold' |
| 1014 | $TitleLabel.HorizontalAlignment = 'Center' |
| 1015 | $TitleLabel.Margin = '0,0,0,15' |
| 1016 | $TitleLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 0) |
| 1017 | $TitleLabel.SetValue([System.Windows.Controls.Grid]::ColumnSpanProperty, 3) |
| 1018 | $PartitionGrid.Children.Add($TitleLabel) |
| 1019 | |
| 1020 | # 当前C盘大小显示 |
| 1021 | $CurrentSizeLabel = New-Object System.Windows.Controls.Label |
| 1022 | $CVolume = Get-Volume -DriveLetter C |
| 1023 | $CurrentSizeGB = [math]::Round($CVolume.Size / 1GB, 2) |
| 1024 | $CurrentSizeLabel.Content = "当前系统盘大小:" |
| 1025 | $CurrentSizeLabel.VerticalAlignment = 'Center' |
| 1026 | $CurrentSizeLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 1) |
| 1027 | $CurrentSizeLabel.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) |
| 1028 | $PartitionGrid.Children.Add($CurrentSizeLabel) |
| 1029 | |
| 1030 | $CurrentSizeValue = New-Object System.Windows.Controls.Label |
| 1031 | $CurrentSizeValue.Content = "$CurrentSizeGB GB" |
| 1032 | $CurrentSizeValue.FontWeight = 'Bold' |
| 1033 | $CurrentSizeValue.Foreground = 'Green' |
| 1034 | $CurrentSizeValue.VerticalAlignment = 'Center' |
| 1035 | $CurrentSizeValue.SetValue([System.Windows.Controls.Grid]::RowProperty, 1) |
| 1036 | $CurrentSizeValue.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) |
| 1037 | $PartitionGrid.Children.Add($CurrentSizeValue) |
| 1038 | |
| 1039 | # 压缩C盘大小输入 |
| 1040 | $ShrinkLabel = New-Object System.Windows.Controls.Label |
| 1041 | $ShrinkLabel.Content = "压缩系统盘到 (GB):" |
| 1042 | $ShrinkLabel.VerticalAlignment = 'Center' |
| 1043 | $ShrinkLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 2) |
| 1044 | $ShrinkLabel.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) |
| 1045 | $PartitionGrid.Children.Add($ShrinkLabel) |
| 1046 | |
| 1047 | $ShrinkTextBox = New-Object System.Windows.Controls.TextBox |
| 1048 | $ShrinkTextBox.Name = "ShrinkSize" |
| 1049 | $ShrinkTextBox.Margin = '5' |
| 1050 | $ShrinkTextBox.Height = 25 |
| 1051 | $ShrinkTextBox.VerticalAlignment = 'Center' |
| 1052 | $ShrinkTextBox.VerticalContentAlignment = 'Center' # 添加这行 |
| 1053 | $ShrinkTextBox.SetValue([System.Windows.Controls.Grid]::RowProperty, 2) |
| 1054 | $ShrinkTextBox.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) |
| 1055 | $PartitionGrid.Children.Add($ShrinkTextBox) |
| 1056 | |
| 1057 | # 第一个新分区大小输入 |
| 1058 | $NewPartLabel1 = New-Object System.Windows.Controls.Label |
| 1059 | $NewPartLabel1.Content = "第一个新分区大小 (GB):" |
| 1060 | $NewPartLabel1.VerticalAlignment = 'Center' |
| 1061 | $NewPartLabel1.SetValue([System.Windows.Controls.Grid]::RowProperty, 3) |
| 1062 | $NewPartLabel1.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) |
| 1063 | $PartitionGrid.Children.Add($NewPartLabel1) |
| 1064 | |
| 1065 | $NewPartTextBox1 = New-Object System.Windows.Controls.TextBox |
| 1066 | $NewPartTextBox1.Name = "NewPartitionSize1" |
| 1067 | $NewPartTextBox1.Margin = '5' |
| 1068 | $NewPartTextBox1.Height = 25 |
| 1069 | $NewPartTextBox1.VerticalAlignment = 'Center' |
| 1070 | $NewPartTextBox1.VerticalContentAlignment = 'Center' # 添加这行 |
| 1071 | $NewPartTextBox1.SetValue([System.Windows.Controls.Grid]::RowProperty, 3) |
| 1072 | $NewPartTextBox1.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) |
| 1073 | $PartitionGrid.Children.Add($NewPartTextBox1) |
| 1074 | |
| 1075 | # 第二个新分区大小输入 |
| 1076 | $NewPartLabel2 = New-Object System.Windows.Controls.Label |
| 1077 | $NewPartLabel2.Content = "第二个新分区大小 (GB):" |
| 1078 | $NewPartLabel2.VerticalAlignment = 'Center' |
| 1079 | $NewPartLabel2.SetValue([System.Windows.Controls.Grid]::RowProperty, 4) |
| 1080 | $NewPartLabel2.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) |
| 1081 | $PartitionGrid.Children.Add($NewPartLabel2) |
| 1082 | |
| 1083 | $NewPartTextBox2 = New-Object System.Windows.Controls.TextBox |
| 1084 | $NewPartTextBox2.Name = "NewPartitionSize2" |
| 1085 | $NewPartTextBox2.Margin = '5' |
| 1086 | $NewPartTextBox2.Height = 25 |
| 1087 | $NewPartTextBox2.VerticalAlignment = 'Center' |
| 1088 | $NewPartTextBox2.VerticalContentAlignment = 'Center' # 添加这行 |
| 1089 | $NewPartTextBox2.SetValue([System.Windows.Controls.Grid]::RowProperty, 4) |
| 1090 | $NewPartTextBox2.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) |
| 1091 | $PartitionGrid.Children.Add($NewPartTextBox2) |
| 1092 | |
| 1093 | # 计算可用空间显示 |
| 1094 | $AvailableSpaceLabel = New-Object System.Windows.Controls.Label |
| 1095 | $AvailableSpaceLabel.Content = "剩余可用空间:" |
| 1096 | $AvailableSpaceLabel.VerticalAlignment = 'Center' |
| 1097 | $AvailableSpaceLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 5) |
| 1098 | $AvailableSpaceLabel.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) |
| 1099 | $PartitionGrid.Children.Add($AvailableSpaceLabel) |
| 1100 | |
| 1101 | $AvailableSpaceValue = New-Object System.Windows.Controls.Label |
| 1102 | $AvailableSpaceValue.Name = "AvailableSpaceValue" |
| 1103 | $AvailableSpaceValue.Content = "0 GB" |
| 1104 | $AvailableSpaceValue.FontWeight = 'Bold' |
| 1105 | $AvailableSpaceValue.Foreground = 'Blue' |
| 1106 | $AvailableSpaceValue.VerticalAlignment = 'Center' |
| 1107 | $AvailableSpaceValue.SetValue([System.Windows.Controls.Grid]::RowProperty, 5) |
| 1108 | $AvailableSpaceValue.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) |
| 1109 | $PartitionGrid.Children.Add($AvailableSpaceValue) |
| 1110 | |
| 1111 | # 按钮区域 |
| 1112 | $ButtonStack = New-Object System.Windows.Controls.StackPanel |
| 1113 | $ButtonStack.Orientation = 'Horizontal' |
| 1114 | $ButtonStack.HorizontalAlignment = 'Center' |
| 1115 | $ButtonStack.Margin = '0,20,0,10' |
| 1116 | $ButtonStack.SetValue([System.Windows.Controls.Grid]::RowProperty, 6) |
| 1117 | $ButtonStack.SetValue([System.Windows.Controls.Grid]::ColumnSpanProperty, 3) |
| 1118 | $PartitionGrid.Children.Add($ButtonStack) |
| 1119 | |
| 1120 | $StartButton = New-Object System.Windows.Controls.Button |
| 1121 | $StartButton.Content = "开始分区" |
| 1122 | $StartButton.Width = 100 |
| 1123 | $StartButton.Height = 35 |
| 1124 | $StartButton.FontSize = 12 |
| 1125 | $StartButton.Background = '#4CAF50' |
| 1126 | $StartButton.Foreground = 'White' |
| 1127 | $StartButton.Margin = '0,0,10,0' |
| 1128 | $ButtonStack.Children.Add($StartButton) |
| 1129 | |
| 1130 | # 显示说明按钮 |
| 1131 | $ToggleInstructionsButton = New-Object System.Windows.Controls.Button |
| 1132 | $ToggleInstructionsButton.Content = "显示说明" |
| 1133 | $ToggleInstructionsButton.Width = 100 |
| 1134 | $ToggleInstructionsButton.Height = 35 |
| 1135 | $ToggleInstructionsButton.FontSize = 12 |
| 1136 | $ToggleInstructionsButton.Background = '#607D8B' |
| 1137 | $ToggleInstructionsButton.Foreground = 'White' |
| 1138 | $ToggleInstructionsButton.Margin = '0,0,10,0' |
| 1139 | $ButtonStack.Children.Add($ToggleInstructionsButton) |
| 1140 | |
| 1141 | $CancelButton = New-Object System.Windows.Controls.Button |
| 1142 | $CancelButton.Content = "取消" |
| 1143 | $CancelButton.Width = 100 |
| 1144 | $CancelButton.Height = 35 |
| 1145 | $CancelButton.FontSize = 12 |
| 1146 | $ButtonStack.Children.Add($CancelButton) |
| 1147 | |
| 1148 | $InstructionGrid = New-Object System.Windows.Controls.Grid |
| 1149 | $InstructionGrid.Margin = '10,5,10,5' |
| 1150 | $InstructionGrid.Visibility = 'Collapsed' |
| 1151 | $InstructionGrid.SetValue([System.Windows.Controls.Grid]::RowProperty, 7) |
| 1152 | $InstructionGrid.SetValue([System.Windows.Controls.Grid]::ColumnSpanProperty, 3) |
| 1153 | |
| 1154 | # 创建3列 |
| 1155 | $InstructionGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '*'})) |
| 1156 | $InstructionGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '*'})) |
| 1157 | $InstructionGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = '*'})) |
| 1158 | $PartitionGrid.Children.Add($InstructionGrid) |
| 1159 | |
| 1160 | # 第一列 - 功能说明 |
| 1161 | $Col1Text = New-Object System.Windows.Controls.TextBlock |
| 1162 | $Col1Text.Text = @" |
| 1163 | 📋 功能说明 |
| 1164 | • 压缩C盘释放空间 |
| 1165 | • 创建1-3个新分区 |
| 1166 | • 自动分配盘符 |
| 1167 | • 自动格式化 |
| 1168 | |
| 1169 | ⚙️ 参数设置 |
| 1170 | - 必须小于当前大小 |
| 1171 | - 最少保留50GB+系统空间 |
| 1172 | - 输入正整数(GB) |
| 1173 | - 留空表示不创建 |
| 1174 | - 剩余空间自动分区 |
| 1175 | "@ |
| 1176 | $Col1Text.FontSize = 10 |
| 1177 | $Col1Text.Foreground = 'Gray' |
| 1178 | $Col1Text.TextWrapping = 'Wrap' |
| 1179 | $Col1Text.Margin = '5' |
| 1180 | $Col1Text.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 0) |
| 1181 | $InstructionGrid.Children.Add($Col1Text) |
| 1182 | |
| 1183 | # 第二列 - 注意事项 |
| 1184 | $Col2Text = New-Object System.Windows.Controls.TextBlock |
| 1185 | $Col2Text.Text = @" |
| 1186 | 🛡️ 注意事项 |
| 1187 | • 谨慎操作防止数据丢失 |
| 1188 | • 确保足够可用空间 |
| 1189 | • 操作期间勿断电 |
| 1190 | • 关闭运行的程序 |
| 1191 | |
| 1192 | 📊 示例演示 |
| 1193 | 当前C盘:930GB |
| 1194 | 压缩到:200GB |
| 1195 | → 释放730GB空间 |
| 1196 | - C区:200GB |
| 1197 | - D区:730GB (自动) |
| 1198 | "@ |
| 1199 | $Col2Text.FontSize = 10 |
| 1200 | $Col2Text.Foreground = 'Gray' |
| 1201 | $Col2Text.TextWrapping = 'Wrap' |
| 1202 | $Col2Text.Margin = '5' |
| 1203 | $Col2Text.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 1) |
| 1204 | $InstructionGrid.Children.Add($Col2Text) |
| 1205 | |
| 1206 | # 第三列 - 操作提示 |
| 1207 | $Col3Text = New-Object System.Windows.Controls.TextBlock |
| 1208 | $Col3Text.Text = @" |
| 1209 | 🎯 操作提示 |
| 1210 | 1. 输入压缩后大小 |
| 1211 | 2. 设置新分区大小 |
| 1212 | 3. 点击开始分区 |
| 1213 | 4. 等待操作完成 |
| 1214 | |
| 1215 | ✅ 完成检查 |
| 1216 | • 查看新盘符 |
| 1217 | • 验证分区大小 |
| 1218 | • 脚本执行完毕请检查 |
| 1219 | "@ |
| 1220 | $Col3Text.FontSize = 10 |
| 1221 | $Col3Text.Foreground = 'Gray' |
| 1222 | $Col3Text.TextWrapping = 'Wrap' |
| 1223 | $Col3Text.Margin = '5' |
| 1224 | $Col3Text.SetValue([System.Windows.Controls.Grid]::ColumnProperty, 2) |
| 1225 | $InstructionGrid.Children.Add($Col3Text) |
| 1226 | |
| 1227 | # 折叠按钮事件 |
| 1228 | $ToggleInstructionsButton.Add_Click({ |
| 1229 | if ($InstructionGrid.Visibility -eq 'Visible') { |
| 1230 | $InstructionGrid.Visibility = 'Collapsed' |
| 1231 | $ToggleInstructionsButton.Content = "显示说明" |
| 1232 | $PartitionWindow.Height = 355 |
| 1233 | } else { |
| 1234 | $InstructionGrid.Visibility = 'Visible' |
| 1235 | $ToggleInstructionsButton.Content = "隐藏说明" |
| 1236 | $PartitionWindow.Height = 530 |
| 1237 | } |
| 1238 | }) |
| 1239 | |
| 1240 | # 状态显示 |
| 1241 | $StatusText = New-Object System.Windows.Controls.TextBlock |
| 1242 | $StatusText.Name = "StatusText" |
| 1243 | $StatusText.Text = "等待操作..." |
| 1244 | $StatusText.FontSize = 10 |
| 1245 | $StatusText.Foreground = 'Blue' |
| 1246 | $StatusText.TextWrapping = 'Wrap' |
| 1247 | $StatusText.Margin = '10,5,10,5' |
| 1248 | $StatusText.SetValue([System.Windows.Controls.Grid]::RowProperty, 8) |
| 1249 | $StatusText.SetValue([System.Windows.Controls.Grid]::ColumnSpanProperty, 3) |
| 1250 | $PartitionGrid.Children.Add($StatusText) |
| 1251 | |
| 1252 | # 实时计算可用空间的函数 |
| 1253 | $CalculateAvailableSpace = { |
| 1254 | $ShrinkSizeText = $ShrinkTextBox.Text |
| 1255 | $NewPart1Text = $NewPartTextBox1.Text |
| 1256 | $NewPart2Text = $NewPartTextBox2.Text |
| 1257 | |
| 1258 | $CVolume = Get-Volume -DriveLetter C |
| 1259 | $CurrentSizeGB = [math]::Round($CVolume.Size / 1GB, 2) |
| 1260 | |
| 1261 | if ([string]::IsNullOrWhiteSpace($ShrinkSizeText)) { |
| 1262 | $AvailableSpaceValue.Content = "$CurrentSizeGB GB" |
| 1263 | return |
| 1264 | } |
| 1265 | |
| 1266 | $ShrinkSizeInt = 0 |
| 1267 | if ([int]::TryParse($ShrinkSizeText, [ref]$ShrinkSizeInt)) { |
| 1268 | $AvailableSpace = $CurrentSizeGB - $ShrinkSizeInt |
| 1269 | |
| 1270 | $NewPart1Int = 0 |
| 1271 | if (-not [string]::IsNullOrWhiteSpace($NewPart1Text)) { |
| 1272 | [int]::TryParse($NewPart1Text, [ref]$NewPart1Int) |
| 1273 | } |
| 1274 | |
| 1275 | $NewPart2Int = 0 |
| 1276 | if (-not [string]::IsNullOrWhiteSpace($NewPart2Text)) { |
| 1277 | [int]::TryParse($NewPart2Text, [ref]$NewPart2Int) |
| 1278 | } |
| 1279 | |
| 1280 | $RemainingSpace = $AvailableSpace - $NewPart1Int - $NewPart2Int |
| 1281 | $AvailableSpaceValue.Content = "$AvailableSpace GB (剩余: $RemainingSpace GB)" |
| 1282 | |
| 1283 | if ($RemainingSpace -lt 0) { |
| 1284 | $AvailableSpaceValue.Foreground = 'Red' |
| 1285 | } else { |
| 1286 | $AvailableSpaceValue.Foreground = 'Blue' |
| 1287 | } |
| 1288 | } |
| 1289 | } |
| 1290 | |
| 1291 | # 添加文本框变化事件 |
| 1292 | $ShrinkTextBox.Add_TextChanged({ |
| 1293 | & $CalculateAvailableSpace |
| 1294 | }) |
| 1295 | |
| 1296 | $NewPartTextBox1.Add_TextChanged({ |
| 1297 | & $CalculateAvailableSpace |
| 1298 | }) |
| 1299 | |
| 1300 | $NewPartTextBox2.Add_TextChanged({ |
| 1301 | & $CalculateAvailableSpace |
| 1302 | }) |
| 1303 | |
| 1304 | # 初始化可用空间显示 |
| 1305 | & $CalculateAvailableSpace |
| 1306 | |
| 1307 | # 按钮事件处理 |
| 1308 | $StartButton.Add_Click({ |
| 1309 | $ShrinkSize = $ShrinkTextBox.Text.Trim() |
| 1310 | $NewPartitionSize1 = $NewPartTextBox1.Text.Trim() |
| 1311 | $NewPartitionSize2 = $NewPartTextBox2.Text.Trim() |
| 1312 | |
| 1313 | # 验证输入 |
| 1314 | if (-not (ValidateCInput -ShrinkSize $ShrinkSize -NewPartitionSize1 $NewPartitionSize1 -NewPartitionSize2 $NewPartitionSize2 -StatusText $StatusText)) { |
| 1315 | return |
| 1316 | } |
| 1317 | |
| 1318 | # 确认对话框 |
| 1319 | $PartitionSummary = "压缩系统盘到: $script:ShrinkSizeInt GB`n" |
| 1320 | if ($script:NewPartitionSize1Int -gt 0) { |
| 1321 | $PartitionSummary += "第一个新分区: $script:NewPartitionSize1Int GB`n" |
| 1322 | } |
| 1323 | if ($script:NewPartitionSize2Int -gt 0) { |
| 1324 | $PartitionSummary += "第二个新分区: $script:NewPartitionSize2Int GB`n" |
| 1325 | } |
| 1326 | $RemainingSpace = ($CurrentSizeGB - $script:ShrinkSizeInt) - $script:NewPartitionSize1Int - $script:NewPartitionSize2Int |
| 1327 | if ($RemainingSpace -gt 0) { |
| 1328 | $PartitionSummary += "剩余空间分区: $RemainingSpace GB`n" |
| 1329 | } |
| 1330 | |
| 1331 | $Result = [System.Windows.MessageBox]::Show( |
| 1332 | "确定要执行分区操作吗?`n`n$PartitionSummary`n此操作可能需要几分钟时间,请勿中断!", |
| 1333 | "确认分区操作", |
| 1334 | [System.Windows.MessageBoxButton]::YesNo, |
| 1335 | [System.Windows.MessageBoxImage]::Warning |
| 1336 | ) |
| 1337 | |
| 1338 | if ($Result -eq 'No') { |
| 1339 | return |
| 1340 | } |
| 1341 | |
| 1342 | # 禁用按钮防止重复点击 |
| 1343 | $StartButton.IsEnabled = $false |
| 1344 | $CancelButton.IsEnabled = $false |
| 1345 | $ToggleInstructionsButton.IsEnabled = $false |
| 1346 | $StatusText.Text = "正在执行分区操作,请稍候..." |
| 1347 | $StatusText.Foreground = 'Orange' |
| 1348 | |
| 1349 | # 执行分区操作 |
| 1350 | ExecuteCPartitionOperation -ShrinkSizeInt $script:ShrinkSizeInt -NewPartitionSize1Int $script:NewPartitionSize1Int -NewPartitionSize2Int $script:NewPartitionSize2Int -StatusText $StatusText -StartButton $StartButton -CancelButton $CancelButton -ToggleButton $ToggleInstructionsButton |
| 1351 | }) |
| 1352 | |
| 1353 | $CancelButton.Add_Click({ |
| 1354 | $PartitionWindow.Close() |
| 1355 | }) |
| 1356 | |
| 1357 | $PartitionWindow.Content = $PartitionGrid |
| 1358 | $PartitionWindow.ShowDialog() | Out-Null |
| 1359 | } |
| 1360 | |
| 1361 | function ValidateCInput { |
| 1362 | param($ShrinkSize, $NewPartitionSize1, $NewPartitionSize2, $StatusText) |
| 1363 | |
| 1364 | # 验证压缩大小 |
| 1365 | if ([string]::IsNullOrWhiteSpace($ShrinkSize)) { |
| 1366 | $StatusText.Text = "错误:请输入压缩大小" |
| 1367 | $StatusText.Foreground = 'Red' |
| 1368 | return $false |
| 1369 | } |
| 1370 | |
| 1371 | $script:ShrinkSizeInt = 0 |
| 1372 | if (-not ([int]::TryParse($ShrinkSize, [ref]$script:ShrinkSizeInt)) -or $script:ShrinkSizeInt -le 0) { |
| 1373 | $StatusText.Text = "错误:压缩大小必须是正整数" |
| 1374 | $StatusText.Foreground = 'Red' |
| 1375 | return $false |
| 1376 | } |
| 1377 | |
| 1378 | # 获取当前C盘大小 |
| 1379 | $CVolume = Get-Volume -DriveLetter C |
| 1380 | $CurrentSizeGB = [math]::Round($CVolume.Size / 1GB, 2) |
| 1381 | if ($script:ShrinkSizeInt -ge $CurrentSizeGB) { |
| 1382 | $StatusText.Text = "错误:压缩大小必须小于当前系统盘大小 ($CurrentSizeGB GB)" |
| 1383 | $StatusText.Foreground = 'Red' |
| 1384 | return $false |
| 1385 | } |
| 1386 | |
| 1387 | # 验证第一个新分区大小(可选) |
| 1388 | $script:NewPartitionSize1Int = 0 |
| 1389 | if (-not [string]::IsNullOrWhiteSpace($NewPartitionSize1)) { |
| 1390 | if (-not ([int]::TryParse($NewPartitionSize1, [ref]$script:NewPartitionSize1Int)) -or $script:NewPartitionSize1Int -le 0) { |
| 1391 | $StatusText.Text = "错误:第一个新分区大小必须是正整数" |
| 1392 | $StatusText.Foreground = 'Red' |
| 1393 | return $false |
| 1394 | } |
| 1395 | } |
| 1396 | |
| 1397 | # 验证第二个新分区大小(可选) |
| 1398 | $script:NewPartitionSize2Int = 0 |
| 1399 | if (-not [string]::IsNullOrWhiteSpace($NewPartitionSize2)) { |
| 1400 | if (-not ([int]::TryParse($NewPartitionSize2, [ref]$script:NewPartitionSize2Int)) -or $script:NewPartitionSize2Int -le 0) { |
| 1401 | $StatusText.Text = "错误:第二个新分区大小必须是正整数" |
| 1402 | $StatusText.Foreground = 'Red' |
| 1403 | return $false |
| 1404 | } |
| 1405 | } |
| 1406 | |
| 1407 | # 检查总分区大小是否合理 |
| 1408 | $TotalNewPartitionSize = $script:NewPartitionSize1Int + $script:NewPartitionSize2Int |
| 1409 | $AvailableSize = $CurrentSizeGB - $script:ShrinkSizeInt |
| 1410 | if ($TotalNewPartitionSize -gt $AvailableSize) { |
| 1411 | $StatusText.Text = "错误:新分区总大小 ($TotalNewPartitionSize GB) 不能大于可用空间 ($AvailableSize GB)" |
| 1412 | $StatusText.Foreground = 'Red' |
| 1413 | return $false |
| 1414 | } |
| 1415 | |
| 1416 | $StatusText.Text = "输入验证通过,准备执行分区操作..." |
| 1417 | $StatusText.Foreground = 'Green' |
| 1418 | return $true |
| 1419 | } |
| 1420 | |
| 1421 | function ExecuteCPartitionOperation { |
| 1422 | param($ShrinkSizeInt, $NewPartitionSize1Int, $NewPartitionSize2Int, $StatusText, $StartButton, $CancelButton, $ToggleButton) |
| 1423 | |
| 1424 | try { |
| 1425 | $StatusText.Text = "正在调整分区大小..." |
| 1426 | $StatusText.Foreground = 'Orange' |
| 1427 | |
| 1428 | # 获取磁盘信息 |
| 1429 | $Disk = Get-Partition -DriveLetter C | Get-Disk |
| 1430 | $DiskNumber = $Disk.Number |
| 1431 | |
| 1432 | # 调整分区大小 |
| 1433 | Resize-Partition -DriveLetter C -Size ($ShrinkSizeInt * 1GB) -ErrorAction Stop |
| 1434 | $StatusText.Text = "分区调整完成,正在创建新分区..." |
| 1435 | |
| 1436 | # 获取调整后的C盘大小 |
| 1437 | $CVolume = Get-Volume -DriveLetter C |
| 1438 | $NewCSizeGB = [math]::Round($CVolume.Size / 1GB, 2) |
| 1439 | |
| 1440 | # 创建第一个新分区(如果需要) |
| 1441 | if ($NewPartitionSize1Int -gt 0) { |
| 1442 | $NewPartition1 = New-Partition -DiskNumber $DiskNumber -Size ($NewPartitionSize1Int * 1GB) -AssignDriveLetter -ErrorAction Stop |
| 1443 | if ($NewPartition1) { |
| 1444 | Format-Volume -DriveLetter $NewPartition1.DriveLetter -FileSystem NTFS -Confirm:$false -ErrorAction Stop |
| 1445 | $StatusText.Text = "第一个新分区创建完成,正在创建第二个新分区..." |
| 1446 | Write-Host "-- 第一个新分区创建成功,盘符: $($NewPartition1.DriveLetter)" -ForegroundColor Green |
| 1447 | } |
| 1448 | } |
| 1449 | |
| 1450 | # 创建第二个新分区(如果需要) |
| 1451 | if ($NewPartitionSize2Int -gt 0) { |
| 1452 | $NewPartition2 = New-Partition -DiskNumber $DiskNumber -Size ($NewPartitionSize2Int * 1GB) -AssignDriveLetter -ErrorAction Stop |
| 1453 | if ($NewPartition2) { |
| 1454 | Format-Volume -DriveLetter $NewPartition2.DriveLetter -FileSystem NTFS -Confirm:$false -ErrorAction Stop |
| 1455 | $StatusText.Text = "第二个新分区创建完成,正在处理剩余空间..." |
| 1456 | Write-Host "-- 第二个新分区创建成功,盘符: $($NewPartition2.DriveLetter)" -ForegroundColor Green |
| 1457 | } |
| 1458 | } |
| 1459 | |
| 1460 | # 处理剩余空间 |
| 1461 | $RemainingSize = (Get-Disk -Number $DiskNumber).Size - (Get-Disk -Number $DiskNumber).AllocatedSize |
| 1462 | if ($RemainingSize -gt 1GB) { |
| 1463 | $RemainingPartition = New-Partition -DiskNumber $DiskNumber -UseMaximumSize -AssignDriveLetter -ErrorAction Stop |
| 1464 | if ($RemainingPartition) { |
| 1465 | Format-Volume -DriveLetter $RemainingPartition.DriveLetter -FileSystem NTFS -Confirm:$false -ErrorAction Stop |
| 1466 | $StatusText.Text = "剩余空间分区创建完成" |
| 1467 | Write-Host "-- 剩余空间分区创建成功,盘符: $($RemainingPartition.DriveLetter)" -ForegroundColor Green |
| 1468 | } |
| 1469 | } |
| 1470 | |
| 1471 | $StatusText.Text = "分区操作完成!" |
| 1472 | $StatusText.Foreground = 'Green' |
| 1473 | |
| 1474 | [System.Windows.MessageBox]::Show("分区操作已完成!", "完成", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information) |
| 1475 | |
| 1476 | } catch { |
| 1477 | $StatusText.Text = "操作失败: $($_.Exception.Message)" |
| 1478 | $StatusText.Foreground = 'Red' |
| 1479 | [System.Windows.MessageBox]::Show("分区操作失败: $($_.Exception.Message)", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) |
| 1480 | } finally { |
| 1481 | # 重新启用按钮 |
| 1482 | $StartButton.IsEnabled = $true |
| 1483 | $CancelButton.IsEnabled = $true |
| 1484 | if ($ToggleButton) { |
| 1485 | $ToggleButton.IsEnabled = $true |
| 1486 | } |
| 1487 | } |
| 1488 | } |
| 1489 | |
| 1490 | |
| 1491 | |
| 1492 | |
| 1493 | |
| 1494 | # 第五部分:盘符理顺相关函数 |
| 1495 | |
| 1496 | function ReassignDriveLettersWithUI { |
| 1497 | $Result = [System.Windows.MessageBox]::Show( |
| 1498 | "确定要重新分配盘符吗?`n`n此操作将:`n- 保持系统盘符不变`n- 重新分配其他盘符`n- 按磁盘和分区顺序整理盘符", |
| 1499 | "确认盘符理顺", |
| 1500 | [System.Windows.MessageBoxButton]::YesNo, |
| 1501 | [System.Windows.MessageBoxImage]::Question |
| 1502 | ) |
| 1503 | |
| 1504 | if ($Result -eq 'Yes') { |
| 1505 | # 直接执行盘符理顺操作 |
| 1506 | try { |
| 1507 | Write-Host "-- 开始重新分配盘符..." -ForegroundColor Yellow |
| 1508 | |
| 1509 | # 获取系统盘符 |
| 1510 | $systemDriveLetter = (Get-WmiObject -Class Win32_OperatingSystem).SystemDrive.Replace(":", "").Trim() |
| 1511 | |
| 1512 | # 获取系统磁盘索引 |
| 1513 | $systemDiskIndex = (Get-Partition -DriveLetter $systemDriveLetter).DiskNumber |
| 1514 | |
| 1515 | # 预定义可用的盘符列表 |
| 1516 | $driveLetters = @('D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z') |
| 1517 | |
| 1518 | # 获取所有有效卷的信息 |
| 1519 | $volumes = Get-Volume | Where-Object { $_.DriveLetter -ne $null -and $_.DriveLetter -match '[A-Z]' -and $_.HealthStatus -eq 'Healthy' } |
| 1520 | |
| 1521 | # 获取所有卷的分区信息并记录 |
| 1522 | $partitions = @{} |
| 1523 | foreach ($volume in $volumes) { |
| 1524 | $partition = Get-Partition -DriveLetter $volume.DriveLetter |
| 1525 | $partitions[$volume.DriveLetter] = @{ |
| 1526 | 'DiskNumber' = $partition.DiskNumber |
| 1527 | 'PartitionNumber' = $partition.PartitionNumber |
| 1528 | } |
| 1529 | } |
| 1530 | |
| 1531 | # 获取系统磁盘上的卷和其他磁盘上的卷,并按PartitionNumber排序 |
| 1532 | $volumesOnSystemDisk = $volumes | Where-Object { $partitions[$_.DriveLetter]['DiskNumber'] -eq $systemDiskIndex } | Sort-Object -Property {$partitions[$_.DriveLetter]['PartitionNumber']} |
| 1533 | $volumesOnOtherDisks = $volumes | Where-Object { $partitions[$_.DriveLetter]['DiskNumber'] -ne $systemDiskIndex } | Sort-Object -Property {$partitions[$_.DriveLetter]['DiskNumber']}, {$partitions[$_.DriveLetter]['PartitionNumber']} |
| 1534 | |
| 1535 | # 打印所有有效卷的信息 |
| 1536 | Write-Host "-- 所有有效卷的信息:" |
| 1537 | $volumes | Format-Table -Property DriveLetter, DriveType, FileSystemLabel, HealthStatus |
| 1538 | |
| 1539 | Write-Host "-- 系统盘 $systemDriveLetter 不会更改或删除盘符" |
| 1540 | |
| 1541 | # 删除非系统盘的盘符 |
| 1542 | foreach ($volume in $volumes) { |
| 1543 | if ($volume.DriveLetter -eq $systemDriveLetter) { |
| 1544 | continue |
| 1545 | } |
| 1546 | |
| 1547 | try { |
| 1548 | $partitionInfo = $partitions[$volume.DriveLetter] |
| 1549 | Remove-PartitionAccessPath -DiskNumber $partitionInfo.DiskNumber -PartitionNumber $partitionInfo.PartitionNumber -AccessPath ($volume.DriveLetter + ":") -ErrorAction Stop |
| 1550 | Write-Host "-- 成功删除卷 $($volume.DriveLetter) 的盘符" |
| 1551 | } catch { |
| 1552 | Write-Warning "-- 无法删除卷 $($volume.DriveLetter) 的盘符: $($_.Exception.Message)" -ForegroundColor Red |
| 1553 | } |
| 1554 | } |
| 1555 | |
| 1556 | # 重新分配盘符 |
| 1557 | $index = 0 |
| 1558 | $availableDriveLetters = $driveLetters | Where-Object { $_ -notin @($systemDriveLetter) } |
| 1559 | |
| 1560 | # 先处理系统磁盘上的卷 |
| 1561 | foreach ($volume in $volumesOnSystemDisk) { |
| 1562 | if ($volume.DriveLetter -eq $systemDriveLetter) { |
| 1563 | continue |
| 1564 | } |
| 1565 | |
| 1566 | if ($index -lt $availableDriveLetters.Length) { |
| 1567 | $newLetter = $availableDriveLetters[$index] |
| 1568 | try { |
| 1569 | $partitionInfo = $partitions[$volume.DriveLetter] |
| 1570 | Add-PartitionAccessPath -DiskNumber $partitionInfo.DiskNumber -PartitionNumber $partitionInfo.PartitionNumber -AccessPath ($newLetter + ":") -ErrorAction Stop |
| 1571 | Write-Host "-- 成功将系统磁盘上的卷 $($volume.DriveLetter) 更改为盘符 $newLetter" -ForegroundColor Green |
| 1572 | } catch { |
| 1573 | Write-Warning "-- 无法更改系统磁盘上的卷 $($volume.DriveLetter) 的盘符: $($_.Exception.Message)" -ForegroundColor Red |
| 1574 | } |
| 1575 | $index++ |
| 1576 | } else { |
| 1577 | Write-Warning "-- 没有足够的可用盘符" -ForegroundColor Red |
| 1578 | } |
| 1579 | } |
| 1580 | |
| 1581 | # 再处理其他磁盘上的卷,按正确顺序分配盘符 |
| 1582 | foreach ($volume in $volumesOnOtherDisks) { |
| 1583 | if ($index -lt $availableDriveLetters.Length) { |
| 1584 | $newLetter = $availableDriveLetters[$index] |
| 1585 | try { |
| 1586 | $partitionInfo = $partitions[$volume.DriveLetter] |
| 1587 | Add-PartitionAccessPath -DiskNumber $partitionInfo.DiskNumber -PartitionNumber $partitionInfo.PartitionNumber -AccessPath ($newLetter + ":") -ErrorAction Stop |
| 1588 | Write-Host "-- 成功将其他磁盘上的卷 $($volume.DriveLetter) 更改为盘符 $newLetter" -ForegroundColor Yellow |
| 1589 | } catch { |
| 1590 | Write-Warning "-- 无法更改其他磁盘上的卷 $($volume.DriveLetter) 的盘符: $($_.Exception.Message)" -ForegroundColor Red |
| 1591 | } |
| 1592 | $index++ |
| 1593 | } else { |
| 1594 | Write-Warning "-- 没有足够的可用盘符" -ForegroundColor Red |
| 1595 | } |
| 1596 | } |
| 1597 | |
| 1598 | Write-Host "-- 盘符重新分配完成。" -ForegroundColor Green |
| 1599 | [System.Windows.MessageBox]::Show("盘符理顺操作已完成!", "完成", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information) |
| 1600 | |
| 1601 | } catch { |
| 1602 | Write-Host "-- 盘符重新分配时出错: $($_.Exception.Message)" -ForegroundColor Red |
| 1603 | [System.Windows.MessageBox]::Show("盘符理顺操作失败:$($_.Exception.Message)", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) |
| 1604 | } |
| 1605 | } |
| 1606 | } |
| 1607 | |
| 1608 | |
| 1609 | function ReassignDriveLetters { |
| 1610 | Write-Host "-- 开始重新分配盘符..." -ForegroundColor Yellow |
| 1611 | |
| 1612 | try { |
| 1613 | $SystemDriveLetter = (Get-WmiObject -Class Win32_OperatingSystem).SystemDrive.Replace(":", "").Trim() |
| 1614 | Write-Host "-- 系统盘符: $SystemDriveLetter" -ForegroundColor Green |
| 1615 | |
| 1616 | # 获取所有磁盘和分区 |
| 1617 | $Disks = Get-Disk | Where-Object { $_.OperationalStatus -eq 'Online' } |
| 1618 | |
| 1619 | foreach ($Disk in $Disks) { |
| 1620 | $Partitions = Get-Partition -DiskNumber $Disk.Number -ErrorAction SilentlyContinue |
| 1621 | $PartitionCount = if ($Partitions -and $Partitions.Count -gt 0) { $Partitions.Count } else { 0 } |
| 1622 | $PartitionStyle = if ($Disk.PartitionStyle -eq "RAW") { "未初始化" } else { $Disk.PartitionStyle } |
| 1623 | $DiskInfo = "磁盘 $($Disk.Number) - $($Disk.Model) - $([math]::Round($Disk.Size / 1GB, 2)) GB - $PartitionStyle - $PartitionCount 个分区" |
| 1624 | Write-Host "-- $DiskInfo" -ForegroundColor Cyan |
| 1625 | } |
| 1626 | |
| 1627 | Write-Host "-- 盘符重新分配完成。" -ForegroundColor Green |
| 1628 | } catch { |
| 1629 | Write-Host "-- 盘符重新分配时出错: $($_.Exception.Message)" -ForegroundColor Red |
| 1630 | } |
| 1631 | } |
| 1632 | |
| 1633 | |
| 1634 | |
| 1635 | |
| 1636 | |
| 1637 | |
| 1638 | |
| 1639 | # 保留原始函数供其他部分使用 |
| 1640 | function ReassignDriveLetters { |
| 1641 | Write-Host "-- 开始重新分配盘符..." -ForegroundColor Yellow |
| 1642 | |
| 1643 | # 获取系统盘符 |
| 1644 | $systemDriveLetter = (Get-WmiObject -Class Win32_OperatingSystem).SystemDrive.Replace(":", "").Trim() |
| 1645 | |
| 1646 | # 获取系统磁盘索引 |
| 1647 | $systemDiskIndex = (Get-Partition -DriveLetter $systemDriveLetter).DiskNumber |
| 1648 | |
| 1649 | # 预定义可用的盘符列表 |
| 1650 | $driveLetters = @('D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z') |
| 1651 | |
| 1652 | # 获取所有有效卷的信息 |
| 1653 | $volumes = Get-Volume | Where-Object { $_.DriveLetter -ne $null -and $_.DriveLetter -match '[A-Z]' -and $_.HealthStatus -eq 'Healthy' } |
| 1654 | |
| 1655 | # 获取所有卷的分区信息并记录 |
| 1656 | $partitions = @{} |
| 1657 | foreach ($volume in $volumes) { |
| 1658 | $partition = Get-Partition -DriveLetter $volume.DriveLetter |
| 1659 | $partitions[$volume.DriveLetter] = @{ |
| 1660 | 'DiskNumber' = $partition.DiskNumber |
| 1661 | 'PartitionNumber' = $partition.PartitionNumber |
| 1662 | } |
| 1663 | } |
| 1664 | |
| 1665 | # 获取系统磁盘上的卷和其他磁盘上的卷,并按PartitionNumber排序 |
| 1666 | $volumesOnSystemDisk = $volumes | Where-Object { $partitions[$_.DriveLetter]['DiskNumber'] -eq $systemDiskIndex } | Sort-Object -Property {$partitions[$_.DriveLetter]['PartitionNumber']} |
| 1667 | $volumesOnOtherDisks = $volumes | Where-Object { $partitions[$_.DriveLetter]['DiskNumber'] -ne $systemDiskIndex } | Sort-Object -Property {$partitions[$_.DriveLetter]['DiskNumber']}, {$partitions[$_.DriveLetter]['PartitionNumber']} |
| 1668 | |
| 1669 | # 打印所有有效卷的信息 |
| 1670 | Write-Host "-- 所有有效卷的信息:" |
| 1671 | $volumes | Format-Table -Property DriveLetter, DriveType, FileSystemLabel, HealthStatus |
| 1672 | |
| 1673 | Write-Host "-- 系统盘 $systemDriveLetter 不会更改或删除盘符" |
| 1674 | |
| 1675 | # 删除非系统盘的盘符 |
| 1676 | foreach ($volume in $volumes) { |
| 1677 | if ($volume.DriveLetter -eq $systemDriveLetter) { |
| 1678 | continue |
| 1679 | } |
| 1680 | |
| 1681 | try { |
| 1682 | $partitionInfo = $partitions[$volume.DriveLetter] |
| 1683 | Remove-PartitionAccessPath -DiskNumber $partitionInfo.DiskNumber -PartitionNumber $partitionInfo.PartitionNumber -AccessPath ($volume.DriveLetter + ":") -ErrorAction Stop |
| 1684 | Write-Host "-- 成功删除卷 $($volume.DriveLetter) 的盘符" |
| 1685 | } catch { |
| 1686 | Write-Warning "-- 无法删除卷 $($volume.DriveLetter) 的盘符: $($_.Exception.Message)" -ForegroundColor Red |
| 1687 | } |
| 1688 | } |
| 1689 | |
| 1690 | # 重新分配盘符 |
| 1691 | $index = 0 |
| 1692 | $availableDriveLetters = $driveLetters | Where-Object { $_ -notin @($systemDriveLetter) } |
| 1693 | |
| 1694 | # 先处理系统磁盘上的卷 |
| 1695 | foreach ($volume in $volumesOnSystemDisk) { |
| 1696 | if ($volume.DriveLetter -eq $systemDriveLetter) { |
| 1697 | continue |
| 1698 | } |
| 1699 | |
| 1700 | if ($index -lt $availableDriveLetters.Length) { |
| 1701 | $newLetter = $availableDriveLetters[$index] |
| 1702 | try { |
| 1703 | $partitionInfo = $partitions[$volume.DriveLetter] |
| 1704 | Add-PartitionAccessPath -DiskNumber $partitionInfo.DiskNumber -PartitionNumber $partitionInfo.PartitionNumber -AccessPath ($newLetter + ":") -ErrorAction Stop |
| 1705 | Write-Host "-- 成功将系统磁盘上的卷 $($volume.DriveLetter) 更改为盘符 $newLetter" -ForegroundColor Green |
| 1706 | } catch { |
| 1707 | Write-Warning "-- 无法更改系统磁盘上的卷 $($volume.DriveLetter) 的盘符: $($_.Exception.Message)" -ForegroundColor Red |
| 1708 | } |
| 1709 | $index++ |
| 1710 | } else { |
| 1711 | Write-Warning "-- 没有足够的可用盘符" -ForegroundColor Red |
| 1712 | } |
| 1713 | } |
| 1714 | |
| 1715 | # 再处理其他磁盘上的卷,按正确顺序分配盘符 |
| 1716 | foreach ($volume in $volumesOnOtherDisks) { |
| 1717 | if ($index -lt $availableDriveLetters.Length) { |
| 1718 | $newLetter = $availableDriveLetters[$index] |
| 1719 | try { |
| 1720 | $partitionInfo = $partitions[$volume.DriveLetter] |
| 1721 | Add-PartitionAccessPath -DiskNumber $partitionInfo.DiskNumber -PartitionNumber $partitionInfo.PartitionNumber -AccessPath ($newLetter + ":") -ErrorAction Stop |
| 1722 | Write-Host "-- 成功将其他磁盘上的卷 $($volume.DriveLetter) 更改为盘符 $newLetter" -ForegroundColor Yellow |
| 1723 | } catch { |
| 1724 | Write-Warning "-- 无法更改其他磁盘上的卷 $($volume.DriveLetter) 的盘符: $($_.Exception.Message)" -ForegroundColor Red |
| 1725 | } |
| 1726 | $index++ |
| 1727 | } else { |
| 1728 | Write-Warning "-- 没有足够的可用盘符" -ForegroundColor Red |
| 1729 | } |
| 1730 | } |
| 1731 | |
| 1732 | Write-Host "-- 盘符重新分配完成。" |
| 1733 | } |
| 1734 | |
| 1735 | |
| 1736 | |
| 1737 | |
| 1738 | |
| 1739 | |
| 1740 | |
| 1741 | |
| 1742 | |
| 1743 | # GUI 关闭回调 |
| 1744 | $MainWindow.Add_Closed({ |
| 1745 | # 创建退出标志文件 |
| 1746 | New-Item -Path "$env:TEMP\PartitionTool.done" -ItemType File -Force | Out-Null |
| 1747 | }) |
| 1748 | |
| 1749 | |
| 1750 | |
| 1751 | |
| 1752 | |
| 1753 | |
| 1754 | |
| 1755 | # 第六部分:主窗口和事件处理 |
| 1756 | |
| 1757 | |
| 1758 | |
| 1759 | |
| 1760 | |
| 1761 | # 创建主窗口 |
| 1762 | $MainWindow = New-Object System.Windows.Window |
| 1763 | |
| 1764 | # === Added: GUI close callback === |
| 1765 | $MainWindow.Add_Closed({ |
| 1766 | try { |
| 1767 | New-Item -Path "$env:TEMP\PartitionTool.done" -ItemType File -Force | Out-Null |
| 1768 | } catch {} |
| 1769 | }) |
| 1770 | |
| 1771 | $MainWindow.Title = "磁盘分区工具集 - 主界面" |
| 1772 | $MainWindow.Width = 500 |
| 1773 | $MainWindow.Height = 450 |
| 1774 | $MainWindow.WindowStartupLocation = 'CenterScreen' |
| 1775 | $MainWindow.ResizeMode = 'NoResize' |
| 1776 | |
| 1777 | # 创建主界面布局 |
| 1778 | $MainGrid = New-Object System.Windows.Controls.Grid |
| 1779 | $MainGrid.Margin = New-Object System.Windows.Thickness(20) |
| 1780 | |
| 1781 | # 添加行定义 |
| 1782 | $MainGrid.RowDefinitions.Add((New-Object System.Windows.Controls.RowDefinition -Property @{Height = 'Auto'})) |
| 1783 | $MainGrid.RowDefinitions.Add((New-Object System.Windows.Controls.RowDefinition -Property @{Height = 'Auto'})) |
| 1784 | $MainGrid.RowDefinitions.Add((New-Object System.Windows.Controls.RowDefinition -Property @{Height = '*'})) |
| 1785 | $MainGrid.RowDefinitions.Add((New-Object System.Windows.Controls.RowDefinition -Property @{Height = 'Auto'})) |
| 1786 | $MainGrid.RowDefinitions.Add((New-Object System.Windows.Controls.RowDefinition -Property @{Height = 'Auto'})) |
| 1787 | $MainGrid.RowDefinitions.Add((New-Object System.Windows.Controls.RowDefinition -Property @{Height = 'Auto'})) |
| 1788 | |
| 1789 | # 添加标题 |
| 1790 | $TitleLabel = New-Object System.Windows.Controls.Label |
| 1791 | $TitleLabel.Content = "磁盘分区工具集" |
| 1792 | $TitleLabel.FontSize = 20 |
| 1793 | $TitleLabel.FontWeight = 'Bold' |
| 1794 | $TitleLabel.HorizontalAlignment = 'Center' |
| 1795 | $TitleLabel.Margin = '0,0,0,20' |
| 1796 | $TitleLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 0) |
| 1797 | $MainGrid.Children.Add($TitleLabel) |
| 1798 | |
| 1799 | # 添加系统信息 |
| 1800 | $InfoLabel = New-Object System.Windows.Controls.Label |
| 1801 | $CVolume = Get-Volume -DriveLetter C -ErrorAction SilentlyContinue |
| 1802 | if ($CVolume) { |
| 1803 | $CurrentSizeGB = [math]::Round($CVolume.Size / 1GB, 2) |
| 1804 | |
| 1805 | # 获取磁盘信息 |
| 1806 | $CDisk = $null |
| 1807 | try { |
| 1808 | $CDisk = Get-Partition -DriveLetter C | Get-Disk -ErrorAction Stop |
| 1809 | } catch { |
| 1810 | $CDisk = $null |
| 1811 | } |
| 1812 | |
| 1813 | # 获取分区表类型 |
| 1814 | $PartitionStyle = if ($CDisk) { $CDisk.PartitionStyle } else { "未知" } |
| 1815 | |
| 1816 | # 检查BitLocker状态(简化显示) |
| 1817 | $BitLockerStatus = "关" |
| 1818 | try { |
| 1819 | $BitLockerInfo = Get-BitLockerVolume -MountPoint "C:" -ErrorAction SilentlyContinue |
| 1820 | if ($BitLockerInfo -and $BitLockerInfo.VolumeStatus -eq "FullyEncrypted") { |
| 1821 | $BitLockerStatus = "开" |
| 1822 | } |
| 1823 | } catch { |
| 1824 | $BitLockerStatus = "?" |
| 1825 | } |
| 1826 | |
| 1827 | $InfoLabel.Content = "当前 C 盘大小: $CurrentSizeGB GB | $PartitionStyle | BitLocker: $BitLockerStatus" |
| 1828 | } else { |
| 1829 | $InfoLabel.Content = "无法获取 C 盘信息" |
| 1830 | } |
| 1831 | $InfoLabel.FontSize = 12 |
| 1832 | $InfoLabel.Foreground = 'Blue' |
| 1833 | $InfoLabel.HorizontalAlignment = 'Center' |
| 1834 | $InfoLabel.Margin = '0,0,0,10' |
| 1835 | $InfoLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 1) |
| 1836 | $MainGrid.Children.Add($InfoLabel) |
| 1837 | |
| 1838 | # 添加磁盘信息 |
| 1839 | $DiskInfoLabel = New-Object System.Windows.Controls.Label |
| 1840 | try { |
| 1841 | $Disk = Get-Partition -DriveLetter C | Get-Disk -ErrorAction Stop |
| 1842 | $DiskInfoLabel.Content = "系统磁盘: $($Disk.Model) | 总大小: $([math]::Round($Disk.Size / 1GB, 2)) GB" |
| 1843 | } catch { |
| 1844 | $DiskInfoLabel.Content = "无法获取磁盘信息" |
| 1845 | } |
| 1846 | $DiskInfoLabel.FontSize = 11 |
| 1847 | $DiskInfoLabel.Foreground = 'DarkGreen' |
| 1848 | $DiskInfoLabel.HorizontalAlignment = 'Center' |
| 1849 | $DiskInfoLabel.Margin = '0,0,0,10' |
| 1850 | $DiskInfoLabel.SetValue([System.Windows.Controls.Grid]::RowProperty, 2) |
| 1851 | $MainGrid.Children.Add($DiskInfoLabel) |
| 1852 | |
| 1853 | |
| 1854 | |
| 1855 | # 创建工具选择区域 |
| 1856 | $ToolsStack = New-Object System.Windows.Controls.StackPanel |
| 1857 | $ToolsStack.Orientation = 'Vertical' |
| 1858 | $ToolsStack.HorizontalAlignment = 'Center' |
| 1859 | $ToolsStack.Margin = '0,20,0,10' |
| 1860 | $ToolsStack.SetValue([System.Windows.Controls.Grid]::RowProperty, 3) |
| 1861 | $MainGrid.Children.Add($ToolsStack) |
| 1862 | |
| 1863 | # C盘分区工具按钮 |
| 1864 | $CPartitionButton = New-Object System.Windows.Controls.Button |
| 1865 | $CPartitionButton.Name = "CPartitionButton" |
| 1866 | $CPartitionButton.Content = "系统盘分区工具" |
| 1867 | $CPartitionButton.FontSize = 14 |
| 1868 | $CPartitionButton.Width = 200 |
| 1869 | $CPartitionButton.Height = 45 |
| 1870 | $CPartitionButton.Background = '#2196F3' |
| 1871 | $CPartitionButton.Foreground = 'White' |
| 1872 | $CPartitionButton.Margin = '0,0,0,15' |
| 1873 | $CPartitionButton.ToolTip = "压缩系统盘并创建新分区" |
| 1874 | $ToolsStack.Children.Add($CPartitionButton) |
| 1875 | |
| 1876 | # 其他硬盘分区工具按钮 |
| 1877 | $OtherDiskButton = New-Object System.Windows.Controls.Button |
| 1878 | $OtherDiskButton.Name = "OtherDiskButton" |
| 1879 | $OtherDiskButton.Content = "其他硬盘分区工具" |
| 1880 | $OtherDiskButton.FontSize = 14 |
| 1881 | $OtherDiskButton.Width = 200 |
| 1882 | $OtherDiskButton.Height = 45 |
| 1883 | $OtherDiskButton.Background = '#FF9800' |
| 1884 | $OtherDiskButton.Foreground = 'White' |
| 1885 | $OtherDiskButton.Margin = '0,0,0,15' |
| 1886 | $OtherDiskButton.ToolTip = "对其他硬盘进行分区操作" |
| 1887 | $ToolsStack.Children.Add($OtherDiskButton) |
| 1888 | |
| 1889 | # 盘符理顺工具按钮 |
| 1890 | $DriveLetterButton = New-Object System.Windows.Controls.Button |
| 1891 | $DriveLetterButton.Name = "DriveLetterButton" |
| 1892 | $DriveLetterButton.Content = "盘符理顺工具" |
| 1893 | $DriveLetterButton.FontSize = 14 |
| 1894 | $DriveLetterButton.Width = 200 |
| 1895 | $DriveLetterButton.Height = 45 |
| 1896 | $DriveLetterButton.Background = '#4CAF50' |
| 1897 | $DriveLetterButton.Foreground = 'White' |
| 1898 | $DriveLetterButton.ToolTip = "重新分配和理顺所有盘符" |
| 1899 | $ToolsStack.Children.Add($DriveLetterButton) |
| 1900 | |
| 1901 | # 添加说明文本 |
| 1902 | $NoteText = New-Object System.Windows.Controls.TextBlock |
| 1903 | $NoteText.Text = "注意:分区操作有风险,请确保已备份重要数据" |
| 1904 | $NoteText.FontSize = 10 |
| 1905 | $NoteText.Foreground = 'Red' |
| 1906 | $NoteText.TextWrapping = 'Wrap' |
| 1907 | $NoteText.HorizontalAlignment = 'Center' |
| 1908 | $NoteText.Margin = '0,20,0,0' |
| 1909 | $NoteText.SetValue([System.Windows.Controls.Grid]::RowProperty, 4) |
| 1910 | $MainGrid.Children.Add($NoteText) |
| 1911 | |
| 1912 | # 版本信息 |
| 1913 | $VersionText = New-Object System.Windows.Controls.TextBlock |
| 1914 | $VersionText.Text = "版本 2.0 | 支持多磁盘分区 | 玩家国度 - 丸子装机" |
| 1915 | $VersionText.FontSize = 9 |
| 1916 | $VersionText.Foreground = 'Gray' |
| 1917 | $VersionText.HorizontalAlignment = 'Center' |
| 1918 | $VersionText.Margin = '0,5,0,0' |
| 1919 | $VersionText.SetValue([System.Windows.Controls.Grid]::RowProperty, 5) |
| 1920 | $MainGrid.Children.Add($VersionText) |
| 1921 | |
| 1922 | $MainWindow.Content = $MainGrid |
| 1923 | |
| 1924 | # C盘分区工具按钮点击事件 |
| 1925 | $CPartitionButton.Add_Click({ |
| 1926 | # 获取C盘信息 |
| 1927 | $CVolume = Get-Volume -DriveLetter C -ErrorAction SilentlyContinue |
| 1928 | if (-not $CVolume) { |
| 1929 | [System.Windows.MessageBox]::Show("无法找到 C 盘,请检查系统配置。", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) |
| 1930 | return |
| 1931 | } |
| 1932 | |
| 1933 | $CurrentSizeGB = [math]::Round($CVolume.Size / 1GB, 2) |
| 1934 | Write-Host "-- 当前 C: 卷的总大小是 $CurrentSizeGB GB。" -ForegroundColor Green |
| 1935 | |
| 1936 | # 获取硬盘信息 |
| 1937 | try { |
| 1938 | $Disk = Get-Partition -DriveLetter C | Get-Disk |
| 1939 | $DiskNumber = $Disk.Number |
| 1940 | } catch { |
| 1941 | [System.Windows.MessageBox]::Show("无法获取磁盘信息。", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) |
| 1942 | return |
| 1943 | } |
| 1944 | |
| 1945 | # 检查是否已有分区 |
| 1946 | $Partitions = Get-Partition -DiskNumber $DiskNumber | Where-Object { $_.Type -eq 'Basic' } |
| 1947 | if ($Partitions.Count -ge 2) { |
| 1948 | Write-Host "-- 磁盘上已经存在分区,跳过分区创建。" -ForegroundColor Yellow |
| 1949 | [System.Windows.MessageBox]::Show("检测到已有分区,操作终止。", "分区检测", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) |
| 1950 | return |
| 1951 | } |
| 1952 | |
| 1953 | # 创建分区工具窗口 |
| 1954 | CreateCPartitionWindow |
| 1955 | }) |
| 1956 | |
| 1957 | # 其他硬盘分区工具按钮点击事件 |
| 1958 | $OtherDiskButton.Add_Click({ |
| 1959 | CreateOtherDiskPartitionWindow |
| 1960 | }) |
| 1961 | |
| 1962 | # 盘符理顺工具按钮点击事件 |
| 1963 | $DriveLetterButton.Add_Click({ |
| 1964 | ReassignDriveLettersWithUI |
| 1965 | }) |
| 1966 | |
| 1967 | # 显示主窗口 |
| 1968 | try { |
| 1969 | $null = $MainWindow.ShowDialog() |
| 1970 | } catch { |
| 1971 | Write-Host "启动错误: $($_.Exception.Message)" -ForegroundColor Red |
| 1972 | [System.Windows.MessageBox]::Show("程序启动失败: $($_.Exception.Message)", "错误", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error) |
| 1973 | } |