An Intro to winshell

Today we will look at Tim Golden’s handy package, winshell. The winshell package allows you to find special folders on Windows, create shortcuts easily, work with metadata via “structured storage”, use the Windows shell to accomplish file operations and work with the Windows Recycle Bin.

We will focus on the special folders, shortcuts and the Recycle bin functionality of winshell in this article.


Getting Started

The winshell package depends on having PyWin32 installed. Make sure you have that installed first. Once that’s done, you can install winshell using pip:

pip install winshell

Now that you have winshell installed, we can continue.


Accessing Special Folders

The winshell package exposes access to the paths of special folders in Windows. The paths exposed are:

  • application_data
  • favourites
  • bookmarks (alias of favourites)
  • start_menu
  • programs
  • startup
  • personal_folder
  • my_documents (alias of personal_folder)
  • recent
  • sendto

Let’s look at a few examples:

>>> import winshell
>>> winshell.application_data()
'C:\\Users\\mdriscoll\\AppData\\Roaming'
>>> winshell.desktop()
'C:\\Users\\mdriscoll\\Desktop'
>>> winshell.start_menu()
'C:\\Users\\mdriscoll\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu'

This is pretty self-explanatory. Let’s take a look at one other related method that’s called folder. According to the documentation, it uses either the CSIDL numeric constant or the corresponding name, eg “appdata” for CSIDL_APPDATA or “desktop” for CSIDL_DESKTOP. Let’s look at a simple example:

>>> import winshell
>>> winshell.folder("desktop")
'C:\\Users\\mdriscoll\\Desktop'

This uses some Windows internals that I’ve never even heard of. You will probably need to look up CSIDL numeric constants on MSDN to use this part of winshell effectively. Otherwise I would recommend just sticking with the previously mentioned functions.


Working with Shortcuts

You can use winshell to get information about shortcuts. Let’s take a look at an example where we look at a Google Chrome shortcut:

>>> import winshell
>>> import os
>>> link_path = os.path.join(winshell.desktop(), "Google Chrome.lnk")
>>> sh = winshell.shortcut(link_path)
>>> sh.path
'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'
>>> sh.description
'Access the Internet'
>>> sh.arguments
''

This let’s us learn a bit about the shortcut’s properties. There are a bunch of other methods we could call as well. I recommend reading the full documentation to see what else you can do. Now let’s try creating a shortcut using winshell:

>>> winshell.CreateShortcut(
    Path=os.path.join(winshell.desktop(), "Custom Python.lnk"),
    Target=r"c:\python34\python.exe",
    Icon=(r"c:\python34\python.exe", 0),
    Description="The Python Interpreter")

If you’re a long time reader of this blog, you may recall that I actually wrote about creating shortcuts with winshell several years ago. The functionality here isn’t really any different than it was before and is pretty self-explanatory. You might want to check out that old article though as it also shows how to create shortcuts using PyWin32 too.


winshell and the Recycle Bin

You can also use winshell to access the Windows Recycle Bin. Let’s see what you can do:

>>> import winshell
>>> recycle_bin = winshell.recycle_bin()
>>>
>>> # undelete a file
>>> recycle_bin.undelete(filepath)
>>>
>>> # empty the recycle bin
>>> recycle_bin.empty(confirm=False)

If you call the undelete method multiple times on the same path, you will undelete previous versions of the file that were deleted, if applicable. You can also empty the Recyle Bin via the empty method. There are also some undocumented methods, such as items or folders that appear to return a generator object that I assume you can iterate over to discover what all is currently in the Recycle Bin.


Wrapping Up

At this point, you should be able to use the winshell package pretty competently. You have just learned how to work with the Recycle Bin, read and write shortcuts and acquire special folders on Windows. I hope you have enjoyed this tutorial and can use it in your own code soon.