1

When you try to open a shortcut file (.lnk) that no longer works, Windows lets you know with a prompt that says: "This shortcut has been changed or moved, so this shortcut will no longer work properly." Is there a python code I can use to detect whether such a shortcut no longer works?

When I run the following code to retrieve the target path of a shortcut that no longer works, I don't get any type of error. The code still prints the path to the target file that doesn't exist anymore:

import win32com.client

shell = win32com.client.Dispatch('WScript.Shell')
shortcut = shell.CreateShortcut(shortcutpath_cur)
target = shortcut_cur.Targetpath

print(target)

Sometimes a shortcut no longer works even if the document it points to still exists. In that case, I couldn't use os.path.exists() or os.path.isfile() because they would return True.

Manar
  • 137
  • 8
  • why don't you just check whether `target` is a valid path? – David Zemens Mar 29 '19 at 18:44
  • `import os` and then `os.path.exists(target)` – David Zemens Mar 29 '19 at 18:46
  • @DavidZemens Sometimes a shortcut no longer works even if the document it points to still exists. In that case, `os.path.exists(target)` would still be `True`. I'm trying to detect whether the shortcut itself doesn't work. I will add that clarification to the question. – Manar Mar 29 '19 at 18:50
  • 1
    hmmm. i've never encountered that situation, but figure there's probably [a shell method](https://ss64.com/vb/shell.html) that you could use with try/except. that's where I'd start looking :) good luck! – David Zemens Mar 29 '19 at 18:56

1 Answers1

3

You could do this by attempting to check if the file path has an existing file. There is a solution here on SO that contains many ways to do this: How do I check whether a file exists without exceptions?

If you check if the file exists at the path specified by the shortcut you can then detect whether the shortcut itself would work and do your own procedures for it.

Here is a quote from the link above that you could use to do this:

"If you're not planning to open the file immediately, you can use os.path.isfile

Return True if path is an existing regular file. This follows symbolic links, so both islink() and isfile() can be true for the same path.

import os.path
os.path.isfile(fname) 

if you need to be sure it's a file."

If for some reason the file exists but your shortcut doesnt work, this wouldn't work. You could then use a try: to open the file and except: all the possible errors that may arise. Sometimes a shortcut won't work because of insufficient permissions or because the target is no longer valid.

If the file exists but it won't open via shortcut then it's a problem with the shortcut file itself, the target file, an operating system bug/glitch, or insufficient permissions.

Keith Cronin
  • 373
  • 2
  • 9
  • I added a clarification to my question. Sometimes a shortcut no longer works even if the document it points to still exists. In that case, using `os.path.isfile()` would still return `True`. – Manar Mar 29 '19 at 18:53
  • 1
    @Manar, I edited the answer based off the clarification. – Keith Cronin Mar 29 '19 at 19:08
  • Thank you! This works for the most part. Only problem is if the shortcut points to a directory. Even if the shortcut opens fine, I'm getting a "Permission denied" error. Does open() only work for files? – Manar Mar 29 '19 at 20:26
  • @Manar Yes, `open()` is only for files. Try running your python script as admin. – Keith Cronin Mar 29 '19 at 21:19
  • @Manar You can't `open()` a directory. It must be a file. You can change the current working directory with `os.chdir()`. Opening directories is something you do with a file explorer. In python, directories are paths to files that you interact with. – Keith Cronin Mar 29 '19 at 21:27
  • We can open a directory in the general sense of the word (as in get a handle for it as a Windows file object), but not via Python's built-in `open` function. Python goes out of its way to prohibit this even if it's allowed by the underling system call. – Eryk Sun Mar 30 '19 at 02:40