Visio cannot open the file or a component in the file because it is corrupt (Visio 2016)
After upgrading a number of systems to Visio 2016, I started to hear more and more about old pre-2010 Visio files in VSD format that would no longer open and would throw the following error:
The strange thing was that the files were still launching without issue for users who were still on Visio 2010 and 2013. The consensus as I searched around the Internet was that the older VSD files often had too many shaped embedded in them, and the fix was to open them in Visio 2010 or 2013, go through a process of removing unused shapes, and then saving in VSDX format. Saving the file in the new format without removing the shapes would not resolve the issue.
I worked for a few hours on finding ways to be able to do this in newer versions of Visio, but never came up with a solution. Instead, I found pieces of random VBScripts online where people were doing similar things, and then assisted users in converting these documents to the newer formats in bulk by writing a PowerShell script that essentially did what others were either doing manually or with VBS. While I normally like to references my sources in my blog posts, unfortunately I didn't bookmark the page where I found the most useful information about the Visio COM - so apologies to that author if he ever happens across this post.
The following script is not pretty. It was a rush job to get a large number of users whom I'd just upgraded working again quickly. I often pretty up my code before posting, but this time I'm giving it to you the way I originally wrote it. You're welcome to use it, modify it, redistribute it, and perhaps even make it a little nicer yourself. As with all code you find online, backup your original files first, and always run in test before ever using on anything in production.
1$vsdPath = "C:\temp\Visio2010\2010"
2
3$visio = New-Object -ComObject Visio.Application
4
5If(-Not (Test-Path "$vsdPath\Fixed" -ErrorAction SilentlyContinue)) {
6 New-Item -ItemType Directory -Path "$vsdPath\Fixed" -ErrorAction Stop | Out-Null
7}
8
9Get-ChildItem $vsdPath | Where-Object { $_.Name -like "*.vsd" -and !(Get-ChildItem "$vsdPath\Fixed\$($_.Name)" -ErrorAction SilentlyContinue) } | % {
10
11 $fileName = $_.FullName
12
13 Write-Host "Processing $fileName"
14
15 $document = $visio.documents.open($fileName)
16
17 $objectsToDelete = @()
18
19 ForEach($master in $document.masters) {
20
21 $bThisShapeInUse = $false
22
23 ForEach($page in $visio.ActiveDocument.Pages) {
24
25 ForEach($shape in $page.shapes) {
26
27 if($shape.Name -eq $master.Name) {
28 $bThisShapeInUse = $true
29 }
30 }
31
32 }
33
34 if($bThisShapeInUse -eq $false) {
35 $objectsToDelete += $master.Name
36 } else {
37 "Keeping $($master.name)."
38 }
39
40 }
41
42 Write-Host "Time to delete!"
43
44 if($objectsToDelete) {
45 $($document.Masters | Where-Object { $_.Name -in $objectsToDelete }).delete()
46 }
47
48 $document.SaveAs("$vsdPath\Fixed\$($_.Name)")
49 $document.Close()
50
51}
52
53$visio.Quit()
No comments