This is a technical post highlighting some implementation part in the NWS PowerTool.
This explains how to get the URL to a file in a SharePoint Online or OneDrive from its local synced location.
Main functionality is implemented in ahk/Lib/SharePoint.ahk->SharePoint_Sync2Url function.
Get OneDrive Sync root folders
You can check for the Sync location using the environment variable named onedrive.
This will return your personal onedrive location. (I recommend to move the default location from C: to D:)
For the SharePoint Sync location, it is on the same level but without "OneDrive -" in its name (at least in our company setup)
; Get File Link for Personal OneDrive
EnvGet, sOneDriveDir , onedrive
; Get File Link for SharePoint/OneDrive Synced location
sOneDriveDir := StrReplace(sOneDriveDir,"OneDrive - ","")
Personal OneDrive
This is quite an easy one. You can get the cloud onedrive location from the registry key HKEY_CURRENT_USER\Software\SyncEngines\Providers\OneDrive -> Property UrlNameSpace:
RegRead, rooturl, HKEY_CURRENT_USER\Software\SyncEngines\Providers\OneDrive, UrlNamespace
SharePoint Online
The implementation is based on this trick I've learned in StackOverflow: get-onedrive-file-url-from-a-the-locally-cached-file:
Under the registry key HKEY_CURRENT_USER\Software\SyncEngines\Providers\OneDrive you have for each folder Sync location a SubKey with 2 properties: MountPoint and UrlNameSpace.
Under the registry key HKEY_CURRENT_USER\Software\SyncEngines\Providers\OneDrive you have for each folder Sync location a SubKey with 2 properties: MountPoint and UrlNameSpace.
Unfortunately, these properties are not a point-to-point mapping i.e. if you have synced a folder not on the top level, the MountPoint does not fit to the UrlNameSpace because the UrlNameSpace always points to the root of the Document Library.
This is why I need to store the proper mapping somewhere else: I have chosen to store it in a SPsync.ini file located in the root Sync folder.
You can get the last folder name from the name of the MountPoint/ Sync location since normally it is of the form SharePoint Name - FolderName or in case of a Team Private Channel Team Name - Private Channel Name - Folder Name.
In the example above: I have synced https://tenantName.sharepoint.com/teams/team_10000778/Shared%20Documents/General/Knowledge%20Broker%20Toolkit which is 2 levels below the root level.
The MountPoint/ Sync location is: D:\user\Tenant Name\Knowledge Brokers - Knowledge Broker Toolkit
but the UrlNameSpace is https://tenantName.sharepoint.com/teams/team_10000778/Shared Documents
The guessed mapping is: https://tenantName.sharepoint.com/teams/team_10000778/Shared Documents/Knowledge Broker Toolkit but you see it missed the intermediary folders in this case there shall be the General folder in between https://tenantName.sharepoint.com/teams/team_10000778/Shared%20Documents/General/Knowledge%20Broker%20Toolkit
The guessed mapping will also not work if you have - in your folder names.
You can see the implementation guess in the ahk/Lib/SharePoint.ahk->SharePoint_UpdateSyncIniFile function.
Extract below:
SharePoint_UpdateSyncIniFile(sIniFile:=""){
; showWarn := SharePoint_UpdateSyncIniFile(sIniFile:="")
If (sIniFile="")
sIniFile := SharePoint_GetSyncIniFile()
If Not FileExist(sIniFile)
{
TrayTip, NWS PowerTool, File %sIniFile% does not exist! File was created in "%sOneDriveDir%". Fill it following user documentation.
FileAppend, REM See documentation https://tdalon.github.io/ahk/Sync`n, %sIniFile%
FileAppend, REM Use a TAB to separate local root folder from SharePoint sync root url`n, %sIniFile%
FileAppend, REM It might be the default mapping is wrong if you've synced from a subfolder not in the first level. Url shall not end with /`n, %sIniFile%
}
FileRead, IniContent, %sIniFile%
showWarn := False
Loop, Reg, HKEY_CURRENT_USER\Software\SyncEngines\Providers\OneDrive, K
{
RegRead MountPoint, HKEY_CURRENT_USER\Software\SyncEngines\Providers\OneDrive\%A_LoopRegName%, MountPoint
MountPoint := StrReplace(MountPoint,"\\","\")
; Exclude Personal OneDrive
If InStr(MountPoint,"\OneDrive -")
Continue
If Not InStr(IniContent,MountPoint . A_Tab) {
RegExMatch(MountPoint,"[^\\]*$",sFolderName)
RegRead UrlNamespace, HKEY_CURRENT_USER\Software\SyncEngines\Providers\OneDrive\%A_LoopRegName%, UrlNamespace
sFolderName := RegExReplace(sFolderName,"^EXT - ","") ; Special case for EXT -
If FolderName := RegExMatch(sFolderName,"^[^-]* - ([^-]*) - ([^-]*)$",sMatch) { ; Private Channel
If (sMatch1 = sMatch2) { ; root folder has same name
UrlNamespace := SubStr(UrlNamespace,1,-1) ; remove trailing /
} Else {
UrlNamespace := UrlNamespace . sMatch2
showWarn := True
}
} Else {
FolderName := RegExReplace(sFolderName,".*- ","")
If Not (FolderName = "Documents") { ; not root level
UrlNamespace := UrlNamespace . FolderName
; For Teams SharePoint check for General channel folder to ignore displaying warning
If RegExMatch(UrlNamespace,"sharepoint\.com/teams/team_")
If Not (FolderName = "General")
showWarn := True
Else
showWarn := True
} Else ; root level -> remove trailing /
UrlNamespace := SubStr(UrlNamespace,1,-1)
}
FileAppend, %MountPoint%%A_Tab%%UrlNamespace%`n, %sIniFile%
}
} ; end Loop
If (showWarn) {
sTrayTip = If you are not syncing on the root level, you need to check the default mapping!
TrayTip Check Mapping in SPsync.ini! , %sTrayTip%,,0x2
Run "%sIniFile%"
}
return showWarn
} ; eofun
I've tried to avoid displaying a warning if most likely the guess is right i.e. for a General folder in a Teams SharePoint or for a Private Channel root level.
In case I display a warning, the Ini File will be opened for edit.
When reading the Ini File, if the directory could not be found in it, the SPSync.ini file will be automatically updated.
No comments:
Post a Comment