At my job, I do a fair amount of system administration scripting in Python. For example, almost all the login scripts are written in Python (with some of them ported from Kixtart). Over the years, I’ve been tasked with creating shortcuts to new applications that need to be placed on the user’s desktop or in their Start Menu or both. In this article, I will show you how to accomplish this task.
Note: This is a Windows-only article, so if you don’t use that OS, then this will probably bore you to tears. Heck, it might do that anyway!
The first thing you’ll need to do much of anything on Windows is Mark Hammond’s PyWin32 package (AKA: Python for Windows extensions). I also recommend Tim Golden’s winshell module as it can make finding the user-specific folders much easier. I’ll be using Python 2.5 for this article, but as I understand it, PyWin32 is compatible with Python 3, so this tutorial could apply to those of you who use that too.
The simplest task I’ve had to do is to create a URL link on the user’s desktop. Unless you need to specify a specific browser, this is a really simple task:
import os, winshell desktop = winshell.desktop() path = os.path.join(desktop, "myNeatWebsite.url") target = "http://www.google.com/" shortcut = file(path, 'w') shortcut.write('[InternetShortcut]\n') shortcut.write('URL=%s' % target) shortcut.close()
In the code above, we import the os and winshell modules. We use winshell to grab the current user’s desktop path and then use the os.path’s join() function to connect the path and the name of the url shortcut. Since this is Windows only, you really don’t need to do it this way. A string concatenation would work just as well. Note that we need to supply a “url” extension so Windows knows what to do. Then we write a file using the path we created before and write [InternetShortcut] as the first line. On the second line, we write the url target and then we close the file. That’s it!
The next example will be a little more complex. In it, we will use the win32com module from the PyWin32 package to create a shortcut to Media Player Classic, which is a nice open-source media player. Let’s take a look at some code so we can see how to do this thing:
import os, winshell from win32com.client import Dispatch desktop = winshell.desktop() path = os.path.join(desktop, "Media Player Classic.lnk") target = r"P:\Media\Media Player Classic\mplayerc.exe" wDir = r"P:\Media\Media Player Classic" icon = r"P:\Media\Media Player Classic\mplayerc.exe" shell = Dispatch('WScript.Shell') shortcut = shell.CreateShortCut(path) shortcut.Targetpath = target shortcut.WorkingDirectory = wDir shortcut.IconLocation = icon shortcut.save()
The main takeaway here is the shell part. First you import Dispatch from win32com.client, then you call Dispatch(‘WScript.Shell’) to get a shell object (sort of) which you then use to create a shortcut object. Once you have that, you can assign values to the shortcut’s attributes, which are Targetpath, WorkingDirectory and IconLocation. Note that WorkingDirectory corresponds to the “Start In” field in a normal shortcut’s property dialog. In the script above, the IconLocation can be an icon file or it can extract the icon directly from the executable. One small got’cha here is that if you don’t call save, then the icon will not be created. In the previous example, we don’t explicitly have to call close on the file object because Python will take care of that for us when the script finishes.
Let’s take these two examples and make a reusable function out of them so we can use them in any login script we want:
from win32com.client import Dispatch def createShortcut(path, target='', wDir='', icon=''): ext = path[-3:] if ext == 'url': shortcut = file(path, 'w') shortcut.write('[InternetShortcut]\n') shortcut.write('URL=%s' % target) shortcut.close() else: shell = Dispatch('WScript.Shell') shortcut = shell.CreateShortCut(path) shortcut.Targetpath = target shortcut.WorkingDirectory = wDir if icon == '': pass else: shortcut.IconLocation = icon shortcut.save()
One obvious improvement we could add to this would be to use the os.path.dirname method to extract the Working Directory from the target and eliminate the need to pass that information in. Of course, I’ve seen some screwy shortcuts that don’t specify the target or the Working Directory at all! Anyway, I hope you will find this article helpful in your scripting. Until next time!
Hi Mike, great article.
Just a small comment: you say (first code explanation) and then use the os module’s path function to join the path and the name of the url shortcut
Probably should be and then use the os.path module’s join() function
Since this is Windows-only, you probably could just write (in the code) path = desktop + \myNeatWebsite.url
Hi Mike, great article.
Just a small comment: you say (first code explanation) \and then use the os module’s path function to join the path and the name of the url shortcut\
Probably should be \and then use the os.path module’s join() function\
Since this is Windows-only, you probably could just write (in the code) path = desktop + \\myNeatWebsite.url\
@ Tim,
Thanks for the links. I’m pretty sure those weren’t there when I originally came up with these methods as I Googled all over and visit your site quite a bit.
@ Steven,
I actually did think that line sounded weird when I wrote it. I’ve updated the text some to make it better and also added a note about concatenation as an alternative.
Thanks for the feedback, you guys!
– Mike
@ Tim,
Thanks for the links. I’m pretty sure those weren’t there when I originally came up with these methods as I Googled all over and visit your site quite a bit.
@ Steven,
I actually did think that line sounded weird when I wrote it. I’ve updated the text some to make it better and also added a note about concatenation as an alternative.
Thanks for the feedback, you guys!
– Mike
@ Domen,
I use Inno Setup to create an installer for my applications. It’s quite handy.
– Mike
@ Domen,
I use Inno Setup to create an installer for my applications. It’s quite handy.
– Mike
Hi Mike,
Have you managed to make shortcuts work?
I have failed in the past miserably and Since then I have stayed away “Inno the great”. How did you do? Any tutorial you used?
Thanks
@ Steve,
I just followed the directions on Inno’s website to get the links to work. Note that I created an executable using GUI2Exe first. You can check all that out in this tutorial I wrote:
https://www.blog.pythonlibrary.org/2008/08/27/packaging-wxpymail-for-distribution/
Hope that helps!
– Mike
Very useful tutorial !
I translated this article and Tim Golden’s to Spanish and published the all-in-one version in my blog
http://simelo-es.blogspot.com/2010/03/tutorial-como-crear-enlaces-directos-en.html
Hope this will be valuable for native Spanish speakers
Very useful tutorial !
I translated this article and Tim Golden’s to Spanish and published the all-in-one version in my blog
http://simelo-es.blogspot.com/2010/03/tutorial-como-crear-enlaces-directos-en.html
Hope this will be valuable for native Spanish speakers
I actually did think that line sounded weird when I wrote it. I’ve updated the text some to make it better and also added a note about concatenation as an alternative.
Thanks for the feedback, you guys!new release air jordan