Get link targets (shortcuts) / CallCOM
- 
				BackupUser
- PureBasic Guru 
- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by Max..
There is a nice snippet of Danilo
viewtopic.php?t=4945">http://forums.pur ... php?t=4945
to create links.
Did anyone figure out how to retrieve the path/target of existing links?
There is a GetPath Method which should do that
and I also found an example in C, but sadly I'm not smart enough to get it converted to PB.
http://www.codeguru.com/shell/gettingshortcuts.shtml
Max.
AMD Athlon, Matrox G550, Win 2K SP3, IE 6.0, PB 3.62
			
			
									
									
						There is a nice snippet of Danilo
viewtopic.php?t=4945">http://forums.pur ... php?t=4945
to create links.
Did anyone figure out how to retrieve the path/target of existing links?
There is a GetPath Method which should do that
and I also found an example in C, but sadly I'm not smart enough to get it converted to PB.
http://www.codeguru.com/shell/gettingshortcuts.shtml
Max.
AMD Athlon, Matrox G550, Win 2K SP3, IE 6.0, PB 3.62
- 
				BackupUser
- PureBasic Guru 
- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by El_Choni.
This works here:
El_Choni
			
			
									
									
						This works here:
Code: Select all
; ANSI version (works in Windows 95 and 98 too)
#CLSCTX_INPROC_SERVER = 1
#SLGP_UNCPRIORITY = 2
#QueryInterface = 0
#Release = 8
#GetArguments = 12
#GetPath = 32
#Load = 20
Procedure.s GetShortcutTarget(LinkFileName.s)
  Temp.s = LCase(LinkFileName)
  If FindString(Temp, ".lnk", 0)
    Link.s = LinkFileName
  Else
    Link.s = LinkFileName+".lnk"
  EndIf
  Info.s
  Shared psl ; IShellLink*
  hres = CoCreateInstance_(?CLSID_ShellLink, #NULL, #CLSCTX_INPROC_SERVER, ?IID_IShellLink, @psl)
  If hres=#S_OK
    Shared ppf ; IPersistFile*
    hres = CallCOM(#QueryInterface, psl, ?IID_IPersistFile, @ppf)
    If hres=#S_OK
      Dim wsz.w(#MAX_PATH)
      MultiByteToWideChar_(#CP_ACP, #MB_PRECOMPOSED, Link, -1, wsz(), #MAX_PATH)
      hres = CallCOM(#Load, ppf, wsz(), 0)
      If hres=#S_OK
        TempBuffer = AllocateMemory(0, 1024)
        CallCOM(#GetPath, psl, TempBuffer, 1024, #NULL, #SLGP_UNCPRIORITY)
        TempBuffer = MemoryID() ; TempBuffer variable trashed for some reason (weird!)
        Info.s = PeekS(TempBuffer)
        CallCOM(#GetArguments, psl, TempBuffer, 1024)
        Info+" "+PeekS(TempBuffer)
        FreeMemory(0)
      EndIf
    EndIf
    CallCOM(#Release, psl)
  EndIf
  ProcedureReturn Info
EndProcedure
CoInitialize_(0)
File$ = OpenFileRequester("Select link", "", "Link files (*.lnk)|*.lnk|All files (*.*)|*.*", 0)
If File$
  MessageRequester("Links to", GetShortcutTarget(File$), 0)
EndIf
CoUnInitialize_()
End
!section '.data' Data readable writeable
IID_IShellLink:
!dd $000214EE
!dw 0, 0
!db $0C0, 0, 0, 0, 0, 0, 0, $046
CLSID_ShellLink:
!dd $21401
!dw 0, 0
!db $0C0, 0, 0, 0, 0, 0, 0, $046
IID_IPersistFile:
!dd $0000010B
!dw 0, 0
!db $0C0, 0, 0, 0, 0, 0, 0, $046
- 
				BackupUser
- PureBasic Guru 
- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by Max..
Thanks El Choni!
Your variable declarations look "a little bit" different than mines.
But it doesn't work here...
This condition is not met and the procedure returns an empty string. If I force it to get into it, the result is still empty.
Max.
AMD Athlon, Matrox G550, Win 2K SP3, IE 6.0, PB 3.62
			
			
									
									
						Thanks El Choni!
Your variable declarations look "a little bit" different than mines.
But it doesn't work here...
Code: Select all
If hres =#S_OKMax.
AMD Athlon, Matrox G550, Win 2K SP3, IE 6.0, PB 3.62
- 
				BackupUser
- PureBasic Guru 
- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by El_Choni.
Which one is failing? CoCreateInstance_() or the following CallComs?.
Try doing some error handling:
And post the debugged result, to look up the error name. If you want to do it yourself, I'm using WINDOWS.INC file from Masm to see what error has occured.
El_Choni
			
			
									
									
						Which one is failing? CoCreateInstance_() or the following CallComs?.
Try doing some error handling:
Code: Select all
If hres=#S_OK
 ...
Else
  Debug Hex(hres)
EndIf
El_Choni
- 
				BackupUser
- PureBasic Guru 
- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by Max..
 
Seems that it fails at the Load Method.
Sadly I don't have XP avail at the moment. BTW, retested Danilo's CreateShortcut and that works on Win 2K.
Max.
AMD Athlon, Matrox G550, Win 2K SP3, IE 6.0, PB 3.62
			
			
									
									
						Sorry, forgot one line; this is the entire block now.Originally posted by El_Choni
Which one is failing? CoCreateInstance_() or the following CallComs? I bet this has to do with Win 2k (I've only tesed it in Win XP).
Seems that it fails at the Load Method.
Code: Select all
hres = CallCOM(#Load, ppf, wsz(), 0)      If hres=#S_OK
        TempBuffer = AllocateMemory(0, 1024)
        CallCOM(#GetPath, psl, TempBuffer, 1024, #NULL, #SLGP_UNCPRIORITY)
        TempBuffer = MemoryID() ; TempBuffer variable trashed for some reason (weird!)
        Info.s = PeekS(MemoryID())
        CallCOM(#GetArguments, psl, TempBuffer, 1024)
        Info+" "+PeekS(TempBuffer)
        FreeMemory(0)
      EndIf
    EndIfMax.
AMD Athlon, Matrox G550, Win 2K SP3, IE 6.0, PB 3.62
- 
				BackupUser
- PureBasic Guru 
- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by Max..
 
But:
I added now also - should have checked earlier - a
after the OpenFileRequester (yes, I opened a link: D:\Ethereal.lnk):
So it looks as if the OpenFileRequester resolves the link already.
If I hardcode
then your example works very well.
Is that behaviour different in Win 2K & XP?
BTW, thanks for your patience.
Max.
AMD Athlon, Matrox G550, Win 2K SP3, IE 6.0, PB 3.62
			
			
									
									
						Ok, it's strange:Originally posted by El_Choni
And post the debugged result, to look up the error name. If you want to do it yourself, I'm using WINDOWS.INC file from Masm to see what error has occured.
Code: Select all
Debug Hex(hres) -> 80070002I added now also - should have checked earlier - a
Code: Select all
Debug File$ -> C:\Programme\Ethereal\ethereal.exeSo it looks as if the OpenFileRequester resolves the link already.
If I hardcode
Code: Select all
File$ = "D:\Ethereal.lnk"Is that behaviour different in Win 2K & XP?
BTW, thanks for your patience.

Max.
AMD Athlon, Matrox G550, Win 2K SP3, IE 6.0, PB 3.62
- 
				BackupUser
- PureBasic Guru 
- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by El_Choni.
In XP the link is not resolved by OpenFileRequester().
About the error code, I can't find that one in WINDOWS.INC, maybe in the header files from lcc (but I don't have lcc here).
Those are the error codes for IPersistFile::Load
Maybe a solution would be to check if the returnd string ends in ".lnk". If it does, use the procedure, if it doesn't, use the string as it comes (suppose the link has been resolved).
El_Choni
			
			
									
									
						In XP the link is not resolved by OpenFileRequester().
About the error code, I can't find that one in WINDOWS.INC, maybe in the header files from lcc (but I don't have lcc here).
Those are the error codes for IPersistFile::Load
Code: Select all
STG_E_INVALIDFUNCTION                equ 80030001h
STG_E_FILENOTFOUND                   equ 80030002h
STG_E_PATHNOTFOUND                   equ 80030003h
STG_E_TOOMANYOPENFILES               equ 80030004h
STG_E_ACCESSDENIED                   equ 80030005h
STG_E_INVALIDHANDLE                  equ 80030006h
STG_E_INSUFFICIENTMEMORY             equ 80030008h
STG_E_INVALIDPOINTER                 equ 80030009h
STG_E_NOMOREFILES                    equ 80030012h
STG_E_DISKISWRITEPROTECTED           equ 80030013h
STG_E_SEEKERROR                      equ 80030019h
STG_E_WRITEFAULT                     equ 8003001Dh
STG_E_READFAULT                      equ 8003001Eh
STG_E_SHAREVIOLATION                 equ 80030020h
STG_E_LOCKVIOLATION                  equ 80030021h
STG_E_FILEALREADYEXISTS              equ 80030050h
STG_E_INVALIDPARAMETER               equ 80030057h
STG_E_MEDIUMFULL                     equ 80030070h
STG_E_ABNORMALAPIEXIT                equ 800300FAh
STG_E_INVALIDHEADER                  equ 800300FBh
STG_E_INVALIDNAME                    equ 800300FCh
STG_E_UNKNOWN                        equ 800300FDh
STG_E_UNIMPLEMENTEDFUNCTION          equ 800300FEh
STG_E_INVALIDFLAG                    equ 800300FFh
STG_E_INUSE                          equ 80030100h
STG_E_NOTCURRENT                     equ 80030101h
STG_E_REVERTED                       equ 80030102h
STG_E_CANTSAVE                       equ 80030103h
STG_E_OLDFORMAT                      equ 80030104h
STG_E_OLDDLL                         equ 80030105h
STG_E_SHAREREQUIRED                  equ 80030106h
STG_E_NOTFILEBASEDSTORAGE            equ 80030107h
STG_E_EXTANTMARSHALLINGS             equ 80030108h
El_Choni
- 
				BackupUser
- PureBasic Guru 
- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by Max..
Yep, could do, but as I get the links from the Directory functions and them are not resolved, everything is fine.
BTW, you should post your code in the snippets section and upload it to PB's site.
Max.
AMD Athlon, Matrox G550, Win 2K SP3, IE 6.0, PB 3.62
			
			
									
									
						Yep, could do, but as I get the links from the Directory functions and them are not resolved, everything is fine.
BTW, you should post your code in the snippets section and upload it to PB's site.
Max.
AMD Athlon, Matrox G550, Win 2K SP3, IE 6.0, PB 3.62