Question

I need to determine Windows short file name from my python code. For that I can find a solution using the win32api.

import win32api
long_file_name='C:\Program Files\I am a file'
short_file_name=win32api.GetShortPathName(long_file_name)

Reference: http://blog.lowkster.com/2008/10/spaces-in-directory-names-i-really-love.html

Unfortunately for that I need to install pywin32 or ActivePython which is not possible in my case.

Also reference from SO:

Getting short path in python: Getting short path in python

Was it helpful?

Solution

You can use ctypes. According to the documentation on MSDN, GetShortPathName is in KERNEL32.DLL. Note that the real functions are GetShortPathNameW for wide (Unicode) characters and GetShortPathNameA for single-byte characters. Since wide characters are more general, we'll use that version. First, set the prototype according to the documentation:

import ctypes
from ctypes import wintypes
_GetShortPathNameW = ctypes.windll.kernel32.GetShortPathNameW
_GetShortPathNameW.argtypes = [wintypes.LPCWSTR, wintypes.LPWSTR, wintypes.DWORD]
_GetShortPathNameW.restype = wintypes.DWORD

GetShortPathName is used by first calling it without a destination buffer. It will return the number of characters you need to make the destination buffer. You then call it again with a buffer of that size. If, due to a TOCTTOU problem, the return value is still larger, keep trying until you've got it right. So:

def get_short_path_name(long_name):
    """
    Gets the short path name of a given long path.
    http://stackoverflow.com/a/23598461/200291
    """
    output_buf_size = 0
    while True:
        output_buf = ctypes.create_unicode_buffer(output_buf_size)
        needed = _GetShortPathNameW(long_name, output_buf, output_buf_size)
        if output_buf_size >= needed:
            return output_buf.value
        else:
            output_buf_size = needed
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top