2

I am looking for a way to programmatically add a folder to the Favorites in Windows Explorer. Its Windows Explorer specific and based around this project: http://www.codeproject.com/Tips/132804/Open-folders-using-a-Run-Command

So far I've tried Process Monitor and searching the registry, but I can't seem to find my Windows Explorer Favourites in regedit.

Jeremy Thompson
  • 61,933
  • 36
  • 195
  • 321

4 Answers4

6

Instead of reading the registry, you can do the following:

string favoritesFolder = 
    Environment.GetFolderPath(Environment.SpecialFolder.Favorites);
bsegraves
  • 980
  • 13
  • 22
4

P.S.: Make sure to check out @bsegraves' solution, which I think is far better than mine.

I'm not sure if this is what you're looking for, but I think the favorite folder can be found through the following registry value:

HKEY_CURRENT_USER\
  Software\
    Microsoft\
      Windows\
        CurrentVersion\
          Explorer\
            User Shell Folders\
              Favorites

You should be able to retrieve this folder name with the following code:

using Microsoft.Win32;
...

RegistryKey topLevel = Registry.CurrentUser;
RegistryKey key = topLevel.OpenSubKey(
    @"Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders",
    true);

string favoriteFolder = key.GetValue("Favorites").ToString();

It's then only a matter of creating a link, or document, in the specified folder.

(Take note that this key's value might be something like %USERPROFILE%\Favorites; the environment variable should automatically get expanded by the .GetValue(..) method invoked above.)

Community
  • 1
  • 1
stakx - no longer contributing
  • 83,039
  • 20
  • 168
  • 268
  • THANKS! That directory %USERPROFILE%\Favorites has them:) I'd vote you up, if I had 15 points:( – Jeremy Thompson Nov 24 '10 at 21:51
  • @Jeremy, even if you can't upvote, you should still be able to accept the answer (tick it) if you think it sufficiently answered your question. (That'll give *you* something like 2 rank points, too.) – stakx - no longer contributing Nov 24 '10 at 22:00
  • I think the OP was asking the WINDOWS explorer, not IE. The Favorites folder contains links to favorites in IE. – KFL May 20 '13 at 18:37
  • 3
    @KFL: To be honest, I'm now a little puzzled why my answer seemed right to both me and the OP at the time. Today, my Explorer favourites are indeed *not* located in `Favorites` (where the registry entry points to), but in `Links`. Could it be that the Windows OS has changed slightly since then? I had Windows 7 then, but am using Windows 8 now. – stakx - no longer contributing May 20 '13 at 19:21
  • 1
    @stakx Mate your answer did work. Cant test it on Win8 right now but I wouldn't have marked it correct if it wasn't - this was my very first question here on [so]. Retagged to make my question Win7 specific. – Jeremy Thompson May 09 '14 at 08:45
  • I had to use `using Microsoft.Win32;` – Joe Inner Dec 12 '14 at 18:10
  • @JoeInner: Corrected. Thanks for the hint! – stakx - no longer contributing Dec 12 '14 at 22:03
3

For Windows 8 this location has been changed to %USERPROFILE%\Links. Please refer to this answer.

Community
  • 1
  • 1
KFL
  • 17,162
  • 17
  • 65
  • 89
  • 1
    +1 thanks for the update. This was my 1st ever question here at [so], I'll have to see [if this folder shortcut trick still works on Win8](http://www.codeproject.com/Tips/132804/Open-folders-using-a-Run-Command) – Jeremy Thompson May 20 '13 at 22:49
0

Starting from Vista FOLDERID_Links const was added. It points to Favorites of Windows explorer. My code (Delphi, but the main idea is visible):

procedure AddFileObjectToFavorites(AParent: HWND; const AObjectFileName: UnicodeString);

  function GetFavorites: PItemIDList;
  begin
    if IsWindowsVistaOrLater then
      OleCheck(SHGetKnownFolderIDList(FOLDERID_Links, 0, 0, Result))
    else
      OleCheck(SHGetFolderLocation(AParent, CSIDL_FAVORITES, 0, 0, Result));
  end;

var
  Desktop: IShellFolder;
  Eaten: DWORD;
  Attr: DWORD;
  ObjectIDList: PItemIDList;
  ObjectParentFolder: IShellFolder;
  ObjectChildIDList: PItemIDList;
  LinksIDList: PItemIDList;
  LinksParentFolder: IShellFolder;
  LinksChildIDList: PItemIDList;
  DataObject: IDataObject;
  LinksDropTarget: IDropTarget;
  Effect: Integer;
begin
  OleCheck(SHGetDesktopFolder(Desktop));
  try
    Attr := 0;
    OleCheck(Desktop.ParseDisplayName(AParent, nil, PWideChar(AObjectFileName), Eaten, ObjectIDList, Attr));
    try
      SHBindToParent(ObjectIDList, IShellFolder, Pointer(ObjectParentFolder), ObjectChildIDList);
      try
        LinksIDList := GetFavorites;
        try
          OleCheck(SHBindToParent(LinksIDList, IShellFolder, Pointer(LinksParentFolder), LinksChildIDList));
          try
            OleCheck(LinksParentFolder.GetUIObjectOf(AParent, 1, LinksChildIDList, IDropTarget, nil, LinksDropTarget));
            try
              OleCheck(ObjectParentFolder.GetUIObjectOf(AParent, 1, ObjectChildIDList, IDataObject, nil, DataObject));
              try
                Effect := DROPEFFECT_LINK;
                OleCheck(LinksDropTarget.DragEnter(DataObject, 0, Point(0, 0), Effect));
                if Effect and DROPEFFECT_LINK = 0 then
                  begin
                    OleCheck(LinksDropTarget.DragLeave);
                    raise Exception.Create('Cannot drop');
                  end;
                Effect := DROPEFFECT_LINK;
                OleCheck(LinksDropTarget.Drop(DataObject, 0, Point(0, 0), Effect));
              finally
                DataObject := nil;
              end;
            finally
              LinksDropTarget := nil;
            end;
          finally
            LinksParentFolder := nil;
          end;
        finally
          CoTaskMemFree(LinksIDList);
        end;
      finally
        ObjectParentFolder := nil;
      end;
    finally
      CoTaskMemFree(ObjectIDList);
    end;
  finally
    Desktop := nil;
  end;
end;
Denis Anisimov
  • 3,297
  • 1
  • 10
  • 18
  • 3
    I haven't coded in Delphi before but **7 try catch's** vs *3 lines of .net*. WHOA, *pure insanity*. – Jeremy Thompson Dec 13 '14 at 11:45
  • @JeremyThompson 5 of those `try/finally` blocks are redundant and unnecessary. Delphi has native support for interface reference counting. There is no need to explicitly release the interfaces in this example. Only the 2 calls to `CoTaskMemFree()` should be protected with `try/finally`. Also, `IShellLink` would be far simpler to use than jumping through all these hoops setting up `IShellFolder` and `IDataObject`. – Remy Lebeau Apr 13 '17 at 07:10