Page 1 of 1

FileGetShortcut error when drive removed - even w/ Try-Catch

Posted: 04 Sep 2014, 22:17
by JnLlnd
To reproduce this issue, please follow these steps (tested here with Win 7):

1) Open an external drive (USB drive or key, for example). Create or copy an MS Office file on this drive and open it (just to make sure this file is registered in the Recent items).

2) Open Recent items (C:\Users\[User Name]\AppData\Roaming\Microsoft\Windows\Recent Items) to confirm that the file and the folder containing this file on the removable drive are the most recent items in the list.

3) Run the script below. The 4 most recent items shortcuts will be resolved. Everything will run fine since the external drive is still available.

4) Eject the external drive, using the External device tray icon.

5) Run again the script below. Now (this is the tricky part), the script below will follow one of these scenarios:

5.1) The FileGetShortcut will resolve the shortcut event if the drive is unavailable (no errorlevel, no error thrown for the Try/Catch commands). This is what happens on my PC #1. I like it :-)

5.2) The FileGetShortcut will throw an error and the Try/Catch commands will NOT catch the error. Instead, Windows will display an error message like this "There is no disk in the drive. Please insert a disk into drive \Device\Harddisk\XYZ.". This is what happens on my PC #2. I don't like it :-(

PCs #1 and #2 are both Win 7 64-bit, running the same AHK executable (1.1.14.03, compiled version or not). Tested with the same removable drive on each PC.

My questions:

A) Can you reproduce the scenario 5.2?

b) For those having so much "Inside Windows" knowledge than me, in what direction would you search for the difference between PCs #1 and #2 that would explain these two behaviors?

Thanks for your input,

Jean

Code: Select all

