list Recent Items (My Recent Documents) (Start Menu)

Post your working scripts, libraries and tools
User avatar
jeeswg
Posts: 5428
Joined: 19 Dec 2016, 01:58
Location: UK

list Recent Items (My Recent Documents) (Start Menu)

04 May 2017, 03:56

List recent files from the Start Menu, tested on Windows 7.
Recent Items (Windows 7).
My Recent Documents (Windows XP).

Do notify of any issues.

[EDIT:] I fixed the VarSetCapacity issue, improved the script slightly, and made the script into a function.

Code: Select all

;e.g.
;q:: ;list recent files
vOutput := JEE_SysGetRecentItems("`r`n", 30, "F", vCount)
;vOutput := JEE_SysGetRecentItems("`r`n", 30, "FD", vCount)
;vOutput := JEE_SysGetRecentItems("`r`n", 30, "D", vCount)
Clipboard := vCount "`r`n" vOutput "`r`n"
MsgBox, % Clipboard
return

;vMode: 0(or F)/1(or FD/DF)/2(or D)=files/both/folders
JEE_SysGetRecentItems(vSep="`n", vMax=30, vMode=0, ByRef vCount="", vMustExist=1)
{
	local vAttrib,vData,vDirRecent,vIsDir,vIsV1,vName,vNum,vOffset,vOutput,vPath,vTarget,vTemp
	;CSIDL_RECENT := 8
	VarSetCapacity(vDirRecent, 260*2, 0)
	DllCall("shell32\SHGetFolderPath", Ptr,0, Int,8, Ptr,0, UInt,0, Str,vDirRecent)
	vIsV1 := !!SubStr(1,0)
	(vMode = "F") ? (vMode := 0) : ""
	(vMode = "D") ? (vMode := 2) : ""
	(vMode = "FD")||(vMode = "DF") ? (vMode := 1) : ""
	vCount := 0
	vOutput := ""
	VarSetCapacity(vOutput, 260*2*vMax)
	Loop, % vMax
	{
		RegRead, vData, HKEY_CURRENT_USER, Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs, % A_Index-1
		vTemp := ""
		Loop, % Round(StrLen(vData) / 4)
		{
			vOffset := (A_Index*4)-3
			vNum := Format("{:i}", "0x" SubStr(vData, vOffset+2, 2) SubStr(vData, vOffset, 2))
			vTemp .= (vNum = 0) ? "|" : Chr(vNum)
		}
		vName := ""
		Loop, Parse, vTemp, |
			if (SubStr(A_LoopField, vIsV1-4) = ".lnk")
				vName := A_LoopField
		vPath := vDirRecent "\" vName
		if !(vName = "") && FileExist(vPath)
		{
			FileGetShortcut, % vPath, vTarget
			vAttrib := FileExist(vTarget)
			if vMustExist && (vAttrib = "")
				continue
			vIsDir := InStr(vAttrib, "D")
			if (vMode = 0 && !vIsDir) || (vMode = 1) || (vMode = 2 && vIsDir)
				vOutput .= vTarget vSep, vCount += 1
		}
	}
	return SubStr(vOutput, 1, -StrLen(vSep))
}
Last edited by jeeswg on 04 May 2017, 22:11, edited 4 times in total.
sGuest

Re: list Recent Items (My Recent Documents) (Start Menu)

04 May 2017, 13:25

Hi Jeeswg,

Here's an issue on first hotkey press after which script closes because of instability:

:terms: Error: This DllCall requires a prior VarSetCapacity.
@W7 x64 - AHK 1.1.25.01

Cheers, and thanks for sharing again.
User avatar
TheDewd
Posts: 1135
Joined: 19 Dec 2013, 11:16
Location: USA

Re: list Recent Items (My Recent Documents) (Start Menu)

04 May 2017, 13:56

Code: Select all

An internal error has occurred in the debugger engine. Continue running the script without the debugger?
Yes/No
Image Bulldozer - Sokoban inspired game from 1994 recreated in AutoHotkey.
User avatar
jeeswg
Posts: 5428
Joined: 19 Dec 2016, 01:58
Location: UK

Re: list Recent Items (My Recent Documents) (Start Menu)

04 May 2017, 19:11

OK, I added in one line, VarSetCapacity(vDirRecent, 260*2, 0), it should work now.

Apologies for that, I've asked a question about it here:

