Page 1 of 2

can create shortcut in unicode mode

Posted: Wed Jun 11, 2008 12:07 pm
by Micko
hi everybody !
yes i know there is sometimes i left this forum but there is some reason and like you know that : hunt for natural and it is up to gallop.
i'm back know :D

Code: Select all

ProcedureDLL CreateShortcutPB(Path.s, LINK.s, Argument.s, DESCRIPTION.s, WorkingDirectory.s, ShowCommand.l, IconFile.s, IconIndexInFile.l)
  CoInitialize_(0)
  If CoCreateInstance_(?CLSID_ShellLink,0,1,?IID_IShellLink,@psl.IShellLinkA) = 0
    
    Set_ShellLink_preferences:
    
    ; The file TO which is linked ( = target for the Link )
    ;
    psl\SetPath(@Path)
    
    ; Arguments for the Target
    ;
    psl\SetArguments(@Argument)
    
    ; Working Directory
    ;
    psl\SetWorkingDirectory(@WorkingDirectory)
    
    ; Description ( also used as Tooltip for the Link )
    ;
    psl\SetDescription(@DESCRIPTION)
    
    ; Show command:
    ;               SW_SHOWNORMAL    = Default
    ;               SW_SHOWMAXIMIZED = aehmm... Maximized
    ;               SW_SHOWMINIMIZED = play Unreal Tournament
    psl\SetShowCmd(ShowCommand)
    
    ; Hotkey:
    ; The virtual key code is in the low-order byte,
    ; and the modifier flags are in the high-order byte.
    ; The modifier flags can be a combination of the following values:
    ;
    ;         HOTKEYF_ALT     = ALT key
    ;         HOTKEYF_CONTROL = CTRL key
    ;         HOTKEYF_EXT     = Extended key
    ;         HOTKEYF_SHIFT   = SHIFT key
    ;
    psl\SetHotkey(HotKey)
    
    ; Set Icon for the Link:
    ; There can be more than 1 icons in an icon resource file,
    ; so you have to specify the index.
    ;
    psl\SetIconLocation(@IconFile, IconIndexInFile)
    
    
    ShellLink_SAVE:
    ; Query IShellLink For the IPersistFile interface For saving the
    ; shortcut in persistent storage.
    If psl\QueryInterface(?IID_IPersistFile,@ppf.IPersistFile) = 0
      ; Ensure that the string is Unicode.
      mem.s = Space(1000) ;AllocateMemory(1,1000)
      MultiByteToWideChar_(#CP_ACP, 0, LINK, -1, mem, 1000)
      ;Save the link by calling IPersistFile::Save.
      hres = ppf\Save(@mem,#True)
      result = 1
      ppf\Release()
    EndIf
    psl\Release()
  EndIf
  CoUninitialize_()
  ProcedureReturn result
  
  DataSection
    CLSID_ShellLink:
    ; 00021401-0000-0000-C000-000000000046
    Data.l $00021401
    Data.w $0000,$0000
    Data.b $C0,$00,$00,$00,$00,$00,$00,$46
    IID_IShellLink:
    ; DEFINE_SHLGUID(IID_IShellLinkA,         0x000214EEL, 0, 0);
    ; C000-000000000046
    Data.l $000214EE
    Data.w $0000,$0000
    Data.b $C0,$00,$00,$00,$00,$00,$00,$46
    IID_IPersistFile:
    ; 0000010b-0000-0000-C000-000000000046
    Data.l $0000010B
    Data.w $0000,$0000
    Data.b $C0,$00,$00,$00,$00,$00,$00,$46
  EndDataSection
  
EndProcedure

CreateShortcutPB("C:\Windows\System32\Notepad.exe","C:\Super Notepad.lnk","","NotePAD is a lightweight editor","",#SW_SHOWMAXIMIZED,"%SystemRoot%\system32\SHELL32.dll",12)

Posted: Wed Jun 11, 2008 12:14 pm
by srod
Presumably you want IID_IShellLinkW

Code: Select all

DataSection

  IID_IShellLinkW: ; {000214F9-0000-0000-C000-000000000046}
    Data.l $000214F9
    Data.w $0000, $0000
    Data.b $C0, $00, $00, $00, $00, $00, $00, $46

EndDataSection

Posted: Fri Jun 13, 2008 12:16 pm
by Micko
hi Srod !
i think that is what i'm looking for but i try it like thi and couldn't make it work :(

Code: Select all

Global IID_IShellLinkW,IID_IShellLink
ProcedureDLL CreateShortcutPB(Path.s, LINK.s, Argument.s, DESCRIPTION.s, WorkingDirectory.s, ShowCommand.l, IconFile.s, IconIndexInFile.l) 
   
  
  CoInitialize_(0) 
  If CoCreateInstance_(?CLSID_ShellLink,0,1,?IID_IShellLink,@psl.IShellLinkW) =  0
    
    Set_ShellLink_preferences: 
    
    ; The file TO which is linked ( = target for the Link ) 
    ; 
    psl\SetPath(@Path) 
    
    ; Arguments for the Target 
    ; 
    psl\SetArguments(@Argument) 
    
    ; Working Directory 
    ; 
    psl\SetWorkingDirectory(@WorkingDirectory) 
    
    ; Description ( also used as Tooltip for the Link ) 
    ; 
    psl\SetDescription(@DESCRIPTION) 
    
    ; Show command: 
    ;               SW_SHOWNORMAL    = Default 
    ;               SW_SHOWMAXIMIZED = aehmm... Maximized 
    ;               SW_SHOWMINIMIZED = play Unreal Tournament 
    psl\SetShowCmd(ShowCommand) 
    
    ; Hotkey: 
    ; The virtual key code is in the low-order byte, 
    ; and the modifier flags are in the high-order byte. 
    ; The modifier flags can be a combination of the following values: 
    ; 
    ;         HOTKEYF_ALT     = ALT key 
    ;         HOTKEYF_CONTROL = CTRL key 
    ;         HOTKEYF_EXT     = Extended key 
    ;         HOTKEYF_SHIFT   = SHIFT key 
    ; 
    psl\SetHotkey(HotKey) 
    
    ; Set Icon for the Link: 
    ; There can be more than 1 icons in an icon resource file, 
    ; so you have to specify the index. 
    ; 
    psl\SetIconLocation(@IconFile, IconIndexInFile) 
    
    
    ShellLink_SAVE: 
    ; Query IShellLink For the IPersistFile interface For saving the 
    ; shortcut in persistent storage. 
    If psl\QueryInterface(?IID_IPersistFile,@ppf.IPersistFile) = 0 
      ; Ensure that the string is Unicode. 
      mem.s = Space(1000) ;AllocateMemory(1,1000) 
      MultiByteToWideChar_(#CP_ACP, 0, LINK, -1, mem, 1000) 
      ;Save the link by calling IPersistFile::Save. 
      hres = ppf\Save(@mem,#True) 
      result = 1 
      ppf\Release() 
    EndIf 
    psl\Release() 
  EndIf 
  CoUninitialize_() 
  ProcedureReturn result 
    
 DataSection 
    CLSID_ShellLink: 
    ; 00021401-0000-0000-C000-000000000046 
    Data.l $00021401 
    Data.w $0000,$0000 
    Data.b $C0,$00,$00,$00,$00,$00,$00,$46 
        
    IID_IPersistFile: 
    ; 0000010b-0000-0000-C000-000000000046 
    Data.l $0000010B 
    Data.w $0000,$0000 
    Data.b $C0,$00,$00,$00,$00,$00,$00,$46 
    
    CompilerIf #PB_Compiler_Unicode = 0
    
    IID_IShellLink:
    ; DEFINE_SHLGUID(IID_IShellLinkA,         0x000214EEL, 0, 0); 
    ; C000-000000000046 
    Data.l $000214EE 
    Data.w $0000,$0000 
    Data.b $C0,$00,$00,$00,$00,$00,$00,$46
    
    CompilerElse
    
    IID_IShellLinkW: ; {000214F9-0000-0000-C000-000000000046} 
    Data.l $000214F9 
    Data.w $0000, $0000 
    Data.b $C0, $00, $00, $00, $00, $00, $00, $46 
    CompilerEndIf

 EndDataSection    
    
EndProcedure 

CreateShortcutPB("C:\Windows\System32\Notepad.exe","C:\Super Notepad.lnk","","NotePAD is a lightweight editor","",#SW_SHOWMAXIMIZED,"%SystemRoot%\system32\SHELL32.dll",12)

Posted: Fri Jun 13, 2008 1:09 pm
by srod
You are still using MultiByteToWideChar_() even though the strings will already be in unicode!

Posted: Sat Jun 14, 2008 2:37 pm
by Micko
srod wrote:You are still using MultiByteToWideChar_() even though the strings will already be in unicode!
yes i see that before but i used Droopy's and in unicode mode i could'nt make this functions work.
i have mentioned this too. Now i'm gooing to test the last version of Droopy's Lib.
thanks Srod for your help

Posted: Sat Jun 14, 2008 2:58 pm
by srod
Right, you had a problem with your labels.

The following works fine here on Vista in either Ansi or Unicode mode :

Code: Select all

Global IID_IShellLinkW,IID_IShellLink 
ProcedureDLL CreateShortcutPB(Path.s, LINK.s, Argument.s, DESCRIPTION.s, WorkingDirectory.s, ShowCommand.l, IconFile.s, IconIndexInFile.l) 
    
  
  CoInitialize_(0) 
  If CoCreateInstance_(?CLSID_ShellLink,0,1,?IID_IShellLink,@psl.IShellLinkW) =  0 
    
    Set_ShellLink_preferences: 
    
    ; The file TO which is linked ( = target for the Link ) 
    ; 
    psl\SetPath(@Path) 
    
    ; Arguments for the Target 
    ; 
    psl\SetArguments(@Argument) 
    
    ; Working Directory 
    ; 
    psl\SetWorkingDirectory(@WorkingDirectory) 
    
    ; Description ( also used as Tooltip for the Link ) 
    ; 
    psl\SetDescription(@DESCRIPTION) 
    
    ; Show command: 
    ;               SW_SHOWNORMAL    = Default 
    ;               SW_SHOWMAXIMIZED = aehmm... Maximized 
    ;               SW_SHOWMINIMIZED = play Unreal Tournament 
    psl\SetShowCmd(ShowCommand) 
    
    ; Hotkey: 
    ; The virtual key code is in the low-order byte, 
    ; and the modifier flags are in the high-order byte. 
    ; The modifier flags can be a combination of the following values: 
    ; 
    ;         HOTKEYF_ALT     = ALT key 
    ;         HOTKEYF_CONTROL = CTRL key 
    ;         HOTKEYF_EXT     = Extended key 
    ;         HOTKEYF_SHIFT   = SHIFT key 
    ; 
    psl\SetHotkey(HotKey) 
    
    ; Set Icon for the Link: 
    ; There can be more than 1 icons in an icon resource file, 
    ; so you have to specify the index. 
    ; 
    psl\SetIconLocation(@IconFile, IconIndexInFile) 
    
    
    ShellLink_SAVE: 
    ; Query IShellLink For the IPersistFile interface For saving the 
    ; shortcut in persistent storage. 
    If psl\QueryInterface(?IID_IPersistFile,@ppf.IPersistFile) = 0 
      ; Ensure that the string is Unicode. 
      mem.s = Space(1000) ;AllocateMemory(1,1000) 
      PokeS(@mem, LINK, -1, #PB_Unicode)
      ;Save the link by calling IPersistFile::Save. 
      hres = ppf\Save(@mem,#True) 
      result = 1 
      ppf\Release() 
    EndIf 
    psl\Release() 
  EndIf 
  CoUninitialize_() 
  ProcedureReturn result 
    
 DataSection 
    CLSID_ShellLink: 
    ; 00021401-0000-0000-C000-000000000046 
    Data.l $00021401 
    Data.w $0000,$0000 
    Data.b $C0,$00,$00,$00,$00,$00,$00,$46 
        
    IID_IPersistFile: 
    ; 0000010b-0000-0000-C000-000000000046 
    Data.l $0000010B 
    Data.w $0000,$0000 
    Data.b $C0,$00,$00,$00,$00,$00,$00,$46 
    
    CompilerIf #PB_Compiler_Unicode = 0 
    
    IID_IShellLink: 
    ; DEFINE_SHLGUID(IID_IShellLinkA,         0x000214EEL, 0, 0); 
    ; C000-000000000046 
    Data.l $000214EE 
    Data.w $0000,$0000 
    Data.b $C0,$00,$00,$00,$00,$00,$00,$46 
    
    CompilerElse 
    
    IID_IShellLink: ; {000214F9-0000-0000-C000-000000000046} 
    Data.l $000214F9 
    Data.w $0000, $0000 
    Data.b $C0, $00, $00, $00, $00, $00, $00, $46 
    CompilerEndIf 

 EndDataSection    
    
EndProcedure 

CreateShortcutPB("C:\Windows\System32\Notepad.exe","C:\Super Notepad.lnk","","NotePAD is a lightweight editor","",#SW_SHOWMAXIMIZED,"%SystemRoot%\system32\SHELL32.dll",12)

Posted: Sat Jun 14, 2008 3:17 pm
by Micko
yep this work for me too. :)
so you replace this part:

Code: Select all

MultiByteToWideChar_(#CP_ACP, 0, LINK, -1, mem, 1000)
with this one:

Code: Select all

PokeS(@mem, LINK, -1, #PB_Unicode) 
and it work. :shock:
if MultiByteToWideChar_ should convert to unicode why it won't work :shock:

Posted: Sat Jun 14, 2008 7:55 pm
by srod
No, there was another mistake with your code with one of the data labels. Compare the labels in the data section in your code with those in mine! :wink:

As for MultiByteToWideChar_(), use this to convert Ansi to Unicode NOT Unicode to Unicode! You're safe with the PokeS() method because if the strings are already in Unicode then it just copies the string etc.

Posted: Sun Jun 15, 2008 3:44 pm
by Micko
Very clear now Srod :D

Posted: Sun Jun 15, 2008 3:51 pm
by srod
You're welcome. Useful bit of code, so thanks for that.

Posted: Sun Jun 15, 2008 7:32 pm
by Micko
:D :wink:

Re: can create shortcut in unicode mode

Posted: Tue Jul 20, 2010 1:21 pm
by Klonk
This is an old thread, but that procedure was exactly what I was searching. The only problem: It does not work with PB 4.50.

I always get an error message, e.g.:

Code: Select all

        psl\SetPath(@Path)
Wrong type, a string is expected.

Hm, but the variable Path is a string, and that's a pointer to it. So in my opinion it should work, or did I miss something?

Re: can create shortcut in unicode mode

Posted: Tue Jul 20, 2010 1:33 pm
by srod
Yes, some of the interface definitions were adjusted to make use of suitable pseudotypes etc.

Just remove the @ symbol from every line which throws an error and you will be fine. Remember to compile in Unicode mode though.

Re: can create shortcut in unicode mode

Posted: Tue Jul 20, 2010 3:24 pm
by ts-soft

Re: can create shortcut in unicode mode

Posted: Tue Jul 20, 2010 5:45 pm
by SFSxOI
This is what i've been using for shortcuts > http://www.purebasic.fr/english/viewtop ... t=shortcut

Also, don't forget symbolic links as well in considering the shortcut area for Windows Vista and Windows 7:

Code: Select all

;based on: http://msdn.microsoft.com/en-us/library/aa363866(VS.85).aspx

;dwFlags:
;0x0 = The link target is a file. 
;0x1 = The link target is a directory.

;WARNING - Must be using NTFS for SymLinks to work

; example creates a symlink for the windows\system32\ folder. 
; will create a symlink from where ever the file is run.

ProcedureDLL Sym_Link(in_lnkname.s, in_targetname.s, dw_flag.l)

Libef = LoadLibrary_("Kernel32.dll")

  If Libef
    *SymLfunc = GetProcAddress_(Libef, "CreateSymbolicLinkA")
; *SymLfunc = GetProcAddress_(Libef, "CreateSymbolicLinkW") ; for unicode
    CallFunctionFast(*SymLfunc, in_lnkname, in_targetname, dw_flag)
    FreeLibrary_(Libef)
  EndIf

ProcedureReturn 

EndProcedure

Sym_Link("test_link", "c:\windows\system32\", 1)