Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Resolving shortcut files
#1
Hi,

I'm doing some moderately complicated file manipulations, and have run across a problem. I strongly suspect this is a Windows issue, but perhaps there’s a QuickMacros trick to get around Windows’ problems.

Many of the files I’m working with aren't really files, but rather Windows shortcuts (.lnk files). When the macro encounters a .lnk file, it resolves it using GetShortcutInfoEx.

The problem? Sometimes, GetShortcutInfoEx fails. This seems to happen when the target of the shortcut file has been moved. That’s not especially surprising. More interesting, though, is that Windows Explorer doesn’t have this same problem — If I double click the file in Explorer, it will correctly find the file it refers to, even if I moved it. (Perhaps it does a quick search, or maybe Microsoft has wised up and started to use file ID numbers instead of paths.)

Since it could be relevant, this is with Windows XP Home SP2 on an NTFS volume, and (just to confuse things) the .lnk files as well as the referred-to files are all located within a particular shared folder and its subfolders.

So here’s the question — Is it possible to coax GetShortcutInfoEx into acting like Windows Explorer, and get it to be more successful at resolving shortcuts? One (probably false) trail might be the "param" field of the SHORTCUTINFO structure — I don’t know what parameters can be passed using that field. (The help file uses "-p" as an example, but I don’t know what the -p tells the function to do.)

Thanks!

P.S. Edited to remove reference to "GetShortcutInfo," which doesn't exist.
9: ) Lindsey Dubb
#2
Function UpdateShortcut
Code:
Copy      Help
;/
function# $lnkfile [noUI] [timeout]

;Updates shortcut's target if it is moved or renamed.
;It is not error to call this function for healthy shortcuts too.
;Returns 1 if successful.


;lnkfile - shortcut file.
;noUI - do not display a dialog.
;timeout - if noUI is nonzero, the max number of milliseconds to search. Default or 0 - 3000.


;EXAMPLE
;str lnk="$desktop$\test.lnk"
;if(!UpdateShortcut(lnk)) out "invalid shortcut: %s" lnk



interface# IShellLinkA :IUnknown
,GetPath($pszFile cch WIN32_FIND_DATAA*pfd fFlags)
,GetIDList(ITEMIDLIST**ppidl)
,SetIDList(ITEMIDLIST*pidl)
,GetDescription($pszName cch)
,SetDescription($pszName)
,GetWorkingDirectory($pszDir cch)
,SetWorkingDirectory($pszDir)
,GetArguments($pszArgs cch)
,SetArguments($pszArgs)
,GetHotkey(@*pwHotkey)
,SetHotkey(@wHotkey)
,GetShowCmd(*piShowCmd)
,SetShowCmd(iShowCmd)
,GetIconLocation($pszIconPath cch *piIcon)
,SetIconLocation($pszIconPath iIcon)
,SetRelativePath($pszPathRel dwReserved)
,Resolve(hwnd fFlags)
,SetPath($pszFile)
,{000214EE-0000-0000-C000-000000000046}
interface# IPersist :IUnknown
,GetClassID(GUID*pClassID)
,{0000010c-0000-0000-C000-000000000046}
interface# IPersistFile :IPersist
,IsDirty()
,Load(@*pszFileName dwMode)
,Save(@*pszFileName fRemember)
,SaveCompleted(@*pszFileName)
,GetCurFile(@**ppszFileName)
,{0000010b-0000-0000-C000-000000000046}
def CLSID_ShellLink uuidof("{00021401-0000-0000-C000-000000000046}")
def SLR_UPDATE 0x4
def SLR_NO_UI 0x1

IShellLinkA sl._create(CLSID_ShellLink)
IPersistFile pf=+sl
str s.expandpath(lnkfile)
pf.Load(+s.unicode 0); err ret
int flags=SLR_UPDATE; if(noUI) flags|SLR_NO_UI; flags|timeout<<16
sl.Resolve(0 flags); err ret
ret !_hresult

You can call it before GetShortcutInfoEx (easier), or when GetShortcutInfoEx returns invalid path (maybe a bit faster).
#3
Gintaras,

Thank you for coming up with the function! That's going to save me quite a lot of time, and avoid some really dumb kludges I was working towards.

For anyone else working with lots of shortcut files — Yes, UpdateShortcut is working for me quite well.
9: ) Lindsey Dubb


Forum Jump:


Users browsing this thread: 1 Guest(s)