Path to files on start menu
I was asked today if it was possible the path to recent files that are shown on the start menu. I thought it was easy until I started digging into it. The files on the start menu are .lnk files and are in a binary format.
| 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020
| $rd = New-Object -ComObject Shell.Application Get-ChildItem -Path $rd.Namespace(0x8).Self.Path | where {-not $_.PSIsContainer} | foreach { if (Test-Path $_.Fullname){ $txt = (Select-String -InputObject (Get-Content -Path $_.Fullname ) -Pattern ":\" -SimpleMatch).ToString() $i = $txt.LastIndexOf(":\") $txt2 = $txt.SubString($i-1) $i = 0 $stuffs = $txt2.ToCharArray() foreach($stuff in $stuffs){ $test = [byte]$stuff if($test -eq 0){break} $i++ } -join $stuffs[0..$i] } } |
Getting the actual .lnk files is easy because they are in a special folder. Create a COM object for the Shell.Application and then get-childitem on the contents of the Recent Files folder designated by 0x8. Filter out ant subfolders.
For each .lnk file on the start menu – check that it actually exists, and do a select-string on the content to find the last “:\” – this is near the start of the path of the real file.
Jump back a character and take the string from that point to the end – we don’t know how long the file path is.
The file path has some special characters after it – byte code 0 so we flip the string into a char array and test the byte of each character. Once we find a 0 we know we’ve hit the end of the path so we rejoin the array of chars – up to that point and output the string
This works except that anything on the desktop or other special folder the path gets truncated.
I’ll solve that another day.