Skip to content

Robust Sharepoint and onedrive mount location from registry #1829

@jreyenga

Description

@jreyenga

OS (e.g. Windows 10 or macOS Sierra)

Win10

Versions of xlwings, Excel and Python (e.g. 0.11.8, Office 365, Python 3.7)

xlwings 0.26, python 3.8.8

Describe your issue (incl. Traceback!)

I have found that at least for windows the current user registry contains all the URLs and mount points for both onedrive and sharepoint. Sample code below successfully takes OneDrive and Sharepoint URL path, scans multiple mounts in registry, and returns the local path. This should allow files to live on sharepoint with arbitrary mounts and move around without any custom environment variables...

I haven't hacked utils.py yet but the logic below 'should' work... at least for windows. It's not the cleanest code in the world, but the info is there to find the local path for sharepoint files.

Thoughts?

import winreg
import os


def URL2Local(url):
    REG_Path = r"SOFTWARE\SyncEngines\Providers\OneDrive"
    MountName = 'MountPoint'
    URLName = 'URLNamespace'

    # iterate through base OneDrive to fine all sub-keys
    reg_key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, REG_Path, 0, winreg.KEY_READ)
    i = 0
    subkeys = []
    while True:
        try:
            subkey = winreg.EnumKey(reg_key, i)
            subkeys.append(subkey)
            i = i + 1
        except WindowsError:
            break
    winreg.CloseKey(reg_key)

    # iterate through subkeys to get a list of all mounts and urls
    URLs = []
    Mounts = []
    for subkey in subkeys:
        subREG_Path = os.path.join(REG_Path, subkey)
        reg_key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, subREG_Path, 0, winreg.KEY_READ)
        value, regtype = winreg.QueryValueEx(reg_key, MountName)
        Mounts.append(value)
        value, regtype = winreg.QueryValueEx(reg_key, URLName)
        URLs.append(value)
        winreg.CloseKey(reg_key)

    # iterate through keys to find match with mount
    # Could technically combine with the previous iteration
    LocalPath = ''
    for idx, location in enumerate(URLs):
        if location in url:
            LocalPath = Mounts[idx]
            LocalPath = os.path.join(LocalPath, url[len(location):])
            LocalPath = os.path.normcase(LocalPath)
        else:
            pass

    return LocalPath

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Done

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions