Tuesday, July 5, 2011

Finding and Removing Dead Program Shortcuts

In Windows 7, I had moved my Start Menu to a folder on drive W.  This protected the Start Menu in case of Windows reinstallation, and made it available for regular backup on the same basis as everything else on drive W.  It could also be shared on a network.

That relocated Start Menu contained all the shortcuts normally found in a start menu.  I had since uninstalled some of the programs to which those shortcuts pointed.  There were a lot of programs, and a lot of shortcuts.  I wanted to find a way to automate the process of going through that folder and detecting the shortcuts that didn't work anymore. 

This post describes the start I made toward that effort.  The post is terminated prematurely.  I did not record the event leading to that termination.  I think I may have reinstalled Windows at that point.

I began with the assumption that the files I was looking for were .lnk files.  That is, I decided to disregard .url or any other kinds of link or shortcut files; I wanted only those that would link to an executable program on my computer.  This did not appear to be a major limiting assumption:  a quick look suggested that only a small number of files in the Start Menu were .url links.

On that assumption, in a CMD box (Start > Run > cmd), I went to the root of the Start Menu folder (using CD W:\) and ran a command to get a file list:

dir *.lnk /s /b /a-d > dirlist.txt
In the resulting dirlist.txt file, I found lots of lines with entries like "W:\Start Menu\Programs\Miscellany\Games\Freecell.lnk."  I copied the contents of dirlist.txt into a Microsoft Excel 2003 spreadsheet.  I added an index column at the far left, so as to number each filename that I had gotten from dirlist.txt.  I gave the files odd numbers.  For example, in cell A2 I typed this:  =A1+2.  I copied that all the way down column A.  So the consecutive rows were numbered 1, 3, 5, and so forth.  I made the numbers permanent by using this sequence:  highlight all numbers; Edit > Copy; Edit > Paste Special > Values.  (Alt-E would bring up those options in newer versions of Excel.)  Now cell A2 just contained the number 3, with no underlying formula.

I copied that worksheet into a second worksheet in the same Excel file.  Here, I replaced the numbers with even numbers.  So in this worksheet, cell A2 contained the number 4.  I named the first worksheet "Odd" and the second worksheet "Even."  I did this so that I could eventually combine the two worksheets into a Combined worksheet, and the numbers would sort in the correct order on that first column in the combined worksheet:  1, 2, 3 ...

In the Odd worksheet, I wanted to produce batch commands that would give me the name of the file we were talking about.  For this purpose, cell A1 contained the number 1, cell B1 contained a file and path name like "W:\Start Menu\Programs\Miscellany\Games\Freecell.lnk," and now cell C1 would contain this formula:  ="DIR /s /b /a-d "&CHAR(34)&B1&CHAR(34)&" >> output.txt."  The CHAR(34) would produce quotation marks that Excel would not misunderstand.  This formula produced a value in cell C1 like this:
DIR /s /b /a-d "W:\Start Menu\Adobe Acrobat.lnk" >> OUTPUT.TXT
I copied that formula all the way down column C, so that I had a whole series of commands to type the names of each link or shortcut file into the OUTPUT.TXT file.

Now I wanted OUTPUT.TXT to contain the file's contents after its name.  These link and shortcut files were typically pretty small, so I felt I could just put it all into the same OUTPUT.TXT file.  To get the file's contents, I went to the Even worksheet.  The command that I put into cell C1 in that spreadsheet was the same as the one quoted above, except here the command was TYPE rather than DIR (and had no /s or other parameters).  This would actually type the contents of the file into the tail end of OUTPUT.TXT.  Here, again, I copied the formula all the way down the worksheet.

