4

I have created shortcuts for executables and it works, but when I try to create one for a folder it does not work. It does create a shortcut, it is just not the right 'Target Type'. Please take a look at the image below. Instead of 'File', the target type should be 'File folder'. The problem is that when I open the shortcut it asks me which program do I want to open the File with and it does not open the folder.

screenshot showing incorrect Target property of a shortcut created to a folder with my code

The function I'm using to create the shortcuts is the following

from win32com.client import Dispatch
import winshell
import os

def create_shortcuts(self, tool_name, exe_path, startin, icon_path):

    shell = Dispatch('WScript.Shell')
    shortcut_file = os.path.join(winshell.desktop(), tool_name + '.lnk')
    shortcut = shell.CreateShortCut(shortcut_file)
    shortcut.Targetpath = exe_path
    shortcut.WorkingDirectory = startin
    shortcut.IconLocation = icon_path
    shortcut.save()

I don't know if it's possible to set the 'Target Type'. I couldn't find a way to do it, but I do know there must be a way.

martineau
  • 119,623
  • 25
  • 170
  • 301
munoz
  • 65
  • 1
  • 6
  • 1
    I just ran your code using Python 3.6.1 on Windows 7 and it created a perfectly valid shortcut to a folder on my desktop (and that works correctly when you click to open it). The Target Type property of shortcut created is set to `File folder`. [Screenshot](https://www.dropbox.com/s/4ffhc0sf4rse8hv/properties-of-shortcut.png?dl=0). – martineau Apr 22 '17 at 02:44
  • Thanks @martineau, I ran the code on windows server 2008 and python 3.4.4, and it did not work. Any idea why? or how to work around it? – munoz Apr 25 '17 at 17:26
  • 1
    It could be the arguments you're passing the function are incorrect—it's hard to tell because you didn't include an example of a call to the function that fails. One important thing to remember is that all paths passed to the function must include backslash characters, which means if they are literals you either have to double each one like this: `"C:\\path\\to\\some\\folder"` or use the `r` string prefix like this `r"C:\path\to\some\folder"`. – martineau Apr 25 '17 at 17:50
  • 2
    That was the problem, I was missing some backslashs. Since the path was showing correctly in the target entry in the shortcut properties, I did not think that the path was being the problem, but it was. Thanks @martineau! – munoz Apr 25 '17 at 19:33
  • 1
    That's good to hear. In the future you should provide a [**MCVE**](https://stackoverflow.com/help/mcve) to allow others to reproduce the problem (instead of guessing) because you'll get a better response(s) if you do so. – martineau Apr 25 '17 at 19:36

2 Answers2

1

If you want to use .Net "clr" (especially if you already require it):

First run this... you will have to ship the output of this command with your application:

"c:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\TlbImp.exe" %SystemRoot%\system32\wshom.ocx /out:Interop.IWshRuntimeLibrary.dll

tlbimp.exe might even be in the path if you installed the Windows SDK in a fairly standard way. But if not, it's OK, you'll just ship the "assembly" (fancy word for interface-providing dll in .Net land) with your application.

Then this code will work in python:

import clr
sys.path.append(DIRECTORY_WHERE_YOU_PUT_THE_DLL)
clr.AddReference('Interop.IWshRuntimeLibrary')
import Interop.IWshRuntimeLibrary
sc = Interop.IWshRuntimeLibrary.WshShell().CreateShortcut("c:\\test\\sc.lnk")
isc = Interop.IWshRuntimeLibrary.IWshShortcut(sc)
isc.set_TargetPath("C:\\")
isc.Save()

.... the above code, with far too much modification and preamble, might even work with Mono.

Erik Aronesty
  • 11,620
  • 5
  • 64
  • 44
0

For future reference: I observed the described behavior in python 3.9.6 when creating a shortcut to a non-existing directory, which was easily fixed by incorporating os.makedirs() into the method. I've added a method parameter to the version I'm using, so it can handle shortcuts to files and directories:

def create_shortcuts(self, tool_name, exe_path, startin, icon_path, is_directory=False):
    if is_directory:
        os.makedirs(exe_path, exist_ok=True) 

    shell = Dispatch('WScript.Shell')
    shortcut_file = os.path.join(winshell.desktop(), tool_name + '.lnk')
    shortcut = shell.CreateShortCut(shortcut_file)
    shortcut.Targetpath = exe_path
    shortcut.WorkingDirectory = startin
    shortcut.IconLocation = icon_path
    shortcut.save()
M463
  • 2,003
  • 3
  • 23
  • 39