basic DllCall + VarSetCapacity question - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=31419
AHKStudent
Posts: 313
Joined: 05 May 2018, 12:23

Re: list Recent Items (My Recent Documents) (Start Menu)

06 Aug 2018, 05:59

works on windows 10 as well

Is there a way to sort it by date / most recent?

In windows 10 there is a recent folder, access it quick via run > shell:Recent

Is there a negative to getting recent files from there other than it probably taking longer than your method and it not working on windows 7 possibly?
User avatar
jeeswg
Posts: 5428
Joined: 19 Dec 2016, 01:58
Location: UK

Re: list Recent Items (My Recent Documents) (Start Menu)

06 Aug 2018, 15:50

- Here are 2 different ways to get the files in recent order. One via the registry, one via a file loop. (Tested on Windows 7.)
- The one disadvantage of the file loop is that sometimes some random old links persist in the folder.

Code: Select all

q:: ;get recent files in order (via the registry)
;CSIDL_RECENT := 8
VarSetCapacity(vDirRecent, 260*2, 0)
DllCall("shell32\SHGetFolderPath", Ptr,0, Int,8, Ptr,0, UInt,0, Str,vDirRecent)

RegRead, vDataList, HKEY_CURRENT_USER, Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs, MRUListEx
vOutput := ""
Loop, % (StrLen(vDataList)/8) - 1
{
	vIndex := Format("{:i}", "0x" SubStr(vDataList, A_Index*8-7, 2))
	RegRead, vData, HKEY_CURRENT_USER, Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs, % vIndex

	vTemp := ""
	Loop, % Round(StrLen(vData) / 4)
	{
		vOffset := (A_Index*4)-3
		vNum := Format("{:i}", "0x" SubStr(vData, vOffset+2, 2) SubStr(vData, vOffset, 2))
		vTemp .= (vNum = 0) ? "|" : Chr(vNum)
	}

	RegExMatch(vTemp, "O)([^|]+\.lnk)(?=\|)", oMatch)
	vPath := vDirRecent "\" oMatch.0
	FileGetShortcut, % vPath, vTarget
	if InStr(FileExist(vTarget), "D")
		continue
	vOutput .= vTarget "`r`n"
}
Clipboard := vOutput
MsgBox, % vOutput
return

;==================================================

w:: ;get recent files registry indexes in order
RegRead, vDataList, HKEY_CURRENT_USER, Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs, MRUListEx
vOutput := ""
Loop, % (StrLen(vDataList)/8) - 1
	vOutput .= (A_Index=1?"":",") Format("{:i}", "0x" SubStr(vDataList, A_Index*8-7, 2))
MsgBox, % vOutput
return

;==================================================

e:: ;get recent files in order (via a file loop)
;CSIDL_RECENT := 8
VarSetCapacity(vDirRecent, 260*2, 0)
DllCall("shell32\SHGetFolderPath", Ptr,0, Int,8, Ptr,0, UInt,0, Str,vDirRecent)
vOutput := ""
Loop, Files, % vDirRecent "\*", F
{
	vPath := A_LoopFileFullPath
	FileGetShortcut, % vPath, vTarget
	if InStr(FileExist(vTarget), "D")
		continue
	vOutput .= A_LoopFileTimeModified "`t" vTarget "`n"
}
Sort, vOutput, R
vOutput := RegExReplace(vOutput, "(?<=^|`n)\d{14}`t")
Clipboard := StrReplace(vOutput, "`n", "`r`n")
MsgBox, % vOutput
return

;==================================================
- Re. speed, here are the results of some benchmark tests. So, effectively speed is the same, the registry approach fractionally faster.

Code: Select all

100 iterations

registry loop:
2054.150320
2041.298359
2048.170158

file loop:
2086.826109
2065.356710
2079.769569
User avatar
jeeswg
Posts: 5428
Joined: 19 Dec 2016, 01:58
Location: UK

Re: list Recent Items (My Recent Documents) (Start Menu)

30 Aug 2018, 13:50

This is the latest version of the script I'm using:

Code: Select all