With that done, I could combine the Odd and Even worksheets into a Combined worksheet.  I sorted the Combined worksheet on the first field, by the index numbers.  So now I had a list of paired commands, a DIR and a TYPE command for each .lnk file in my Start Menu.  So the first two resulting entries in this Combined worksheet looked like this:
DIR /s /b /a-d "W:\Start Menu\Adobe Acrobat.lnk" >> OUTPUT.TXT
TYPE "W:\Start Menu\Adobe Acrobat.lnk" >> OUTPUT.TXT
After running those two commands, OUTPUT.TXT contained gibberish looking somewhat like this:
W:\Start Menu\Adobe Acrobat.lnk
L        À      FÉP                                                     Ó PàOÐ ê:i ¢Ø +00 /C:\                   R 1     ¬>X~0 Windows < ï¾î:£ ¬>X~*   'ó                   W i n d o w s   X 1     ²>Í1 INSTAL~1  @ ï¾!>&y²>Í1*   ñ©                   I n s t a l l e r   ’ 1     ²>Í1 {A4EF1~1  z ᆵ> §²>Í1*   ô    
              { A C 7 6 B A 8 6 - 1 0 3 3 - F 4 0 0 - 7 7 6 0 - 0 0 0 0 0 0 0 0 0 0 0 4 }   h 2 ˜  ²>Í1! _SC_AC~1.EXE  L ï¾²>Í1²>Í1*   gz                   _ S C _ A c r o b a t . e x e      W . . \ . . \ . . \ . . \ . . \ W i n d o w s \ I n s t a l l e r \ { A C 7 6 B A 8 6 - 1 0 3 3 - F 4 0 0 - 7 7 6 0 - 0 0 0 0 0 0 0 0 0 0 0 4 } \ _ S C _ A c r o b a t . e x e K C : \ W i n d o w s \ I n s t a l l e r \ { A C 7 6 B A 8 6 - 1 0 3 3 - F 4 0 0 - 7 7 6 0 - 0 0 0 0 0 0 0 0 0 0 0 4 } \ _ S C _ A c r o b a t . e x e      34TL`aMnKwUK&!!'L?@$ViewerProgramFiles>c%TW.h=LK?6-6ht!be8]                                                                                                                                                                                                         3 4 T L ` a M n K w U K & ! ! ' L ? @ $ V i e w e r P r o g r a m F i l e s > c % T W . h = L K ? 6 - 6 h t ! b e 8 ]                                                                                                                                                                                                                                                                                                                                                                                                                        %SystemRoot%\Installer\{AC76BA86-1033-F400-7760-000000000004}\_SC_Acrobat.exe                                                                                                                                                                                       % S y s t e m R o o t % \ I n s t a l l e r \ { A C 7 6 B A 8 6 - 1 0 3 3 - F 4 0 0 - 7 7 6 0 - 0 0 0 0 0 0 0 0 0 0 0 4 } \ _ S C _ A c r o b a t . e x e
In other words, I had a link named "Adobe Acrobat" in W:\Start Menu, and that link connected with a file called _SC_Acrobat.exe in the "%SystemRoot%\Installer\{AC76BA86-1033-F400-7760-000000000004}" subfolder.  (The folder named %SystemRoot% would ordinarily be the C:\Windows folder.)  There no longer was any such subfolder, so this particular link was bad.  The challenge for me would thus be to extract those file and directory locations from OUTPUT.TXT, and test them to see which ones led to actual files and folders.

To extract the file and directory locations, I copied the gibberish of OUTPUT.TXT into Word 2003, and saved it as OUTPUT.DOC.  As shown in the gibberish example above, it appeared that extra spaces were added among many characters.  I searched OUTPUT.DOC and verified that there were no occurrences of @@@.  I did a find and replace in Word, replacing three consecutive spaces with @@@.  I repeated that until there were no more occurrences of three consecutive spaces.  Then I replaced all occurrences of two consecutive spaces with ### (also verified not to be present previously).  Next, I replaced all single spaces with nothing.  That is, I just eliminated them.  Now I could convert ### back to two spaces and all occurrences of @@@@ (since there had been a huge number of extra blank spaces) to just three "at" symbols (@@@).  I had to repeat that one a number of times.