OneDrive On-demand sync

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
darkzbaron
Posts: 3
Joined: 31 Oct 2015, 16:57

OneDrive On-demand sync

22 Oct 2017, 10:33

hello,

The new OneDrive version allows for on-demand sync. Meaning that some files could be kept in the cloud while appearing on the computer.

There is no documentation whatsover so , the only way I could think of to automate this is through automating the right click action in Windows Explorer.
onedrive.png
onedrive.png (4.36 KiB) Viewed 4013 times
So I tried to intercept the message using spyxx, but the output it's not something that I can understand nor replicate using Post/SendMessage.

Anyone here has expert advice to offer?

Looking forward to you your wisdom, thank you so much!

Below is the log from Spyxx

0000000000AE175C S WM_KILLFOCUS
0000000000AE175C P message:0x04D4 [User-defined:WM_USER+212]
0000000000AE175C P message:0x04D4 [User-defined:WM_USER+212]
0000000000AE175C P WM_CONTEXTMENU
0000000000AE175C P message:0x04D4 [User-defined:WM_USER+212]
0000000000AE175C P message:0x0118 [Unknown]
0000000000AE175C P WM_MOUSEHOVER
0000000000AE175C P message:0x04C8 [User-defined:WM_USER+200]
0000000000AE175C P message:0x04CC [User-defined:WM_USER+204]
0000000000AE175C P message:0x04CF [User-defined:WM_USER+207]
0000000000AE175C P message:0x04C8 [User-defined:WM_USER+200]
0000000000AE175C P message:0x04C8 [User-defined:WM_USER+200]
0000000000AE175C P message:0x04CF [User-defined:WM_USER+207]
0000000000AE175C P message:0x04C8 [User-defined:WM_USER+200]
0000000000AE175C P message:0x04C8 [User-defined:WM_USER+200]
0000000000AE175C P message:0x04C8 [User-defined:WM_USER+200]
0000000000AE175C P message:0x04C8 [User-defined:WM_USER+200]
0000000000AE175C P message:0x04CC [User-defined:WM_USER+204]
0000000000AE175C P message:0x04CF [User-defined:WM_USER+207]
0000000000AE175C P message:0x04C8 [User-defined:WM_USER+200]
0000000000AE175C S WM_KILLFOCUS
0000000000AE175C S WM_IME_NOTIFY
0000000000AE175C P message:0x04C8 [User-defined:WM_USER+200]
0000000000AE175C P message:0x04C8 [User-defined:WM_USER+200]
0000000000AE175C P message:0x04CC [User-defined:WM_USER+204]
0000000000AE175C P message:0x04CF [User-defined:WM_USER+207]
0000000000AE175C P message:0x04C8 [User-defined:WM_USER+200]
0000000000AE175C P message:0x04C8 [User-defined:WM_USER+200]
0000000000AE175C P message:0x04C8 [User-defined:WM_USER+200]
0000000000AE175C P message:0x04CC [User-defined:WM_USER+204]
0000000000AE175C P message:0x04CF [User-defined:WM_USER+207]
0000000000AE175C P message:0x04C8 [User-defined:WM_USER+200]
teadrinker
Posts: 4331
Joined: 29 Mar 2015, 09:41
Contact:

Re: OneDrive On-demand sync

22 Oct 2017, 21:43

Hi, darkzbaron,
the only way I could think of to automate this
I'm not sure, what exactly do you want to automate?
Noesis
Posts: 301
Joined: 26 Apr 2014, 07:57

Re: OneDrive On-demand sync

23 Oct 2017, 01:43

Yeah, I'm not sure what you're after either. I'm actually wondering if your confused about what On-Demand sync actually is (or perhaps I am), my understanding is you don't need to do anything to do it, other than access a file from explorer, and it's explorer that handles it, if/when the file isn't already stored locally, so it's kind of already automated.

Where I can see potential issues is if you're say looking for a file with an AHK script, and that file is not locally stored but is on OneDrive, not sure what would happen here, i.e. does fileexist() show the file as existing ? and if so what happens if you try to read the file. It may be the case that windows does the sync even in this case so it works but is delayed (due to downloading first) but it also may do something else entirely, I dunno, haven't played with it, and personally I don't have a need for it at this point in time, but I suspect it's meant to be handled by the OS kind of like a file on a network drive would be.
teadrinker
Posts: 4331
Joined: 29 Mar 2015, 09:41
Contact:

Re: OneDrive On-demand sync

23 Oct 2017, 09:34

It seems to me, this feature is available for Windows Insiders only. Anyway, I have no such setting in the OneDrive options window on Windows 10 build 15063.
Noesis
Posts: 301
Joined: 26 Apr 2014, 07:57

