14

If I use the following to get the list of all connected drives:

available_drives = ['%s:' % d for d in string.ascii_uppercase if os.path.exists('%s:' % d)]

How do I get the UNC path of the connected drives?

os.path just returns z:\ instead of \share\that\was\mapped\to\z

Robben_Ford_Fan_boy
  • 8,494
  • 11
  • 64
  • 85
  • Note: I didn't try executing this. https://docs.python.org/2/library/os.path.html Based on this, "Note On Windows, many of these functions do not properly support UNC pathnames. splitunc() and ismount() do handle them correctly". os.path.splitunc(path) Split the pathname path into a pair (unc, rest) so that unc is the UNC mount point (such as r'\\host\mount'), if present, and rest the rest of the path (such as r'\path\file.ext'). For paths containing drive letters, unc will always be the empty string. – prashanth Jul 10 '17 at 13:13
  • Try the following library in the blog post. http://developer.covenanteyes.com/unc-paths-with-python/ The link to the library http://covenanteyes.github.io/py_win_unc/ – prashanth Jul 10 '17 at 13:19
  • been a while since I did this, but iirc the way I found is to call `net show` (sp?) and parse the output... don't have any windows machines nearby to try it now... – Corley Brigman Jul 10 '17 at 13:19

3 Answers3

14

Use win32wnet from pywin32 to convert your drive letters. For example:

import win32wnet
import sys

print(win32wnet.WNetGetUniversalName(sys.argv[1], 1))

This gives me something like this when I run it:

C:\test>python get_unc.py i:\some\path
\\machine\test_share\some\path
Peter Brittain
  • 13,489
  • 3
  • 41
  • 57
  • Doesn't deal with local drives, instead use https://stackoverflow.com/a/45016081 by @njoosse – a different ben Dec 04 '18 at 04:26
  • Local drives don't have a UNC name. Only shared drives on a network will have them. Anyway, I'd still recommend using pywin32 rather than rolling your own ctypes access to windows, including http://timgolden.me.uk/pywin32-docs/win32wnet__WNetGetConnection_meth.html – Peter Brittain Dec 04 '18 at 07:52
  • Sorry, you're completely right. I was thinking about the error, which you can just catch of course. – a different ben Dec 05 '18 at 00:31
6

Here's how to do it in python ≥ 3.4, with no dependencies!*

from pathlib import Path

def unc_drive(file_path):
    return str(Path(file_path).resolve())

*Note: I just found a situation in which this method fails. One of my company's network shares has permissions setup such that this method raises a PermissionError. In this case, win32wnet.WNetGetUniversalName is a suitable fallback.

Terry Davis
  • 511
  • 5
  • 8
3

Using ctypes and the code shown in the first answer in this post: Get full computer name from a network drive letter in python, it is possible to get the drive paths for every network drive, or a selected few.

The get_connection function given will throw an error if the drive is not a network drive, either local or removable drives, this can be accounted for with

# your drive list
available_drives = ['%s:' % d for d in string.ascii_uppercase if os.path.exists('%s:' % d)]
for drive in available_drives:
    try:
        # function from linked post
        print(get_connection(drive))
    except WindowsError: # thrown from local drives
        print('{} is a local drive'.format(drive))
njoosse
  • 549
  • 3
  • 8