q:: ;get recent files in order (via a file loop)
;CSIDL_RECENT := 8
VarSetCapacity(vDirRecent, 260*2, 0)
DllCall("shell32\SHGetFolderPath", Ptr,0, Int,8, Ptr,0, UInt,0, Str,vDirRecent)
vOutput := ""
VarSetCapacity(vOutput, 100000*2)
Loop, Files, % vDirRecent "\*.lnk", F
{
	vPath := A_LoopFileFullPath
	FileGetShortcut, % vPath, vTarget
	vAttrib := FileExist(vTarget)
	if InStr(vAttrib, "D") || !vAttrib
		continue
	vOutput .= A_LoopFileTimeModified "`t" vTarget "`n"
}
Sort, vOutput, R
vOutput := RegExReplace(vOutput, "(?<=^|`n)\d{14}`t")
Clipboard := StrReplace(vOutput, "`n", "`r`n")
MsgBox, % vOutput
return
carno
Posts: 133
Joined: 20 Jun 2014, 16:48

Re: list Recent Items (My Recent Documents) (Start Menu)

13 Oct 2018, 03:38

Could RegRead cause any damage to Registry?
User avatar
jeeswg
Posts: 5428
Joined: 19 Dec 2016, 01:58
Location: UK

Re: list Recent Items (My Recent Documents) (Start Menu)

13 Oct 2018, 05:02

AFAIK no. See the RegRead function in the source code (script_registry.cpp) to see what it does. I would suggest starting a new question in Ask For Help if you want to know more.
marcovilliams
Posts: 1
Joined: 05 Dec 2018, 00:41

Re: list Recent Items (My Recent Documents) (Start Menu)

05 Dec 2018, 01:18

Hello,
jeeswg wrote: List recent files from the Start Menu, tested on Windows 7.
Recent Items (Windows 7).
My Recent Documents (Windows XP).

Do notify of any issues.

[EDIT:] I fixed the VarSetCapacity issue, improved the script slightly, and made the script into a function.

Code: Select all

;e.g.
;q:: ;list recent files
vOutput := JEE_SysGetRecentItems("`r`n", 30, "F", vCount)
;vOutput := JEE_SysGetRecentItems("`r`n", 30, "FD", vCount)
;vOutput := JEE_SysGetRecentItems("`r`n", 30, "D", vCount)
Clipboard := vCount "`r`n" vOutput "`r`n"
MsgBox, % Clipboard
return

;vMode: 0(or F)/1(or FD/DF)/2(or D)=files/both/folders
JEE_SysGetRecentItems(vSep="`n", vMax=30, vMode=0, ByRef vCount="", vMustExist=1)
{
 local vAttrib,vData,vDirRecent,vIsDir,vIsV1,vName,vNum,vOffset,vOutput,vPath,vTarget,vTemp
 ;CSIDL_RECENT := 8
 VarSetCapacity(vDirRecent, 260*2, 0)
 DllCall("shell32\SHGetFolderPath", Ptr,0, Int,8, Ptr,0, UInt,0, Str,vDirRecent)
 vIsV1 := !!SubStr(1,0)
 (vMode = "F") ? (vMode := 0) : ""
 (vMode = "D") ? (vMode := 2) : ""
 (vMode = "FD")||(vMode = "DF") ? (vMode := 1) : ""
 vCount := 0
 vOutput := ""
 VarSetCapacity(vOutput, 260*2*vMax)
 Loop, % vMax
 {
 RegRead, vData, HKEY_CURRENT_USER, Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs, % A_Index-1
 vTemp := ""
 Loop, % Round(StrLen(vData) / 4)
 {
 vOffset := (A_Index*4)-3
 vNum := Format("{:i}", "0x" SubStr(vData, vOffset+2, 2) SubStr(vData, vOffset, 2))
 vTemp .= (vNum = 0) ? "|" : Chr(vNum)
 }
 vName := ""
 Loop, Parse, vTemp, |
 if (SubStr(A_LoopField, vIsV1-4) = ".lnk")
 vName := A_LoopField
 vPath := vDirRecent "\" vName
 if !(vName = "") && FileExist(vPath)
 {
 FileGetShortcut, % vPath, vTarget
 vAttrib := FileExist(vTarget)
 if vMustExist && (vAttrib = "")
 continue
 vIsDir := InStr(vAttrib, "D")
 if (vMode = 0 && !vIsDir) || (vMode = 1) || (vMode = 2 && vIsDir)
 vOutput .= vTarget vSep, vCount += 1
 }
 }
 return SubStr(vOutput, 1, -StrLen(vSep))
}
Thanks for share details actually reason is that I using windows 7 & this code is very useful.
Thanks again!

Return to “Scripts and Functions”

Who is online

Users browsing this forum: just me and 42 guests