Re: OneDrive On-demand sync

24 Oct 2017, 00:40

teadrinker, It's a new feature added with the windows fall update, build 16299.19, which was released 17 October.

MS apparently staggers the release of the "feature" updates for downloading via auto-update, but there are ways to get it earlier (google it if you want to force the update). Personally I wouldn't worry too much about forcing it to update, Mine updated on the 18th so I say apparently they stagger it because I've never had these updates delayed (being in Australia the 18th here is kind of the 17th in the States, and Patch Tuesday should be called Patch Wednesday IMO, not to mention it should be the Spring Update ;) ).
teadrinker
Posts: 4331
Joined: 29 Mar 2015, 09:41
Contact:

Re: OneDrive On-demand sync

24 Oct 2017, 01:29

I didn't get this update yet. Trying to update manually.
teadrinker
Posts: 4331
Joined: 29 Mar 2015, 09:41
Contact:

Re: OneDrive On-demand sync

24 Oct 2017, 04:04

Got it, experimented with files stored on cloud.
not sure what would happen here, i.e. does fileexist() show the file as existing ? and if so what happens if you try to read the file.
FileExist shows the file as existing. If I try to read or run the file, first it will be downloaded, afterwards it will be marked as locally stored.
Noesis
Posts: 301
Joined: 26 Apr 2014, 07:57

Re: OneDrive On-demand sync

24 Oct 2017, 05:30

Ok, thanks for the update teadrinker, confirms what I kind of suspected but was a bit too lazy to test :).

So the file is also marked as stored locally (which makes sense). Makes me wonder if it actually keeps the file stored locally indefinitely, or if there is some kind of time frame where it is later removed from the local machine, if not accessed, i.e. a cleanup type phase after a certain period of time (perhaps a day or two or reboot or something ?) Just thinking out loud with regard to this, might be worth keeping an eye on the file to find out if you're also curious, in any event I'm pretty sure there'd be a way you could manually revert it if one wanted.
teadrinker
Posts: 4331
Joined: 29 Mar 2015, 09:41
Contact:

Re: OneDrive On-demand sync

24 Oct 2017, 06:06

Makes me wonder if it actually keeps the file stored locally indefinitely, or if there is some kind of time frame where it is later removed from the local machine, if not accessed
As I understood, such files will be stored locally indefinitely, you could change their status manually only:
When you open an online-only file, it downloads to your device and becomes a locally available file. You can open a locally available file anytime, even without Internet access. If you need more space, you can change the file back to online-only. Just right-click the file and select “Free up space.”
darkzbaron
Posts: 3
Joined: 31 Oct 2015, 16:57

Re: OneDrive On-demand sync

25 Nov 2017, 13:03

HI there, apologies I thought notifications were turned on by default hence my slow reply.

What I would like to achieve is to reverse engineer this "on-demand sync" feature so that I can run: "myautohotkeyscript.ahk" "targetfilename" to either "always keep on device"or "clear space".

Yes I confirm it is an insider feature, it is very handy as I have a small hdd on my laptop.
qwerty12
Posts: 468
Joined: 04 Mar 2016, 04:33
Contact:

Re: OneDrive On-demand sync

28 Nov 2017, 02:03

Hi,
darkzbaron wrote: The new OneDrive version allows for on-demand sync. Meaning that some files could be kept in the cloud while appearing on the computer.

There is no documentation whatsover so , the only way I could think of to automate this is through automating the right click action in Windows Explorer.
Here's a hack that loads the OneDrive context menu shell extension into AutoHotkey, where AHK can then select menu items directly - the extension tells the OneDrive client to perform the action:

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#NoTrayIcon

MODE_GET_STATUS := 0
,MODE_TOGGLE_KEEP_ON_DEVICE := 1
,MODE_FREE_SPACE := 2

mode := MODE_GET_STATUS

if 0 < 1
{
    MsgBox This script requires at least 1 incoming parameter.
    ExitApp 1
}
else if 0 = 2
{
	firstParam = %1%
	if (firstParam = "/keepondevice")
		mode := MODE_TOGGLE_KEEP_ON_DEVICE
	else if (firstParam = "/freespace")
		mode := MODE_FREE_SPACE
	else
		ExitApp 1
}
else if 0 > 2
{
	ExitApp 1
}

RegRead, UserFolder, HKEY_CURRENT_USER\Software\Microsoft\OneDrive, UserFolder
if (ErrorLevel || !InStr(FileExist(UserFolder), "D"))
	ExitApp 1
SetWorkingDir %UserFolder%

if (mode == MODE_GET_STATUS)
	filenameParam = %1%
else
	filenameParam = %2%
