背景
Creo 在構(gòu)建模型時,如果發(fā)生修改并完成保存時會創(chuàng)建新的 .prt 或者 .asm 文件,命名會以數(shù)字結(jié)尾;隨著時間的推移,這類文件會越來越多,如果模型已經(jīng)定性定型,那么這些舊版本文件就可以刪除了
實(shí)現(xiàn)
已在 Window11 x64 完成測試
- 實(shí)現(xiàn)了對舊版本文件的刪除
- 實(shí)現(xiàn)了對刪除的文件使用 zip 備份
- 完善的 log 輸出,方便確認(rèn)執(zhí)行結(jié)果
- 支持僅作 log 輸出,只需要刪除下面快捷方式中出現(xiàn)的
-Delete字樣即可 - 支持將刪除文件的詳細(xì)信息整合到 zip 備份,方便對照查閱和審計
- 支持通過構(gòu)建多個快捷方式處理更多的 Creo 工作目錄
<#
CreoOldVersionsHandler.ps1 (終極排序修復(fù)版)
- 核心修復(fù):
1. 強(qiáng)制按整數(shù)降序排序版本號,避免排序失效
2. 顯式輸出每組所有版本號,便于排查排序問題
3. 增加待刪除數(shù)校驗,確保舊版本被識別
#>
param(
[Parameter(Mandatory = $true)]
[string]$WorkDir,
[switch]$Delete
)
# 1. 標(biāo)準(zhǔn)化工作目錄
Try {
$fullWorkDir = [System.IO.Path]::GetFullPath($WorkDir).TrimEnd(' ', '\', '/')
Set-Location -Path "$fullWorkDir" -ErrorAction Stop
} Catch {
Write-Error "路徑不存在或無法訪問: $WorkDir"
exit 1
}
# 2. 初始化日志(UTF-8)
$LogFile = Join-Path "$fullWorkDir" "cleanup_log.txt"
"" | Out-File -FilePath "$LogFile" -Encoding UTF8 -Force
# 3. 控制臺基礎(chǔ)信息
Write-Host "====================================="
Write-Host "Creo 舊版本文件處理工具 (終極排序修復(fù)版)"
Write-Host "====================================="
Write-Host "掃描路徑: $fullWorkDir"
Write-Host "模式: 遞歸掃描所有子目錄"
Write-Host "日志路徑: $LogFile"
Write-Host "刪除模式: $(if ($Delete) { '啟用(先備份)' } else { '禁用(僅掃描)' })"
Write-Host "====================================="
Write-Host ""
# 4. 解析.prt.N/.asm.N文件(標(biāo)準(zhǔn)化分組鍵)
$allFiles = Get-ChildItem -Path "$fullWorkDir" -File -Recurse -ErrorAction SilentlyContinue
$parsedItems = @()
foreach ($file in $allFiles) {
$fileName = $file.Name.Trim()
$fileFullPath = $file.FullName
$fileDirectory = [System.IO.Path]::GetFullPath($file.DirectoryName).TrimEnd(' ', '\', '/')
# 步驟1:找最后一個“.”(版本號分隔符)
$lastDotPos = $fileName.LastIndexOf('.')
if ($lastDotPos -le 0) { continue }
# 步驟2:強(qiáng)制校驗版本號為整數(shù)(顯式轉(zhuǎn)換,避免類型問題)
$versionStr = $fileName.Substring($lastDotPos + 1)
if (-not [int]::TryParse($versionStr, [ref]$null)) {
Add-Content -Path "$LogFile" -Value "[跳過] 非數(shù)字版本號:$fileName(版本號:$versionStr)"
continue
}
$version = [int]$versionStr # 強(qiáng)制轉(zhuǎn)為int類型,確保排序生效
# 步驟3:截取“基名+后綴”
$baseWithExt = $fileName.Substring(0, $lastDotPos).Trim()
# 步驟4:匹配.prt/.asm后綴(忽略大小寫)
$typeRegex = [regex]::new('\.(prt|asm)$', [System.Text.RegularExpressions.RegexOptions]::IgnoreCase)
$typeMatch = $typeRegex.Match($baseWithExt)
if (-not $typeMatch.Success) {
Add-Content -Path "$LogFile" -Value "[跳過] 非目標(biāo)類型:$fileName(后綴:$baseWithExt 的最后部分)"
continue
}
$fileType = $typeMatch.Groups[1].Value.ToLower()
# 步驟5:截取基名
$baseDotPos = $baseWithExt.LastIndexOf('.')
$baseName = if ($baseDotPos -gt 0) {
$baseWithExt.Substring(0, $baseDotPos).Trim()
} else {
$baseWithExt.Trim()
}
# 步驟6:標(biāo)準(zhǔn)化分組鍵
$standardizedGroupKey = "$fileDirectory\$baseName.$fileType".ToLower()
# 添加到解析結(jié)果(顯式指定Version類型為int)
$parsedItems += [PSCustomObject]@{
FullName = $fileName
FullPath = $fileFullPath
Directory = $fileDirectory
BaseName = $baseName
Type = $fileType
Version = [int]$version # 強(qiáng)制int類型
StandardGroupKey = $standardizedGroupKey
}
}
# 5. 檢查匹配結(jié)果
$totalMatched = $parsedItems.Count
Write-Host "已匹配的.prt/.asm版本文件數(shù): $totalMatched"
if ($totalMatched -eq 0) {
Add-Content -Path "$LogFile" -Value "【掃描結(jié)果】未找到*.prt.<數(shù)字>或*.asm.<數(shù)字>文件。"
Add-Content -Path "$LogFile" -Value "【掃描時間】$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
Write-Host "`n未找到匹配文件,日志已生成。"
Invoke-Item "$LogFile"
exit 0
}
# 6. 按標(biāo)準(zhǔn)化分組鍵分組
$fileGroups = $parsedItems | Group-Object -Property StandardGroupKey
$totalGroups = $fileGroups.Count
$expectedToRemove = $totalMatched - $totalGroups # 理論待刪除數(shù)
Write-Host "文件分組數(shù): $totalGroups 組"
Write-Host "理論待刪除文件數(shù): $expectedToRemove 個(匹配數(shù)-分組數(shù))"
# 7. 識別待刪除文件(強(qiáng)制排序+顯性日志)
$allToRemove = @()
Add-Content -Path "$LogFile" -Value "【掃描匯總】"
Add-Content -Path "$LogFile" -Value " 匹配文件總數(shù):$totalMatched 個"
Add-Content -Path "$LogFile" -Value " 文件分組總數(shù):$totalGroups 組"
Add-Content -Path "$LogFile" -Value " 理論待刪除數(shù):$expectedToRemove 個"
Add-Content -Path "$LogFile" -Value " 排序規(guī)則:強(qiáng)制按版本號(整數(shù))降序"
Add-Content -Path "$LogFile" -Value "====================================="
foreach ($group in $fileGroups) {
$groupFiles = $group.Group
$groupFileCount = $groupFiles.Count
Add-Content -Path "$LogFile" -Value "`n【文件組】$($group.Name)"
Add-Content -Path "$LogFile" -Value " 組內(nèi)文件總數(shù):$groupFileCount 個"
# 核心修復(fù):強(qiáng)制按Version(int)降序排序,指定排序類型
$sortedFiles = $groupFiles | Sort-Object -Property @{Expression = { $_.Version }; Ascending = $false }
# 顯式輸出組內(nèi)所有文件的版本號(便于驗證排序結(jié)果)
$versionList = $sortedFiles | ForEach-Object { "v$($_.Version)($($_.FullName))" }
Add-Content -Path "$LogFile" -Value " 組內(nèi)版本排序(降序):"
foreach ($ver in $versionList) {
Add-Content -Path "$LogFile" -Value " - $ver"
}
# 確定保留文件(第一個,最大版本)和待刪除文件(剩余)
if ($groupFileCount -eq 1) {
$keepFile = $sortedFiles[0]
Add-Content -Path "$LogFile" -Value " 保留文件:v$($keepFile.Version)($($keepFile.FullName))"
Add-Content -Path "$LogFile" -Value " 待刪除:無(僅1個版本)"
} else {
$keepFile = $sortedFiles[0]
$removeFiles = $sortedFiles | Select-Object -Skip 1 # 跳過最大版本
$removeCount = $removeFiles.Count
# 記錄保留文件
Add-Content -Path "$LogFile" -Value " 保留文件(最大版本):v$($keepFile.Version)($($keepFile.FullName))"
Add-Content -Path "$LogFile" -Value " 待刪除文件(共 $removeCount 個):"
foreach ($delFile in $removeFiles) {
Add-Content -Path "$LogFile" -Value " - v$($delFile.Version):$($delFile.FullName)"
$allToRemove += $delFile.FullPath
}
}
}
# 8. 待刪除列表去重+校驗
$uniqueToRemove = $allToRemove | Sort-Object -Unique
$actualToRemove = $uniqueToRemove.Count
Add-Content -Path "$LogFile" -Value "`n====================================="
Add-Content -Path "$LogFile" -Value "【待刪除校驗】"
Add-Content -Path "$LogFile" -Value " 理論待刪除數(shù):$expectedToRemove 個"
Add-Content -Path "$LogFile" -Value " 實(shí)際待刪除數(shù)(去重后):$actualToRemove 個"
# 校驗理論值與實(shí)際值是否一致,不一致則日志警告
if ($actualToRemove -ne $expectedToRemove) {
Add-Content -Path "$LogFile" -Value " [警告] 待刪除數(shù)不匹配!可能存在分組錯誤或排序失效。"
Write-Host "`n[警告] 待刪除數(shù)不匹配(理論:$expectedToRemove,實(shí)際:$actualToRemove),請查看日志排查。"
} else {
Add-Content -Path "$LogFile" -Value " 待刪除數(shù)校驗通過,無遺漏。"
}
# 9. 執(zhí)行刪除(如需)
$backupPath = $null
if ($Delete -and $actualToRemove -gt 0) {
Add-Content -Path "$LogFile" -Value "`n【刪除流程】開始備份+刪除"
$timestamp = Get-Date -Format 'yyyyMMdd_HHmmss'
$backupPath = Join-Path "$fullWorkDir" "Creo_Backup_$timestamp.zip"
$snapshotLog = Join-Path "$fullWorkDir" "Snapshot_$timestamp.txt"
# 復(fù)制日志快照
Try {
Copy-Item -LiteralPath "$LogFile" -Destination "$snapshotLog" -Force -ErrorAction Stop
Add-Content -Path "$LogFile" -Value " 1. 快照日志生成成功:$snapshotLog"
} Catch {
Add-Content -Path "$LogFile" -Value " 1. [警告] 快照日志失?。?($_.Exception.Message)"
$snapshotLog = $null
}
# 打包備份
$itemsToZip = $uniqueToRemove
if ($snapshotLog) { $itemsToZip += "$snapshotLog" }
Try {
Compress-Archive -LiteralPath $itemsToZip -DestinationPath "$backupPath" -Force -ErrorAction Stop
Add-Content -Path "$LogFile" -Value " 2. 備份包生成成功:$backupPath"
} Catch {
Add-Content -Path "$LogFile" -Value " 2. [錯誤] 備份失敗:$($_.Exception.Message)"
Add-Content -Path "$LogFile" -Value " 3. [安全] 取消刪除(防止數(shù)據(jù)丟失)"
Write-Host "`n備份錯誤,刪除已取消!詳見日志。"
Invoke-Item "$LogFile"
exit 1
}
# 刪除舊文件
$successCount = 0
$failCount = 0
Add-Content -Path "$LogFile" -Value " 3. 開始刪除(共 $actualToRemove 個文件)"
foreach ($filePath in $uniqueToRemove) {
Try {
Remove-Item -LiteralPath "$filePath" -Force -ErrorAction Stop
Add-Content -Path "$LogFile" -Value " - 成功:$filePath"
$successCount++
} Catch {
Add-Content -Path "$LogFile" -Value " - 失敗:$filePath | 錯誤:$($_.Exception.Message)"
$failCount++
}
}
# 清理快照
if ($snapshotLog -and (Test-Path "$snapshotLog")) {
Try {
Remove-Item -LiteralPath "$snapshotLog" -Force -ErrorAction Stop
Add-Content -Path "$LogFile" -Value " 4. 快照日志已清理:$snapshotLog"
} Catch {
Add-Content -Path "$LogFile" -Value " 4. [警告] 快照清理失?。?($_.Exception.Message)"
}
}
Add-Content -Path "$LogFile" -Value " 5. 刪除統(tǒng)計:成功 $successCount 個 | 失敗 $failCount 個"
}
# 10. 最終報告
Add-Content -Path "$LogFile" -Value "`n====================================="
Add-Content -Path "$LogFile" -Value "【最終報告】"
Add-Content -Path "$LogFile" -Value " 掃描時間:$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
Add-Content -Path "$LogFile" -Value " 掃描路徑:$fullWorkDir"
Add-Content -Path "$LogFile" -Value " 匹配文件:$totalMatched 個"
Add-Content -Path "$LogFile" -Value " 文件分組:$totalGroups 組"
Add-Content -Path "$LogFile" -Value " 待刪除文件:$actualToRemove 個"
Add-Content -Path "$LogFile" -Value " 刪除操作:$(if ($Delete) { '已執(zhí)行(備份:' + $backupPath + ')' } else { '未啟用' })"
Add-Content -Path "$LogFile" -Value "====================================="
# 11. 輸出結(jié)果并打開日志
Write-Host "`n====================================="
Write-Host "處理完成!"
Write-Host "====================================="
Write-Host "匹配文件總數(shù): $totalMatched 個"
Write-Host "文件分組數(shù): $totalGroups 組"
Write-Host "理論待刪除數(shù): $expectedToRemove 個"
Write-Host "實(shí)際待刪除數(shù): $actualToRemove 個"
Write-Host "刪除操作: $(if ($Delete) { '已執(zhí)行(備份已生成)' } else { '未啟用(僅掃描)' })"
Write-Host "日志已保存至: $LogFile"
Write-Host "====================================="
Invoke-Item "$LogFile"
exit 0
快速開始:
- 將代碼保存為 CreoOldVersionsHandler.ps1
- 在桌面右鍵生成快捷方式,填入如下代碼(僅供參考):
powershell.exe -ExecutionPolicy Bypass -File "D:\AppData\CreoOldVersionsHandler.ps1" -WorkDir "D:\AppData\Solid ElecValue" -Delete
- 執(zhí)行此快捷方式(如果被攔截請放行)
請注意上面快捷方式內(nèi)容僅供參考,在你的電腦上使用時,請做如下修正:
-
D:\AppData\CreoOldVersionsHandler.ps1請改為你的 CreoOldVersionsHandler.ps1 存儲的位置。 -
D:\AppData\Solid ElecValue請改為你的 Creo 工作目錄 - 你可以通過構(gòu)建多個快捷方式來處理多個 Creo 工作目錄
執(zhí)行結(jié)果
代碼會將需要保留的文件,刪除的文件以及備份進(jìn)行羅列,如圖所示(僅供參考)

更新日志
2025年11月7日:修復(fù)會遺漏、跳過本該被刪除的文件的問題
友情提示:數(shù)據(jù)寶貴,請務(wù)必再確認(rèn)腳本能夠正常使用前做好備份。
版權(quán)所有,轉(zhuǎn)載請注明出處