Modify Windows shortcuts using Python
Asked Answered
Y

5

9

How do you change a Windows shortcut using Python?

e.g. from:

H:\My Music\some_file.mp3

to:

D:\Users\Myself\My Music\some_file.mp3
Yasmeen answered 24/7, 2011 at 8:55 Comment(3)
Have you tried this: #6806381 ?Ludewig
Followup question for unicode shortcutsYasmeen
Answer for unicode. https://mcmap.net/q/1172958/-modify-windows-unicode-shortcuts-using-pythonKitsch
L
8

Here's another, more appropriate way to do this in Python with Winshell library: Using Python to create Windows shortcuts. In your case the code will look like:

import os, winshell
from win32com.client import Dispatch

desktop = winshell.desktop()
path = os.path.join(desktop, "some_file.mp3.lnk")
target = r"D:\Users\Myself\My Music\some_file.mp3"
wDir = r"D:\Users\Myself\My Music"
icon = r"D:\Users\Myself\My Music\some_file.mp3"

shell = Dispatch('WScript.Shell')
shortcut = shell.CreateShortCut(path)
shortcut.Targetpath = target
shortcut.WorkingDirectory = wDir
shortcut.IconLocation = icon
shortcut.save()

Existing shortcut should be deleted or rewritten. If you need it for batch processing of shortcut files then I think there's some way to read paths from existing shortcuts, but didn't managed to find it.

Ludewig answered 24/7, 2011 at 11:9 Comment(1)
winshell is probably not far fetched. still it's not build-in. And just to get the users desktop location you can also do: os.path.join(os.getenv('userprofile'), 'desktop')Unveil
H
4

Jonathan's solution works perfectly. This is the useful function I produced implementing this. Simply pass in the name of the shortcut file (for example "Mozilla Firefox.lnk", it is unnecessary to specify the entire filepath), and the new shortcut destination, and it will be modified.

import os, sys
import pythoncom
from win32com.shell import shell, shellcon

def short_target(filename,dest):
    shortcut = pythoncom.CoCreateInstance (
        shell.CLSID_ShellLink,
        None,
        pythoncom.CLSCTX_INPROC_SERVER,
        shell.IID_IShellLink
    )
    desktop_path = shell.SHGetFolderPath (0, shellcon.CSIDL_DESKTOP, 0, 0)
    shortcut_path = os.path.join (desktop_path, filename)
    persist_file = shortcut.QueryInterface (pythoncom.IID_IPersistFile)
    persist_file.Load (shortcut_path)
    shortcut.SetPath(dest)
    mydocs_path = shell.SHGetFolderPath (0, shellcon.CSIDL_PERSONAL, 0, 0)
    shortcut.SetWorkingDirectory (mydocs_path)
    persist_file.Save (shortcut_path, 0)

The only dependency is the pywin32 library. Also note that one is able to specify options and arguments in their shortcut destination. To implement, just call:

short_target("shortcut test.lnk",'C:\\')   #note that the file path must use double backslashes rather than single ones. This is because backslashes are used for special characters in python (\n=enter, etc) so a string must contain two backslashes for it to be registered as one backslash character.

This example will set the destination of a shortcut on your desktop called "shortcut test" to a shortcut that opens up the file manager in the root directory of the hard drive (C:).

Hardesty answered 27/3, 2014 at 1:16 Comment(1)
I was looking for a way to SetWorkingDirectory to "" to get shortcuts to work like normal programs. This helped me.Perforce
L
2

Here is how you can create a shortcut using Windows script host: http://msdn.microsoft.com/en-us/library/fywyxt64

Try to write it to file from Python and run it dynamically.

Ludewig answered 24/7, 2011 at 9:4 Comment(0)
Y
2

Yet another method is detailed here

Use the shortcut update example. You can shortcut.GetPath(), modify it and then use shortcut.SetPath() method to set it.

Yasmeen answered 1/8, 2011 at 4:45 Comment(0)
P
1

The previous answer are perfectly valid however to really complete them I added the code for bulk editing because I suppose you might have a lots of link to edit.

use this if you want to edit many links at once:

import os, sys
import glob
import pythoncom
from win32com.shell import shell, shellcon

def shortcut_target (filename):
  link = pythoncom.CoCreateInstance (
    shell.CLSID_ShellLink,    
    None,
    pythoncom.CLSCTX_INPROC_SERVER,    
    shell.IID_IShellLink
  )
  persist_file = link.QueryInterface (pythoncom.IID_IPersistFile)
  persist_file.Load (filename)
  #
  # GetPath returns the name and a WIN32_FIND_DATA structure
  # which we're ignoring. The parameter indicates whether
  # shortname, UNC or the "raw path" are to be
  # returned. Bizarrely, the docs indicate that the 
  # flags can be combined.
  #
  name, _ = link.GetPath (shell.SLGP_UNCPRIORITY)

  target = name
  target = target.replace('H:\My Music', 'D:\Users\Myself\My Music')

  link.SetPath(target)
  persist_file.Save(filename, 0)

  return name

def shell_glob (pattern):
  for filename in glob.glob (pattern):
    if filename.endswith (".lnk"):
      print shortcut_target(filename)



desktop = "H:\My Music\"
for filename in shell_glob (os.path.join (desktop, "*")):
  print filename
Padraig answered 23/1, 2018 at 13:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.