-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcompression_module.ps1
More file actions
320 lines (265 loc) · 11.6 KB
/
compression_module.ps1
File metadata and controls
320 lines (265 loc) · 11.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
<#
CompressionModule.ps1 - 7zip 壓縮與加密模組
Version: v0.2
功能說明: 提供系統備份檔案的壓縮、解壓縮、完整性檢查及壓縮檔資訊查詢功能,
支援密碼加密保護,並集成統一日誌記錄機制。
版本歷史:
v0.1 - 初始版本,實現基本壓縮、解壓縮、測試及資訊查詢功能
v0.2 - 修復日誌呼叫機制,統一使用logging_module中的Add-LogEntry進行日誌記錄,
移除直接Write-Host調用,增強日誌可跟蹤性與輸出靈活性
#>
function Compress-BackupFile {
param(
[string]$SourceFile,
[string]$Password = $null,
[string]$CompressionLevel = "9",
[string]$OutputPath = $null
)
$result = @{
Success = $false
CompressedFile = $null
Error = $null
OriginalSize = 0
CompressedSize = 0
CompressionRatio = 0
}
try {
# 檢查來源檔案是否存在
if (-not (Test-Path $SourceFile)) {
throw "來源檔案不存在: $SourceFile"
}
# 獲取 7zip 路徑
$config = Get-AppConfig
$sevenZipPath = $config.SevenZipPath
if (-not (Test-Path $sevenZipPath)) {
throw "找不到 7zip 執行檔: $sevenZipPath"
}
# 建立輸出檔案路徑
if (-not $OutputPath) {
$sourceDir = [System.IO.Path]::GetDirectoryName($SourceFile)
$sourceBaseName = [System.IO.Path]::GetFileNameWithoutExtension($SourceFile)
$OutputPath = Join-Path $sourceDir "$sourceBaseName.7z"
}
# 獲取原始檔案大小
$originalFileInfo = Get-Item $SourceFile
$result.OriginalSize = $originalFileInfo.Length
Add-LogEntry -Message "開始壓縮檔案: $SourceFile" -Level INFO -ConsoleOutput -GUIOutput
Add-LogEntry -Message "輸出檔案: $OutputPath" -Level INFO -ConsoleOutput -GUIOutput
Add-LogEntry -Message "原始大小: $([math]::Round($result.OriginalSize / 1MB, 2)) MB" -Level INFO -ConsoleOutput -GUIOutput
# 建立 7zip 參數
$sevenZipArgs = @(
"a" # 添加到壓縮檔
"-t7z" # 7z 格式
"-mx=$CompressionLevel" # 壓縮等級 (0-9)
"-mmt=on" # 多執行緒
"-ms=on" # 固態壓縮
"-md=64m" # 字典大小
"-mfb=64" # 快速位元組數
"-y" # 全部回答 Yes
)
# 如果有密碼,加入加密選項
if ($Password) {
$sevenZipArgs += "-p$Password" # 設定密碼
$sevenZipArgs += "-mhe=on" # 加密檔案標頭
$sevenZipArgs += "-mx0" # 對於加密檔案,先用較低壓縮等級測試
Add-LogEntry -Message "已啟用密碼保護" -Level INFO -ConsoleOutput -GUIOutput
}
# 加入輸出檔案和來源檔案
$sevenZipArgs += "`"$OutputPath`""
$sevenZipArgs += "`"$SourceFile`""
# 執行 7zip 壓縮
Add-LogEntry -Message "執行壓縮指令..." -Level INFO -ConsoleOutput -GUIOutput
$process = Start-Process -FilePath $sevenZipPath -ArgumentList $sevenZipArgs -Wait -PassThru -NoNewWindow -RedirectStandardOutput "$env:TEMP\7zip_output.log" -RedirectStandardError "$env:TEMP\7zip_error.log"
# 檢查執行結果
if ($process.ExitCode -eq 0) {
# 驗證輸出檔案是否存在
if (Test-Path $OutputPath) {
$compressedFileInfo = Get-Item $OutputPath
$result.CompressedSize = $compressedFileInfo.Length
$result.CompressionRatio = [math]::Round((1 - ($result.CompressedSize / $result.OriginalSize)) * 100, 2)
Add-LogEntry -Message "壓縮完成!" -Level INFO -ConsoleOutput -GUIOutput
Add-LogEntry -Message "壓縮後大小: $([math]::Round($result.CompressedSize / 1MB, 2)) MB" -Level INFO -ConsoleOutput -GUIOutput
Add-LogEntry -Message "壓縮率: $($result.CompressionRatio)%" -Level INFO -ConsoleOutput -GUIOutput
$result.Success = $true
$result.CompressedFile = $OutputPath
# 驗證壓縮檔完整性
$testResult = Test-CompressedFile -FilePath $OutputPath -Password $Password
if (-not $testResult.Success) {
throw "壓縮檔完整性驗證失敗: $($testResult.Error)"
}
Add-LogEntry -Message "壓縮檔完整性驗證通過" -Level INFO -ConsoleOutput -GUIOutput
} else {
throw "壓縮檔案建立失敗,找不到輸出檔案"
}
} else {
$errorOutput = Get-Content "$env:TEMP\7zip_error.log" -Raw -ErrorAction SilentlyContinue
throw "7zip 壓縮失敗 (錯誤碼: $($process.ExitCode)): $errorOutput"
}
}
catch {
$result.Error = $_.Exception.Message
Add-LogEntry -Message "壓縮失敗: $($_.Exception.Message)" -Level ERROR -ConsoleOutput -GUIOutput
}
finally {
# 清理暫存檔案
Remove-Item "$env:TEMP\7zip_output.log" -ErrorAction SilentlyContinue
Remove-Item "$env:TEMP\7zip_error.log" -ErrorAction SilentlyContinue
}
return $result
}
function Decompress-BackupFile {
param(
[string]$CompressedFile,
[string]$OutputPath,
[string]$Password = $null
)
$result = @{
Success = $false
ExtractedFiles = @()
Error = $null
}
try {
# 檢查壓縮檔是否存在
if (-not (Test-Path $CompressedFile)) {
throw "壓縮檔不存在: $CompressedFile"
}
# 獲取 7zip 路徑
$config = Get-AppConfig
$sevenZipPath = $config.SevenZipPath
if (-not (Test-Path $sevenZipPath)) {
throw "找不到 7zip 執行檔: $sevenZipPath"
}
# 建立輸出目錄
if (-not (Test-Path $OutputPath)) {
New-Item -Path $OutputPath -ItemType Directory -Force | Out-Null
}
Add-LogEntry -Message "開始解壓縮檔案: $CompressedFile" -Level INFO -ConsoleOutput -GUIOutput
Add-LogEntry -Message "輸出目錄: $OutputPath" -Level INFO -ConsoleOutput -GUIOutput
# 建立 7zip 解壓縮參數
$sevenZipArgs = @(
"x" # 解壓縮保持目錄結構
"`"$CompressedFile`"" # 來源壓縮檔
"-o`"$OutputPath`"" # 輸出目錄
"-y" # 全部回答 Yes
)
# 如果有密碼,加入密碼選項
if ($Password) {
$sevenZipArgs += "-p$Password"
Add-LogEntry -Message "使用密碼解壓縮" -Level INFO -ConsoleOutput -GUIOutput
}
# 執行 7zip 解壓縮
Add-LogEntry -Message "執行解壓縮指令..." -Level INFO -ConsoleOutput -GUIOutput
$process = Start-Process -FilePath $sevenZipPath -ArgumentList $sevenZipArgs -Wait -PassThru -NoNewWindow -RedirectStandardOutput "$env:TEMP\7zip_extract_output.log" -RedirectStandardError "$env:TEMP\7zip_extract_error.log"
# 檢查執行結果
if ($process.ExitCode -eq 0) {
# 列出解壓縮的檔案
$extractedFiles = Get-ChildItem -Path $OutputPath -Recurse -File
$result.ExtractedFiles = $extractedFiles.FullName
Add-LogEntry -Message "解壓縮完成!" -Level INFO -ConsoleOutput -GUIOutput
Add-LogEntry -Message "解壓縮了 $($extractedFiles.Count) 個檔案" -Level INFO -ConsoleOutput -GUIOutput
$result.Success = $true
} else {
$errorOutput = Get-Content "$env:TEMP\7zip_extract_error.log" -Raw -ErrorAction SilentlyContinue
throw "7zip 解壓縮失敗 (錯誤碼: $($process.ExitCode)): $errorOutput"
}
}
catch {
$result.Error = $_.Exception.Message
Add-LogEntry -Message "解壓縮失敗: $($_.Exception.Message)" -Level ERROR -ConsoleOutput -GUIOutput
}
finally {
# 清理暫存檔案
Remove-Item "$env:TEMP\7zip_extract_output.log" -ErrorAction SilentlyContinue
Remove-Item "$env:TEMP\7zip_extract_error.log" -ErrorAction SilentlyContinue
}
return $result
}
function Test-CompressedFile {
param(
[string]$FilePath,
[string]$Password = $null
)
$result = @{
Success = $false
Error = $null
}
try {
# 獲取 7zip 路徑
$config = Get-AppConfig
$sevenZipPath = $config.SevenZipPath
if (-not (Test-Path $sevenZipPath)) {
throw "找不到 7zip 執行檔: $sevenZipPath"
}
# 建立測試參數
$sevenZipArgs = @(
"t" # 測試壓縮檔
"`"$FilePath`"" # 壓縮檔路徑
)
# 如果有密碼,加入密碼選項
if ($Password) {
$sevenZipArgs += "-p$Password"
}
# 執行測試
$process = Start-Process -FilePath $sevenZipPath -ArgumentList $sevenZipArgs -Wait -PassThru -NoNewWindow -RedirectStandardOutput "$env:TEMP\7zip_test_output.log" -RedirectStandardError "$env:TEMP\7zip_test_error.log"
if ($process.ExitCode -eq 0) {
$result.Success = $true
} else {
$errorOutput = Get-Content "$env:TEMP\7zip_test_error.log" -Raw -ErrorAction SilentlyContinue
$result.Error = "壓縮檔測試失敗 (錯誤碼: $($process.ExitCode)): $errorOutput"
}
}
catch {
$result.Error = $_.Exception.Message
}
finally {
# 清理暫存檔案
Remove-Item "$env:TEMP\7zip_test_output.log" -ErrorAction SilentlyContinue
Remove-Item "$env:TEMP\7zip_test_error.log" -ErrorAction SilentlyContinue
}
return $result
}
function Get-CompressedFileInfo {
param([string]$FilePath)
$result = @{
Success = $false
Files = @()
TotalSize = 0
CompressedSize = 0
Error = $null
}
try {
# 獲取 7zip 路徑
$config = Get-AppConfig
$sevenZipPath = $config.SevenZipPath
if (-not (Test-Path $sevenZipPath)) {
throw "找不到 7zip 執行檔: $sevenZipPath"
}
# 列出壓縮檔內容
$sevenZipArgs = @(
"l" # 列出內容
"`"$FilePath`"" # 壓縮檔路徑
)
$process = Start-Process -FilePath $sevenZipPath -ArgumentList $sevenZipArgs -Wait -PassThru -NoNewWindow -RedirectStandardOutput "$env:TEMP\7zip_list_output.log" -RedirectStandardError "$env:TEMP\7zip_list_error.log"
if ($process.ExitCode -eq 0) {
$output = Get-Content "$env:TEMP\7zip_list_output.log"
# 解析輸出以提取檔案資訊
# 這裡簡化處理,實際可能需要更複雜的解析
$result.Success = $true
$result.CompressedSize = (Get-Item $FilePath).Length
} else {
$errorOutput = Get-Content "$env:TEMP\7zip_list_error.log" -Raw -ErrorAction SilentlyContinue
$result.Error = "無法取得壓縮檔資訊 (錯誤碼: $($process.ExitCode)): $errorOutput"
}
}
catch {
$result.Error = $_.Exception.Message
}
finally {
# 清理暫存檔案
Remove-Item "$env:TEMP\7zip_list_output.log" -ErrorAction SilentlyContinue
Remove-Item "$env:TEMP\7zip_list_error.log" -ErrorAction SilentlyContinue
}
return $result
}
# 匯出函數
Export-ModuleMember -Function Compress-BackupFile, Decompress-BackupFile, Test-CompressedFile, Get-CompressedFileInfo