@@ -38,6 +38,10 @@ if ($outputFilePath.EndsWith(".xlsb")) {
38
38
$outputFilePath = $outputFilePath -replace " \.xlsb$" , " .xlsb.xlsm"
39
39
}
40
40
41
+ if ($outputFilePath.EndsWith (" .ppam" )) {
42
+ $outputFilePath = $outputFilePath -replace " \.ppam$" , " .ppam.pptm"
43
+ }
44
+
41
45
# Make sure the output file already exists
42
46
if (-not (Test-Path $outputFilePath )) {
43
47
Write-Host " 🔴 Error: Output file not found: $outputFilePath "
@@ -284,22 +288,41 @@ $basFiles | ForEach-Object {
284
288
285
289
# Save the document
286
290
Write-Host " Saving document..."
291
+ $oldFilePath = " "
287
292
try {
288
- if ($officeAppName -eq " PowerPoint " -or $officeAppName -eq " Word" ) {
293
+ if ($officeAppName -eq " Word" ) {
289
294
# For PowerPoint, use SaveAs with the same file name to force save
290
295
$doc.SaveAs ($outputFilePath )
291
296
Write-Host " Document saved using SaveAs method"
297
+ } elseif ($officeAppName -eq " PowerPoint" ) {
298
+ # For PowerPoint, we need to check if the file name ends with .ppam.pptm
299
+ # If so, we need to save as .ppam
300
+ if ($outputFilePath.EndsWith (" .ppam.pptm" )) {
301
+ $oldFilePath = $outputFilePath
302
+ $outputFilePath = $outputFilePath -replace " \.ppam\.pptm$" , " .ppam"
303
+ # Replace forward slashes with backslashes
304
+ $outputFilePath = $outputFilePath -replace " /" , " \"
305
+ Write-Host " Saving document as .ppam: $outputFilePath "
306
+ $doc.SaveAs ($outputFilePath , 18 ) # 18 is the ppSaveAsOpenXMLAddIn file format for .ppam
307
+ # Delete the .ppam.pptm file
308
+ Remove-Item - Path $oldFilePath - Force
309
+ Write-Host " Document saved as .ppam"
310
+ } else {
311
+ $doc.Save ()
312
+ Write-Host " Document saved successfully"
313
+ }
292
314
} elseif ($officeAppName -eq " Excel" ) {
293
315
# For Excel, we need to check if the file name ends with .xlsb.xlsm
294
316
# If so, we need to save as .xlsb
295
317
if ($outputFilePath.EndsWith (" .xlsb.xlsm" )) {
296
- $newFilePath = $outputFilePath -replace " \.xlsb\.xlsm$" , " .xlsb"
318
+ $oldFilePath = $outputFilePath
319
+ $outputFilePath = $outputFilePath -replace " \.xlsb\.xlsm$" , " .xlsb"
297
320
# Replace forward slashes with backslashes
298
- $newFilePath = $newFilePath -replace " /" , " \"
299
- Write-Host " Saving document as .xlsb: $newFilePath "
300
- $doc.SaveAs ($newFilePath , 50 ) # 50 is the xlExcel12 file format for .xlsb
321
+ $outputFilePath = $outputFilePath -replace " /" , " \"
322
+ Write-Host " Saving document as .xlsb: $outputFilePath "
323
+ $doc.SaveAs ($outputFilePath , 50 ) # 50 is the xlExcel12 file format for .xlsb
301
324
# Delete the .xlsb.xlsm file
302
- Remove-Item - Path $outputFilePath - Force
325
+ Remove-Item - Path $oldFilePath - Force
303
326
Write-Host " Document saved as .xlsb"
304
327
} else {
305
328
$doc.Save ()
@@ -316,8 +339,11 @@ try {
316
339
# Alternative approach for PowerPoint if SaveAs fails
317
340
if ($officeAppName -eq " PowerPoint" ) {
318
341
try {
342
+
343
+ $ppFileExtension = $outputFilePath.Substring ($outputFilePath.LastIndexOf (' .' ) + 1 )
344
+
319
345
# Try saving with a temporary file name and then renaming
320
- $tempPath = [System.IO.Path ]::GetTempFileName() -replace ' \.tmp$' , ' .pptm '
346
+ $tempPath = [System.IO.Path ]::GetTempFileName() -replace ' \.tmp$' , " . $ppFileExtension "
321
347
Write-Host " Attempting to save to temporary location: $tempPath "
322
348
$doc.SaveAs ($tempPath )
323
349
@@ -326,40 +352,71 @@ try {
326
352
$officeApp.Quit ()
327
353
328
354
# Release COM objects
329
- [System.Runtime.Interopservices.Marshal ]::ReleaseComObject($doc ) | Out-Null
330
- [System.Runtime.Interopservices.Marshal ]::ReleaseComObject($officeApp ) | Out-Null
355
+ # Note: Initially, we were releasing the COM objects here, but since we want to use $doc later in the script to call the WriteToFile macro,
356
+ # we will not release them here. Instead, we will release them at the end of the script. Hopefully, this will still allow the SaveAs issue to be resolved.
357
+ # [System.Runtime.Interopservices.Marshal]::ReleaseComObject($doc) | Out-Null
358
+ # [System.Runtime.Interopservices.Marshal]::ReleaseComObject($officeApp) | Out-Null
331
359
332
360
# Wait a moment for resources to be released
333
- Start-Sleep - Seconds 2
361
+ Start-Sleep - Seconds 5
334
362
335
363
# Copy the temp file to the intended destination
336
364
Copy-Item - Path $tempPath - Destination $outputFilePath - Force
337
365
Remove-Item - Path $tempPath - Force
338
-
366
+
339
367
Write-Host " Document saved using alternative method"
340
-
341
- # Skip the rest of the cleanup as we've already done it
342
- Write-Host " VBA import completed successfully."
343
- exit 0
368
+
369
+ if ($oldFilePath ) {
370
+ # If we had an old file path, delete it
371
+ Remove-Item - Path $oldFilePath - Force
372
+ Write-Host " Old file deleted: $oldFilePath "
373
+ }
374
+
375
+ # Reopen the office application
376
+ $officeApp = New-Object - ComObject " $officeAppName .Application"
377
+ $officeApp.Visible = $true
378
+ Write-Host " Reopened $officeAppName application"
379
+
380
+ # Reopen the document, but if it's an Addin, we use Addins.Add then we load it
381
+ if ($outputFilePath.EndsWith (" .ppam" )) {
382
+ $doc = $officeApp.AddIns.Add ($outputFilePath )
383
+ } else {
384
+ $doc = $officeApp.Presentations.Open ($outputFilePath , $false , $false , $true ) # ReadOnly, Untitled, WithWindow
385
+ }
386
+
387
+ Write-Host " Document reopened successfully after alternative save method"
388
+
344
389
} catch {
345
390
Write-Host " Error: Alternative save method also failed: $ ( $_.Exception.Message ) "
346
391
Take- Screenshot - OutputPath " ${screenshotDir} Screenshot_${fileNameNoExt} _{{timestamp}}.png"
347
392
}
348
393
}
349
394
}
350
395
351
- # Generic test
396
+ if ($officeAppName -eq " PowerPoint" -and $outputFilePath.EndsWith (" .ppam" )) {
397
+ # Check for and remove any PowerPoint Addin folder that might have been created
398
+ $presentationName = [System.IO.Path ]::GetFileNameWithoutExtension($outputFilePath )
399
+ $presentationDir = [System.IO.Path ]::GetDirectoryName($outputFilePath )
400
+ $possibleAddinFolder = Join-Path - Path $presentationDir - ChildPath $presentationName
401
+
402
+ if (Test-Path - Path $possibleAddinFolder - PathType Container) {
403
+ Write-Host " Removing auto-generated folder: $possibleAddinFolder "
404
+ Remove-Item - Path $possibleAddinFolder - Recurse - Force
405
+ }
406
+ }
407
+
352
408
# Call the WriteToFile macro to check if the module was imported correctly
353
409
try {
354
410
355
- $vbaModule = $doc.VBProject.VBComponents.Item (1 )
356
- if ($null -eq $vbaModule ) {
357
- Write-Host " Error: No VBA module found in the document."
358
- Take- Screenshot - OutputPath " ${screenshotDir} Screenshot_${fileNameNoExt} _{{timestamp}}.png"
359
- exit 1
411
+ # Adding a slide duplication step similar to the working VBScript example from https://www.msofficeforums.com/powerpoint/23672-calling-macro-powerpoint-command-line.html#post74116
412
+ # This seems to be required for the macro to execute properly in PowerPoint
413
+ if ($fileExtension -eq " pptm" ) {
414
+ $Slide = $doc.Slides (1 ).Duplicate()
415
+ } elseif ($fileExtension -eq " ppam" ) {
416
+ # Ensure the Addin is loaded
417
+ $doc.Loaded = $true
360
418
}
361
- Write-Host " VBA module found: $ ( $vbaModule.Name ) "
362
-
419
+
363
420
$macroName = " WriteToFile"
364
421
Write-Host " Macro to execute: $macroName "
365
422
Write-Host " Application state before macro execution: Type=$ ( $officeApp.GetType ().FullName) "
0 commit comments