{"id":236,"date":"2007-05-12T17:20:45","date_gmt":"2007-05-12T15:20:45","guid":{"rendered":" http:\/\/www.nsonic.de\/blog\/2007\/05\/creating-a-shortcut-to-a-file\/"},"modified":"2007-05-12T17:20:47","modified_gmt":"2007-05-12T15:20:47","slug":"creating-a-shortcut-to-a-file","status":"publish","type":"post","link":"https:\/\/www.nsonic.de\/blog\/2007\/05\/creating-a-shortcut-to-a-file\/","title":{"rendered":"creating a Shortcut to a file"},"content":{"rendered":"<p>Icon Shortcut Verkn\u00fcpfung anlegen<\/p>\n<p>You can try the code below &#8211; maybe you needed CoInitialize?<br \/>\nThe code works fine for me on NT and 98, using Delphi4.<br \/>\n<!--more--><br \/>\n[code lang=&#8221;delphi&#8221;]{<br \/>\n function CreateAShortcut(aTarget,startDir,aCaption,aGroup: string;<br \/>\n   aLoc: TShortcut; silent: Boolean): Boolean;<\/p>\n<p> HISTORY:  Original version by<br \/>\n ========  &#8211; Jon E. Scott<br \/>\n      web: http:\/\/members.xoom.com\/jescott  (&#8220;Delphi Code Tips&#8221;)<br \/>\n      email: jescott@xoommail.com <\/p>\n<p>     Some improvements and comments 1999-06-18 by<br \/>\n     Bjorn Mossberg: mossberg@mindspring.com <\/p>\n<p> PURPOSE:  To create a shortcut on the desktop, start menu,<br \/>\n ========  in a program group, in the SendTo folder,<br \/>\n     or in the SysTray region.<\/p>\n<p> REQUIRES:<br \/>\n =========<br \/>\n uses ShlObj, ComObj, Registry, ActiveX; \/\/ and others<\/p>\n<p> type<br \/>\n  TShortcut = (sc_Desktop, sc_QuickLaunch, sc_SendTo,<br \/>\n      sc_Start, sc_Programs);<\/p>\n<p> PARAMETERS:<br \/>\n ===========<\/p>\n<p> aTarget:  The full path to the executable file<br \/>\n     for which a shortcut is to be created.<\/p>\n<p> startDir: String specifying the folder that is to be made<br \/>\n     current before aTarget executes. May be blank.<\/p>\n<p> aCaption: String specifying the &#8220;legend&#8221; to be written<br \/>\n     under the icon. May be left blank, in which<br \/>\n     case the name of the executable file minus<br \/>\n     its extension is used.<br \/>\n     Caution: Use only legal file characters!<\/p>\n<p> aGroup:  Meaningful only when aLoc=sc_Programs,<br \/>\n     sc_Desktop, or sc_SendTo.<br \/>\n     Specifies the name of the subfolder to<br \/>\n     which the shortcut is to be added.<br \/>\n     Should already exist.<\/p>\n<p> aLoc:   One of the values of type ShortcutType:<\/p>\n<p>  }<br \/>\nfunction CreateAShortcut(aTarget,startDir,aCaption,aGroup: string;<br \/>\n   aLoc: TShortcut; silent: Boolean): Boolean;<br \/>\nvar<br \/>\n anObject: IUnknown;<\/p>\n<p> function SaveLinkFile(aCap,aFldr: String): Boolean;<br \/>\n var<br \/>\n  aPFile: IPersistFile;<br \/>\n  s,fName: String;<br \/>\n  wName: WideString;<br \/>\n  i:   Integer;<br \/>\n begin<br \/>\n  {Save a copy of the object as a link file.<br \/>\n  Try up to 3 times, using tails &#8221; (2)&#8221; and &#8221; (3)&#8221;.}<br \/>\n  Result := False;<br \/>\n  aPFile := anObject as IPersistFile;<br \/>\n  s   := EmptyStr;<br \/>\n  for i:=1 to 3 do begin<br \/>\n   fName  := aCap + s + &#8216;.lnk&#8217;;<br \/>\n   wName  := MergedPath(aFldr,fName);<br \/>\n   Result := S_OK=aPFile.Save(PWChar(wName), False);<br \/>\n   if Result then Break;<br \/>\n   s := Format(&#8216; (%d)&#8217;,[i]);<br \/>\n  end;<br \/>\n end;<\/p>\n<p> function MergedPath(rootDir,subDir: String): String;<br \/>\n var<br \/>\n  n: Integer;<br \/>\n begin<br \/>\n  n := Length(rootDir);<br \/>\n  if n=0 then Result := subDir<br \/>\n  else begin<br \/>\n   if rootDir[n]=&#8217;\\&#8217; then Delete(rootDir,n,1);<br \/>\n   n := Length(subDir);<br \/>\n   if n=0 then Result := rootDir<br \/>\n   else begin<br \/>\n    if subDir[1]=&#8217;\\&#8217; then Delete(subDir,1,1);<br \/>\n    Result := rootDir + &#8216;\\&#8217; + subDir;<br \/>\n   end;<br \/>\n  end;<br \/>\n end;<\/p>\n<p>const<br \/>\n BaseKey   = &#8216;Software\\MicroSoft\\Windows\\CurrentVersion&#8217;;<br \/>\n Shell_Folders = &#8216;Shell Folders&#8217;;<br \/>\n VDesktop   = &#8216;Desktop&#8217;;<br \/>\n ProgramMenu  = &#8216;&#8221;Start | Programs&#8221; menu&#8217;;<br \/>\nvar<br \/>\n aDir,aVar: String;<br \/>\n aDesc:  String;<br \/>\n dskTop:  String;<br \/>\n s,msg:  String;<br \/>\nbegin<br \/>\n Result := False;<br \/>\n if NOT (CoInitialize(nil) in [S_OK,S_FALSE]) then begin<br \/>\n  ShowMessage(&#8216;Could not initialize OLE COM Library&#8217;);<br \/>\n  Exit;<br \/>\n end;<\/p>\n<p> {Create an object that can be used as a shortcut<br \/>\n and later saved as a customized ???.lnk file.}<br \/>\n anObject := CreateComObject(CLSID_ShellLink);<br \/>\n try<br \/>\n  with anObject as IShellLink do begin<br \/>\n   {Write in &#8220;Target&#8221; in the link file:<br \/>\n    The full path of the executable file}<br \/>\n   SetPath(PChar(aTarget));<\/p>\n<p>   {If supplied, write in &#8220;Start In&#8221; in the link file:<br \/>\n    The folder to be made current before executing &#8220;Target&#8221;.}<br \/>\n   if (Length(startDir)>0) AND DirectoryExists(startDir) then<br \/>\n    SetWorkingDirectory(PChar(startDir));<br \/>\n  end;<\/p>\n<p>  {If aCaption is supplied we use that as the caption<br \/>\n  under the icon representing the shortcut.<br \/>\n  Otherwise we simply strip the extension<br \/>\n  from the name of the target file.<br \/>\n  NOTE: The name of the link file is &#8220;aCaption.lnk&#8221;. }<br \/>\n  if Length(aCaption)=0 then<br \/>\n   aCaption := ExtractFileName(aTarget);<br \/>\n  aCaption := ReplaceAll(aCaption,&#8217;\/&#8217;,&#8217;-&#8216;); {May need other fixing.}<br \/>\n  aCaption := ChangeFileExt(aCaption, EmptyStr);<\/p>\n<p>  aVar := EmptyStr;<br \/>\n  aDesc := EmptyStr;<br \/>\n  case aLoc of<br \/>\n   sc_Start:  aVar := &#8216;Start Menu&#8217;;<br \/>\n   sc_Programs: begin<br \/>\n         aVar := &#8216;Programs&#8217;;<br \/>\n         aDesc := ProgramMenu;<br \/>\n        end;<br \/>\n   sc_SendTo:  begin<br \/>\n         aVar := &#8216;SendTo&#8217;;<br \/>\n         aDesc := aVar + &#8216; menu&#8217;;<br \/>\n        end;<br \/>\n   sc_QuickLaunch:<br \/>\n    with TRegIniFile.Create(BaseKey+&#8217;\\GrpConv&#8217;) do try<br \/>\n     aVar := &#8216;Quick Launch&#8217;; {Need aVar for msg later}<br \/>\n     aDir := ReadString(&#8216;MapGroups&#8217;,aVar,EmptyStr);<br \/>\n     aDesc := aVar +  &#8216; (SysTray) area&#8217;;<br \/>\n    finally<br \/>\n     Free;<br \/>\n    end;<br \/>\n  else<br \/>\n   aVar := VDesktop; {Default}<br \/>\n  end;<br \/>\n  if Length(aDesc)=0 then<br \/>\n   aDesc := aVar;<\/p>\n<p>  with TRegIniFile.Create(BaseKey+&#8217;\\Explorer&#8217;) do try<br \/>\n   {Always get the path to the Desktop as a fallback.}<br \/>\n   dskTop := ReadString(Shell_Folders,VDesktop,EmptyStr);<br \/>\n   if Length(aDir)=0 then begin<br \/>\n    {Here for all cases except _QUICKLAUNCH}<br \/>\n    if Length(aVar)>0 then {Paranoid check}<br \/>\n     aDir := ReadString(Shell_Folders,aVar,EmptyStr);<br \/>\n    if Length(aDir)=0 then {Should never happen, but &#8230;}<br \/>\n     aDir := dskTop;<br \/>\n   end;<br \/>\n  finally<br \/>\n   Free;<br \/>\n  end;<\/p>\n<p>  if Length(aDir)=0 then<br \/>\n   {Hard to imagine that we&#8217;ll ever be here.}<br \/>\n   ShowMessage(&#8216;Could not determine where to create new shortcut!&#8217;)<br \/>\n  else begin<br \/>\n   msg := Format(&#8216;Added shortcut &#8220;%s&#8221; to the %s&#8217;,[aCaption,aDesc]);<br \/>\n   {Subfolders do not make sense for the SysTray or StartMenu.}<br \/>\n   if (Length(aGroup)>0) AND<br \/>\n    (aLoc in [sc_Desktop,sc_SendTo,sc_Programs]) then<br \/>\n   begin<br \/>\n    {The caller is suggesting a subfolder which<br \/>\n    we hope exists. Use it only if it does!}<br \/>\n    s := MergedPath(aDir,aGroup);<br \/>\n    if DirectoryExists(s) then begin<br \/>\n     aDir := s;<br \/>\n     AppendStr(msg,Format(&#8216; in the subfolder &#8220;%s&#8221;&#8216;,[aGroup]));<br \/>\n    end else<br \/>\n     msg := Format(&#8216;&#8221;%s&#8221; is not a subfolder of the %s.&#8217;<br \/>\n      +&#8217; Added the shortcut directly instead.&#8217;,[aGroup,aDesc]);<br \/>\n   end;<\/p>\n<p>   {Save a copy of the object as a link file.<br \/>\n   Try up to 3 times, using tails &#8221; (2)&#8221; and &#8221; (3)&#8221;.}<br \/>\n   Result := SaveLinkFile(aCaption,aDir);<\/p>\n<p>   if NOT Result then<br \/>\n    msg := &#8216;Could not create shortcut to &#8216; + aTarget;<br \/>\n   if NOT Result OR NOT silent then<br \/>\n    ShowMessage(msg);<\/p>\n<p>   if (Length(dskTop)>0) AND (aDir<>dskTop) AND<br \/>\n    {Since the dskTop folder is well defined, and not the<br \/>\n    one we just added the shortcut to, we offer to add a<br \/>\n    copy of the shortcut to the Desktop as well.<br \/>\n    We do this whether we failed above or not.}<br \/>\n    (mrYes=MessageDlg(&#8216;Would you like to add a copy&#8217;+<br \/>\n      &#8216; of the shortcut to the desktop?&#8217;,<br \/>\n      mtConfirmation,[mbYes,mbNo],0)) then<br \/>\n   begin<br \/>\n    {Don&#8217;t reset Result unless we are successful!}<br \/>\n    msg := &#8216;esktop shortcut to &#8216;+aTarget;<br \/>\n    if SaveLinkFile(aCaption,dskTop) then begin<br \/>\n     Result := True;<br \/>\n     msg  := &#8216;D&#8217;+msg+&#8217; successfully created!&#8217;;<br \/>\n    end else<br \/>\n     msg := &#8216;Could not create d&#8217;+msg;<br \/>\n    if NOT Result OR NOT silent then<br \/>\n     ShowMessage(msg);<br \/>\n   end;<br \/>\n  end;<br \/>\n finally<br \/>\n\/\/  TComObject(anObject).Free; {Cannot do this! Memory leak???}<br \/>\n  CoUninitialize;<br \/>\n end;<br \/>\nend;<br \/>\n[\/code]<\/p>\n<p>[tags]Delphi, System, Files[\/tags]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Icon Shortcut Verkn\u00fcpfung anlegen You can try the code below &#8211; maybe you needed CoInitialize? The code works fine for me on NT&hellip;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":""},"categories":[11],"tags":[75,112,113],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p71Tml-3O","_links":{"self":[{"href":"https:\/\/www.nsonic.de\/blog\/wp-json\/wp\/v2\/posts\/236"}],"collection":[{"href":"https:\/\/www.nsonic.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.nsonic.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.nsonic.de\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.nsonic.de\/blog\/wp-json\/wp\/v2\/comments?post=236"}],"version-history":[{"count":0,"href":"https:\/\/www.nsonic.de\/blog\/wp-json\/wp\/v2\/posts\/236\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.nsonic.de\/blog\/wp-json\/wp\/v2\/media?parent=236"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.nsonic.de\/blog\/wp-json\/wp\/v2\/categories?post=236"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.nsonic.de\/blog\/wp-json\/wp\/v2\/tags?post=236"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}