getLocalOneDrivePath to be updated (?) #144
Replies: 16 comments
-
Hi @6DiegoDiego9, unfortunately I don't use OneDrive so cannot debug why it is not working... Dim fso As New FileSystemObject
If Not fso.FolderExists(GetLocalOneDrivePath) Then GetLocalOneDrivePath = strPath 'OneDrive folder excluded from sync (@6DiegoDiego9) Could either one of those changes have caused the issue? '------------------------SELENIUMVBA VERSION 2.0-----------------------
Private Function GetLocalOneDrivePath(ByVal strPath As String) As String
' thanks to @6DiegoDiego9 for doing research on this (see https://stackoverflow.com/a/72736800/11738627)
' this function returns the original/local disk path associated with a synched OneDrive or SharePoint cloud url
If isPathHTTPS(strPath) Then
Const HKEY_CURRENT_USER = &H80000001
Dim objReg As WbemScripting.SWbemObjectEx 'changed to early binding by GCUser99
Dim regPath As String
Dim subKeys() As Variant
Dim subKey As Variant
Dim strValue As String
Dim strMountpoint As String
Dim strSecPart As String
Static pathSep As String
If pathSep = "" Then pathSep = Application.PathSeparator
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
regPath = "Software\SyncEngines\Providers\OneDrive\"
objReg.EnumKey HKEY_CURRENT_USER, regPath, subKeys
If isArrayInitialized(subKeys) Then 'found OneDrive in registry
For Each subKey In subKeys
objReg.getStringValue HKEY_CURRENT_USER, regPath & subKey, "UrlNamespace", strValue
If InStr(strPath, strValue) > 0 Then
objReg.getStringValue HKEY_CURRENT_USER, regPath & subKey, "MountPoint", strMountpoint
strSecPart = Replace(Mid(strPath, Len(strValue)), "/", pathSep)
GetLocalOneDrivePath = strMountpoint & strSecPart
Do Until Dir(GetLocalOneDrivePath, vbDirectory) <> "" Or InStr(2, strSecPart, pathSep) = 0
strSecPart = Mid(strSecPart, InStr(2, strSecPart, pathSep))
GetLocalOneDrivePath = strMountpoint & strSecPart
Loop
Exit Function
End If
Next subKey
End If
End If
GetLocalOneDrivePath = strPath 'pass unchanged
End Function '------------------------SELENIUMVBA VERSION 6.3-----------------------
Private Function GetLocalOneDrivePath(ByVal strPath As String) As String
'for more info, see https://stackoverflow.com/a/72736800/11738627 post by Guido Witt-Dorring
'this function returns the original/local disk path associated with a synched OneDrive or SharePoint cloud url
If isPathHTTPS(strPath) Then
Const HKEY_CURRENT_USER = &H80000001
Dim objReg As WbemScripting.SWbemObjectEx 'changed to early binding by GCUser99
Dim regPath As String
Dim subKeys() As Variant
Dim subKey As Variant
Dim strValue As String
Dim strMountpoint As String
Dim strSecPart As String
Static pathSep As String
If pathSep = vbNullString Then pathSep = "\" '<------------------------GCUser99 Changed this line
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
regPath = "Software\SyncEngines\Providers\OneDrive\"
objReg.EnumKey HKEY_CURRENT_USER, regPath, subKeys
If isArrayInitialized(subKeys) Then 'found OneDrive in registry
For Each subKey In subKeys
objReg.getStringValue HKEY_CURRENT_USER, regPath & subKey, "UrlNamespace", strValue
If InStr(strPath, strValue) > 0 Then
objReg.getStringValue HKEY_CURRENT_USER, regPath & subKey, "MountPoint", strMountpoint
strSecPart = Replace$(Mid$(strPath, Len(strValue)), "/", pathSep)
GetLocalOneDrivePath = strMountpoint & strSecPart
Do Until Dir(GetLocalOneDrivePath, vbDirectory) <> vbNullString Or InStr(2, strSecPart, pathSep) = 0
strSecPart = Mid$(strSecPart, InStr(2, strSecPart, pathSep))
GetLocalOneDrivePath = strMountpoint & strSecPart
Loop
'<------------------------At some point these two lines were added
Dim fso As New FileSystemObject
If Not fso.FolderExists(GetLocalOneDrivePath) Then GetLocalOneDrivePath = strPath 'OneDrive folder excluded from sync (@6DiegoDiego9)
Exit Function
End If
Next subKey
End If
End If
GetLocalOneDrivePath = strPath 'pass unchanged
End Function Private Function isArrayInitialized(ByRef arry() As Variant) As Boolean
If (Not arry) = -1 Then isArrayInitialized = False Else isArrayInitialized = True
End Function As far as the original source, I think we used this short version: Public Function GetLocalPath(ByVal Path As String) As String
Const HKCU = &H80000001
Dim objReg As Object, rPath As String, subKeys(), subKey
Dim urlNamespace As String, mountPoint As String, secPart As String
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\." & _
"\root\default:StdRegProv")
rPath = "Software\SyncEngines\Providers\OneDrive\"
objReg.EnumKey HKCU, rPath, subKeys
For Each subKey In subKeys
objReg.GetStringValue HKCU, rPath & subKey, "UrlNamespace", urlNamespace
If InStr(Path, urlNamespace) > 0 Then
objReg.GetStringValue HKCU, rPath & subKey, "MountPoint", mountPoint
secPart = Replace(Mid(Path, Len(urlNamespace)), "/", "\")
Path = mountPoint & secPart
Do Until Dir(Path, vbDirectory) <> "" Or InStr(2, secPart, "\") = 0
secPart = Mid(secPart, InStr(2, secPart, "\"))
Path = mountPoint & secPart
Loop
Exit For
End If
Next
GetLocalPath = Path
End Function And then there is always the deluxe version. |
Beta Was this translation helpful? Give feedback.
-
Maybe it should be: Dim fso As New FileSystemObject
If Not fso.FolderExists(fso.GetParentFolderName(GetLocalOneDrivePath)) Then GetLocalOneDrivePath = strPath 'OneDrive folder excluded from sync (@6DiegoDiego9) or: Dim fso As New FileSystemObject
If Not fso.FileExists(GetLocalOneDrivePath) Then GetLocalOneDrivePath = strPath 'OneDrive folder excluded from sync (@6DiegoDiego9) ? |
Beta Was this translation helpful? Give feedback.
-
The current "short version" on StackOverflow, with my mods at the beginning and at the end, works for me as expected for both my OneDrive situations (sync and not sync):
I'd propose to update with this. Thanks! |
Beta Was this translation helpful? Give feedback.
-
What if the path we are trying to resolve is either an existing folder or a file path that has not been created yet (like a save-file path)? getLocalOneDrivePath = IIf(fso.FolderExists(fso.GetParentFolderName(Path)), Path, origPath) 'fallback to original path if it's online-only (excluded from sync) (@6DiegoDiego9) |
Beta Was this translation helpful? Give feedback.
-
Oh, sorry, you're right! I completely ignored/forgot that this function could be used for folders too, not only for files. About your last line, it would be perfect, however it seems there is a "bug in the bug" in this "short version" since it skips the folder when converting an online-only fullpath: In the selected line, "NonSync" is skipped (it's a bug). fso.GetParentFolderName alone would return True because "C:\Users\i\OneDrive" exists, however I don't have the correct folder "C:\Users\i\OneDrive\NonSync". I'm not sure how to solve this issue though, because it's not reliably possible(?) to distinguish a path from a fullpath (path+filename), to put two different tests for those cases, fso.GetParentFolderName and fso.FileExists. |
Beta Was this translation helpful? Give feedback.
-
Thanks for looking into details @6DiegoDiego9. I'm wondering if it would make this easier to solve if we required the callers to only send folder/file paths to getFullLocalPath that are assumed to exist, and/or to indicate whether caller is asking to resolve a folder or a file path. For example, this line in iniFilePath = getFullLocalPath(thisLibFolderPath) & "\SeleniumVBA.ini" In that case the caller knows it wants to resolve an (assumed) existing folder, not a file. So we could change to: iniFilePath = getFullLocalPath(thisLibFolderPath, pathType:=enumFolder) & "\SeleniumVBA.ini" Another in driverPath = getFullLocalPath(driverPath, defaultDriverFolder_) In this case caller wants to resolve an (assumed) existing file path. So we change to: driverPath = getFullLocalPath(driverPath, defaultDriverFolder_, pathType:=enumFile) Gets a little trickier with a method like folderPath = parsePath(filePath).Folder
filePath = getFullLocalPath(folderPath , defaultDriverFolder_, pathType:=enumFolder) & "\" & parsePath(filePath).File In almost all cases, we know what to do from the caller's perspective, and then we can call I don't mind reworking all of the callers if you can come up with a OneDrive solution that:
What do you think Diego? Do you think it is possible to solve under those conditions? |
Beta Was this translation helpful? Give feedback.
-
Yes, given the circumstances I'm absolutely OK to add a mandatory argument to getLocalOneDrivePath for passing type pathType, provided the fallback to original http path if the final "thing" (folder or file) doesn't exist. Thanks a lot for working on this issue Mike, very very appreciated! |
Beta Was this translation helpful? Give feedback.
-
@6DiegoDiego9, as far as solving the "bug", have you tried Cristian Buse's LibFileTools. The |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
So just to be clear, are you saying that you can fix the bug if you know whether the input path is to a folder or a file? If so, then I will get started refactoring the callers. Please send the solution when you have it... |
Beta Was this translation helpful? Give feedback.
-
Yes, I mean, you can simply test if the final path exists using FileExists or FolderExists, depending on whether it is specified as a file or folder:
|
Beta Was this translation helpful? Give feedback.
-
If so, then can't we just do: If Not (fso.FileExists(Path) Or fso.FolderExists(Path)) Then Path = origPath I would still have to refactor the callers to only send paths that are presumed to exist. But I still don't see how that would resolve the "bug within the bug" issue (skipping "NonSync")? |
Beta Was this translation helpful? Give feedback.
-
I didn't solve the "bug within the bug" issue, and this is the only reason I can't rely on your solution. |
Beta Was this translation helpful? Give feedback.
-
But I think |
Beta Was this translation helpful? Give feedback.
-
Ahhhh, stupid me, you're 100% right! FolderExists tests the whole thing, not just the folder of it 🤦🏻♂️ |
Beta Was this translation helpful? Give feedback.
-
@6DiegoDiego9 I included the fix in v6.4, but of course since i don't have OneDrive installed, all I could do was test that the fix did not mess up normal Windows paths. Maybe if you get some time you can do a little testing to verify that the solution is good in a OneDrive situation... BTW, the fix is more than just refactoring |
Beta Was this translation helpful? Give feedback.
-
Hi @GCuser99
I just noticed that the function in WebShared.getLocalOneDrivePath doesn't convert a OneDrive path to an existent local one, returning the original https path.
I then saw that the provided source link https://stackoverflow.com/a/72736800/11738627 currently shows a different code. I tested with that, and it works!
Do you remember why we have a different code?
If there are no good reasons to keep the different code, I would update it with that code that works.
Best,
Diego
Beta Was this translation helpful? Give feedback.
All reactions