uses
...
{$IFDEF MSWINDOWS}windows, shlobj {for special folders}, ActiveX, ComObj,{$ENDIF}
...
procedure TMForm.CreateDesktopShortCut(Target, TargetArguments, ShortcutName: string);
var
IObject: IUnknown;
ISLink: IShellLink;
IPFile: IPersistFile;
PIDL: PItemIDList;
InFolder: array[0..MAX_PATH] of Char;
TargetName: String;
LinkName: WideString;
begin
{ Creates an instance of IShellLink }
IObject := CreateComObject(CLSID_ShellLink);
ISLink := IObject as IShellLink;
IPFile := IObject as IPersistFile;
ISLink.SetPath(pChar(Target));
ISLink.SetArguments(pChar(TargetArguments));
ISLink.SetWorkingDirectory(pChar(ExtractFilePath(Target)));
{ Get the desktop location }
SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, PIDL);
SHGetPathFromIDList(PIDL, InFolder);
LinkName := InFolder + PathDelim + ShortcutName+'.lnk';
{ Create the link }
IPFile.Save(PWChar(LinkName), false);
end;
const
CLSID_FolderShortcut: TGUID = (D1:$0AFACED1; D2:$E828; D3:$11D1; D4:($91, $87, $B5, $32, $F1, $E9, $57, $5D));
Apparently, as I discovered today, there are multiple types of shortcuts on Windows. There was some great code up on the Lazarus Windows Wiki for creating normal shortcuts:Code: [Select]uses
...
{$IFDEF MSWINDOWS}windows, shlobj {for special folders}, ActiveX, ComObj,{$ENDIF}
...
procedure TMForm.CreateDesktopShortCut(Target, TargetArguments, ShortcutName: string);
var
IObject: IUnknown;
ISLink: IShellLink;
IPFile: IPersistFile;
PIDL: PItemIDList;
InFolder: array[0..MAX_PATH] of Char;
TargetName: String;
LinkName: WideString;
begin
{ Creates an instance of IShellLink }
IObject := CreateComObject(CLSID_ShellLink);
ISLink := IObject as IShellLink;
IPFile := IObject as IPersistFile;
ISLink.SetPath(pChar(Target));
ISLink.SetArguments(pChar(TargetArguments));
ISLink.SetWorkingDirectory(pChar(ExtractFilePath(Target)));
{ Get the desktop location }
SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, PIDL);
SHGetPathFromIDList(PIDL, InFolder);
LinkName := InFolder + PathDelim + ShortcutName+'.lnk';
{ Create the link }
IPFile.Save(PWChar(LinkName), false);
end;
However, I couldn't find any code for creating Folder Shortcuts (see: http://en.wikipedia.org/wiki/Symbolic_link#Folder_Shortcuts.5B12.5D (http://en.wikipedia.org/wiki/Symbolic_link#Folder_Shortcuts.5B12.5D)). While the normal shortcuts use CLSID_ShellLink folder shortcuts use CLSID_FolderShortcut. So I tried just subbing that in the code. Microsoft's C++ examples seem to hint that that would be okay (see: http://msdn.microsoft.com/en-us/library/windows/desktop/bb776891(v=vs.85).aspx#Shellink_Creating_Shortcut (http://msdn.microsoft.com/en-us/library/windows/desktop/bb776891(v=vs.85).aspx#Shellink_Creating_Shortcut)). When I did that at first it said CLSID_FolderShortcut wasn't a known constant. So then I dug up the constant from some old Delphi code adding:Code: [Select]const
CLSID_FolderShortcut: TGUID = (D1:$0AFACED1; D2:$E828; D3:$11D1; D4:($91, $87, $B5, $32, $F1, $E9, $57, $5D));
That code compiled. However, when run I didn't end up with a Folder Shortcut. Now in the meantime, I've done some digging into folder shortcuts and they seem to be normal shortcuts in a folder marked slightly specially, with a hidden desktop.ini, so I could probably hack my way into working ones if needed, but I was wondering if there was a nice way to do it more like the CreateDesktopShortCut() procedure above?
The procedure CreateDesktopShortCut takes three arguments two of which are quite obvious but I have failed to find any information regarding 'TargetArguments' and suspect (hope) that this may be the key to a solution.
Thanks lainz - I ought to have realized that :-[The procedure CreateDesktopShortCut takes three arguments two of which are quite obvious but I have failed to find any information regarding 'TargetArguments' and suspect (hope) that this may be the key to a solution.
That argument is to send parameters to the program like:
CreateDesktopShortCut('C:\Windows\Notepad.exe', 'C:\Windows\win.ini', 'Win.ini in Notepad');
And can be used to create a shortcut to a folder like this:
CreateDesktopShortCut('%WINDIR%\explorer.exe', 'C:\Windows\', 'Windows folder');
The second parameter is the folder.
I had already tried that - without success - it does create a shortcut but when that is 'clicked' it puts up a dialogue asking which program I want to use to open the file. Thus it isn't a 'Folder' shortcut - and of course the icon is not what a folder shortcut icon would be, just a 'document' icon.
Maybe things changed on Windows 10, do you have Windows 7?Yes.
Maybe things changed on Windows 10, do you have Windows 7?Yes.
I noticed a potential error in your code at line 26 - it was missing +'.lnk' but adding that didn't have any effect.
OleCheck(SetPath(PChar(Target)));
OleCheck(SetDescription(PChar(Description)));
...
OleCheck(IPFile.Save(PWideChar(LinkName), false));
For me it failed on the last call because i forgot to declare it as a widestring :-[Try this with the original code, try this exactly don't change it:FOUND IT !!
CreateDesktopShortCut('%WINDIR%\explorer.exe', '/root,"C:\Program Files"', 'PF folder');