; Find the recent items folders in Windows XP or 7/8/8.1
if (A_OSVersion = "WIN_XP")
{
	strRecentsFolder := SubStr(A_AppData, 1, InStr(A_AppData, "\", , 0) - 1) . "\Recent"
	if !FileExist(strRecentsFolder)
		strRecentsFolder := SubStr(A_AppData, 1, InStr(A_AppData, "\", , 0) - 1) . "\My Recent Documents"
}
else
	strRecentsFolder := A_AppData . "\Microsoft\Windows\Recent"

strDirList := ""

; Sort recent items chronologically
Loop, %strRecentsFolder%\*.*
	strDirList := strDirList . A_LoopFileTimeModified . "`t`" . A_LoopFileFullPath . "`n"
Sort, strDirList, R

Loop, parse, strDirList, `n
{
	if !StrLen(A_LoopField) ; last line is empty
		continue

	arrTargetFullName := StrSplit(A_LoopField, A_Tab)
	strTargetFullName := arrTargetFullName[2]
	
	MsgBox, % "Will resolve shortcut #" . A_Index . ":`n" . strTargetFullName
	try FileGetShortcut, %strTargetFullName%, strOutTarget
	catch
	{
		MsgBox, % "Error CATCHED in FileGetShortcut."
		continue
	}
	
	if (errorlevel) ; hidden or system files (like desktop.ini) returns an error
	{
		MsgBox, % "Errorlevel: " . errorlevel
		continue
	}
	
	MsgBox, % "Resolved file name is for #" . A_Index . " is:`n" . strOutTarget
	
	; here, in my full script, I check if the resolved file exists and do what I have to do if it exists
	
	if (A_Index > 3)
		break
}

return

Re: FileGetShortcut error when drive removed - even w/ Try-C

Posted: 05 Sep 2014, 05:30
by joedf
You could maybe get the path by directly/manually parsing the *.lnk file... ?

Re: FileGetShortcut error when drive removed - even w/ Try-C

Posted: 05 Sep 2014, 05:50
by JnLlnd
joedf wrote:You could maybe get the path by directly/manually parsing the *.lnk file... ?
If I get you right, in this case, the path of the .lnk file is always "C:\Users\[User Name]\AppData\Roaming\Microsoft\Windows\Recent Items".

Re: FileGetShortcut error when drive removed - even w/ Try-C

Posted: 05 Sep 2014, 09:53
by joedf
What im saying is that, maybe filegetshortcut just doesnt like invalid shortcuts. Try to "raw" read these shortcuts and parse this "raw" data found in the *.lnk files manually..

Re: FileGetShortcut error when drive removed - even w/ Try-C

Posted: 05 Sep 2014, 10:56
by JnLlnd
Oh, I see. I got you wrong.

Using a text editor (that can red binary files), I tried to open the Recent items folder to look at file's content but Windows is preventing me from doing this. I tried on 2 PCs where I have admin access. I hav not try via an AHK script yet.

On your side can you open these .lnk files?

Re: FileGetShortcut error when drive removed - even w/ Try-C

Posted: 05 Sep 2014, 15:55
by JnLlnd
This being said, I appreciate your help to find a workaround, JoeDF. But, my app being quite largely distributes, I would prefer to stay with recommended commands and understand why the same script on 2 similar machines behave differently...
JnLlnd wrote:My questions:

A) Can you reproduce the scenario 5.2?

b) For those having so much "Inside Windows" knowledge than me, in what direction would you search for the difference between PCs #1 and #2 that would explain these two behaviors?
Thanks.

Re: FileGetShortcut error when drive removed - even w/ Try-C

Posted: 05 Sep 2014, 18:20
by Nextron
Are you sure FileGetShortcut is throwing the error? Not the directory parsing loop trying to set some built-in variable based on the non-existent target of the shortcut, rather than the shortcut itself?

Re: FileGetShortcut error when drive removed - even w/ Try-C

Posted: 05 Sep 2014, 18:36
by JnLlnd
Thanks for joining the discussion Nextron.
Nextron wrote:Are you sure FileGetShortcut is throwing the error? Not the directory parsing loop trying to set some built-in variable based on the non-existent target of the shortcut, rather than the shortcut itself?
The error occurs just after the MsgBox command, during the execution of FileGetShortcut.

Code: Select all

    MsgBox, % "Will resolve shortcut #" . A_Index . ":`n" . strTargetFullName
    try FileGetShortcut, %strTargetFullName%, strOutTarget
The error window is created by Windows. Not by the script or by the AHK executable. I'm pretty sure of this.

Re: FileGetShortcut error when drive removed - even w/ Try-C

Posted: 05 Sep 2014, 19:11
by joedf
Hmm, I am currently unable to test any of this. I will when I come back from my travels.

Re: FileGetShortcut error when drive removed - even w/ Try-C

Posted: 05 Sep 2014, 19:24
by JnLlnd
joedf wrote:Hmm, I am currently unable to test any of this. I will when I come back from my travels.
I understand it is not simple to reproduce this scenario. Thanks for taking the time when you'll have it.

Re: FileGetShortcut error when drive removed - even w/ Try-C

Posted: 05 Sep 2014, 20:09
by lexikos
Instead, Windows will display an error message like this "There is no disk in the drive. Please insert a disk into drive \Device\Harddisk\XYZ.".
Exactly. Windows displays an error message. Not AutoHotkey.

You might be able to prevent it with SetErrorMode:

Code: Select all

DllCall("SetErrorMode", "uint", SEM_FAILCRITICALERRORS := 1)

Re: FileGetShortcut error when drive removed - even w/ Try-C

Posted: 05 Sep 2014, 20:41
by JnLlnd
It is so great to have you around Lexikos. I'll have to wait until Monday to test this command on my PC #2. But it seems to be exactly what I needed. Thanks!

Re: FileGetShortcut error when drive removed - even w/ Try-C

Posted: 06 Sep 2014, 11:45
by SKAN
I am not able to reproduce the problem. WMI provides an alternate way to retrieve target file from shortcut with Win32_ShortcutFile, but recent folder is invisible to WMI in XP.

You may use the following to retrieve Recent folder's path in AHK 1.0 and 1.1 :

Code: Select all

; Find the recent items folders in Windows XP or 7/8/8.1
RegRead, strRecentsFolder, HKCU, Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders, Recent

Re: FileGetShortcut error when drive removed - even w/ Try-C

Posted: 06 Sep 2014, 13:47
by JnLlnd
SKAN wrote:You may use the following to retrieve Recent folder's path in AHK 1.0 and 1.1 :
Thanks for the RegRead hint, Skan! Always glad to replace 9 lines of code with one and produce more reliable code!
SKAN wrote:WMI provides an alternate way to retrieve target file from shortcut with Win32_ShortcutFile, but recent folder is invisible to WMI in XP.
Hum.. Interesting. I search for WMI examples using AHK and found this thread. But no example for Win32_ShortcutFile. If you have any code snippet, it would be appreciated. But I'll look into it anyway.

Re: FileGetShortcut error when drive removed - even w/ Try-C

Posted: 06 Sep 2014, 14:02
by SKAN
JnLlnd wrote:If you have any code snippet..
Ofcourse!... I had to test before I posted. :)

Code: Select all

RegRead, Recent, HKCU, Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders, Recent
pathRecent := RegExReplace( SubStr( Recent, 3 ) "\", "\\", "\\" )
MsgBox % Recent "`n" pathRecent

List := ""
for ObjItem in ComObjGet("winmgmts:")
              .ExecQuery( "Select * from Win32_ShortcutFile where path = '" pathRecent "'" )
    List .= ObjItem.LastModified A_Tab ObjItem.Target "`n"
Sort, List, R     

MsgBox % List
Without 'where' condition, Windows XP list all links in my entire HDD, except for its own Recent folder which is also invisible to other win versions installed in the same HDD.

Re: FileGetShortcut error when drive removed - even w/ Try-C

Posted: 06 Sep 2014, 14:28
by JnLlnd
SKAN wrote:Ofcourse!... I had to test before I posted. :)
It works great, thanks. Just bad that Win XP does not see it. I'll have two options: keep FileGetShortcut if the DllCall avoid the error message on my PC #2, or use the WMI approach keeping FileGetShortcut for XP only. This would at least circumscribe the damages to XP ;-)

Re: FileGetShortcut error when drive removed - even w/ Try-C

Posted: 08 Sep 2014, 11:39
by JnLlnd
Grrr... I was not able to reproduce the issue on PC #2 (same PC, same external drive, same script...). I have no idea of what changed since Friday... I hate these intermittent bugs...

I can assure that I'm not the only one having this issue. It has been reported a few times on my blog by users of my apps (here and here)...

For now, I'll include the DllCall in the next release of the app and ask users to test it.

I'll keep you posted. Thanks all.