if (!FileExist(filenameParam))
	ExitApp 1

VarSetCapacity(dwTypeData, 2050)
,VarSetCapacity(IID_IDataObject, 16)
,DllCall("ole32\CLSIDFromString", "WStr", "{0000010e-0000-0000-C000-000000000046}", "Ptr", &IID_IDataObject)

DoOrDie(DllCall("shell32\SHGetDesktopFolder", "Ptr*", pDesktop))
filenames := [DllCall("shlwapi\PathCombineW", "Ptr", &dwTypeData, "Ptr", &UserFolder, "Ptr", &filenameParam, "WStr")]
VarSetCapacity(pidl_list, filenames.MaxIndex() * A_PtrSize)
filenameCount := 0, ParseDisplayName := NumGet(NumGet(pDesktop+0)+3*A_PtrSize)
for _, filename in filenames
	filenameCount += DllCall(ParseDisplayName, "Ptr", pDesktop, "Ptr", 0, Ptr, 0, "WStr", filename, "Ptr", 0, "Ptr", &pidl_list+(filenameCount * A_PtrSize), "Ptr", 0) >= 0x00
if (!filenameCount)
	ExitApp 1
DoOrDie(DllCall(NumGet(NumGet(pDesktop+0)+10*A_PtrSize), "Ptr", pDesktop, "Ptr", 0, "UInt", filenameCount, "Ptr", &pidl_list, "Ptr", &IID_IDataObject, "Ptr", 0, "Ptr*", pDataObject))

fsctxmenu := ComObjCreate("{CB3D0F55-BC2C-4C1A-85ED-23ED75B5106B}", "{000214E4-0000-0000-C000-000000000046}")
fsshextinit := ComObjQuery(fsctxmenu, "{000214E8-0000-0000-C000-000000000046}")
DoOrDie(DllCall(NumGet(NumGet(fsshextinit+0)+3*A_PtrSize), "Ptr", fsshextinit, "Ptr", 0, "Ptr", pDataObject, "Ptr", 0))

DoOrDie(DllCall(NumGet(NumGet(fsctxmenu+0)+3*A_PtrSize), "Ptr", fsctxmenu, "Ptr", (hMenu := DllCall("CreatePopupMenu", "Ptr")), "UInt", 0, "UInt", 0, "UInt", 0x7FFF, "UInt", 0x00000080))
VarSetCapacity(MENUITEMINFOW, (cbMENUITEMINFOW := A_PtrSize == 8 ? 72 : 44))
Loop % DllCall("GetMenuItemCount", "Ptr", hMenu, "Int") {
	DllCall("ntdll\RtlZeroMemory", "Ptr", &MENUITEMINFOW, "Ptr", cbMENUITEMINFOW)
	,NumPut(cbMENUITEMINFOW, MENUITEMINFOW, 0, "UInt")
	,NumPut(0x00000002 | 0x00000001 | 0x00000040, MENUITEMINFOW, 4, "UInt")
	,NumPut(1024, MENUITEMINFOW, A_PtrSize == 8 ? 64 : 40, "UInt")
	,NumPut(&dwTypeData, MENUITEMINFOW, A_PtrSize == 8 ? 56 : 36, "Ptr")
	if ((DllCall("GetMenuItemInfo", "Ptr", hMenu, "UInt", A_Index - 1, "Int", True, "Ptr", &MENUITEMINFOW, "Int")) && (cch := NumGet(MENUITEMINFOW, A_PtrSize == 8 ? 64 : 40, "UInt"))) {
		fState := NumGet(MENUITEMINFOW, 12, "UInt") 
		,idn := NumGet(MENUITEMINFOW, 16, "UInt")
		,menulabel := StrGet(&dwTypeData, cch, "UTF-16")
		if (menulabel == "Always keep on this device") {
			if (mode == MODE_GET_STATUS)
				msg .= (StrLen(msg) ? "`n" : "") . filenameParam . " is " . (fState & 0x00000008 != 0x00000008 ? "not " : "") . "set to always be kept on this device"
			else if (mode == MODE_TOGGLE_KEEP_ON_DEVICE)
				break
		} else if (menulabel == "Free up space") {
			cannotBeSelected := fState & 0x00000001 || fState & 0x00000002
			if (mode == MODE_GET_STATUS) {
				msg .= (StrLen(msg) ? "`n" : "") . filenameParam . " can" . (cannotBeSelected ? "not " : " ") . "be freed to make space"
			} else if (mode == MODE_FREE_SPACE) {
				if (cannotBeSelected)
					mode := -1
				break
			}
		}
	}
}

if (mode == MODE_GET_STATUS) {
	msgbox %msg%
} else if (mode == MODE_TOGGLE_KEEP_ON_DEVICE || mode == MODE_FREE_SPACE) {
	VarSetCapacity(info, (cbCMINVOKECOMMANDINFO := A_PtrSize == 8 ? 56 : 36), 0)
	,NumPut(cbCMINVOKECOMMANDINFO, info, 0, "UInt")
	,NumPut(0x00000100, info, 4, "UInt")
	,NumPut(A_ScriptHwnd, info, 8, "Ptr")
	,NumPut(idn, info, A_PtrSize == 8 ? 16 : 12, "UPtr")
	,DoOrDie(DllCall(NumGet(NumGet(fsctxmenu+0)+4*A_PtrSize), "Ptr", fsctxmenu, "Ptr", &info)) ; IContextMenu::InvokeCommand
	Sleep -1
}

DllCall("DestroyMenu", "Ptr", hMenu)
,ObjRelease(fsshextinit)
,ObjRelease(fsctxmenu)
,ObjRelease(pDataObject)
Loop %filenameCount% {
	if ((pidl := NumGet(pidl_list, (A_Index - 1) * A_PtrSize, "Ptr")))
		DllCall("ole32\CoTaskMemFree", "Ptr", pidl)
}
ObjRelease(pDesktop)
ExitApp

DoOrDie(hr)
{
	if (hr == "" || hr < 0)
		ExitApp 1
}
To find out if a file is set to always remain stored on your PC and/or whether the space used (if any) by said file can be freed, run the script with just the target's filename as the script's sole argument. Example: Untitled.ahk "Documents\New Text Document.txt"
To toggle a file's always-remain-on-your-PC status, run the script with /keepondevice as the first argument, followed by the target's filename as the second argument. Example: Untitled.ahk /keepondevice "Documents\New Text Document.txt"
To have a file cleared from your PC, run the script with /freespace as the first argument, followed by the target's filename as the second argument. Example: Untitled.ahk /freespace "Documents\New Text Document.txt"

The passed filename must be relative to the base OneDrive folder on disk. In these examples, me using C:\Users\Me\OneDrive\Documents\New Text Document.txt would be incorrect. And there can only be one passed file per each script invocation.

Limitations:
  • I have not tested this with any file over 200 KB... Make sure you have backups of any important files stored outside of OneDrive!
  • This is the bare minimum to do something like this this way. Adding in support to toggle multiple files' always-remain-on-your-PC status / freeing multiple files is probably possible by reworking my bad command-line logic and adding the extra filenames to the filenames array.
    • But not for the getting a file's current status operation! Select multiple files in your OneDrive folder of varying sync statuses, right-click and observe the inconsistencies. This script determines the current status for one file by seeing if the relevant menu is (un)checked / enabled / disabled. Yeah...
darkzbaron
Posts: 3
Joined: 31 Oct 2015, 16:57

Re: OneDrive On-demand sync

28 Nov 2017, 06:20

Wow! Thanks so much, I am amazed thanks for this piece of code! Will load it and let you know if anything!

EDIT 22/12/2017 : Once again many thanks, I am using it with a loop so no need for file array, I will do some further testing and post if there is any issue. For now it works for most files and folders regardless of the size.

Also, would I be able to extend this logic to access any right click menu item? What would then be the logic to access the relevant DLL? What I mean is that your code is intimidating and I am not sure where to start if for example I wanted to modify it for accessing the "print" element in the right click menu. Where should I start looking?
Have a great holiday season!
qwerty12
Posts: 468
Joined: 04 Mar 2016, 04:33
Contact:

Re: OneDrive On-demand sync

25 Dec 2017, 15:24

Hi,
darkzbaron wrote:EDIT 22/12/2017 : Once again many thanks, I am using it with a loop so no need for file array, I will do some further testing and post if there is any issue. For now it works for most files and folders regardless of the size.

Also, would I be able to extend this logic to access any right click menu item? What would then be the logic to access the relevant DLL? What I mean is that your code is intimidating and I am not sure where to start if for example I wanted to modify it for accessing the "print" element in the right click menu. Where should I start looking?
Have a great holiday season!
No problem. Thanks for getting back to me.

This script would require a lot of modification to have it printing files instead - it's specialised to work with the OneDrive shell extension only. There is a more general script out there (search for "ShellContextMenu", but that too requires modification to directly invoke options as opposed to showing the entire right-click menu).

However, as per https://autohotkey.com/docs/commands/Run.htm#Remarks, there might be a simpler alternative that might work for you: Run, print <filename and path here>

Happy holidays to you too!

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: peter_ahk, Spawnova, toddhere, USS_Sandhu and 318 guests