Get Path To “Links” (AKA Favorites) Folder

折月煮酒 提交于 2019-11-28 13:15:49

问题


UPDATE:

So I just found out in doing all this leg work that it seems the "Links" folder in your user folder can be named ANYTHING and you can still access it by going to "C:\Users(username)\Links"

Ex: Rename

"C:\Users\(username)\Links"

to

"C:\Users\(username)\MyNewLinksFolder"

Then try to browse to...

"C:\Users\(username)\Links"

(forehead to palm)


There is a "Favorites" node in the Windows 7 file explorer tree:

The path to those favorites (by default) is here:

I want to be able to get this path via c# code. I was hoping to use the Environment.SpecialFolder Enum but that seems to be a wash! I can't depend on the folder always residing at:

c:\users\[username]\Links

... because anyone could change that directory name, it still work correctly and then my hardcoded path would be useless.

So! My question is, how can I get c# to return that path without using a hardcoded string? I would also like to be able to get those items icons as well!

Thanks!


回答1:


Just wanted to share what I came up with. I created a few classes, functions etc that might help others out...

NOTES: - You need to add the WinAPIs reference to your project because it's in a different namespace. - In my case SpecialFolders.cs is contained in a namespace called "FileFolderWorker" so make sure you are calling the function (shown in Usage below) from the same namespace or you will need a using statement as depicted in the Usage area below as well.

Usage

using FileFolderWorker;
SpecialFolders.DebugShowAllFolders();

WinAPI.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace WinAPIs
{
    public class WinAPI
    {
        #region Shell32
        #region Public class constants
        public const int MAX_PATH = 256;
        public const uint BIF_RETURNONLYFSDIRS = 0x0001;
        public const uint BIF_DONTGOBELOWDOMAIN = 0x0002;
        public const uint BIF_STATUSTEXT = 0x0004;
        public const uint BIF_RETURNFSANCESTORS = 0x0008;
        public const uint BIF_EDITBOX = 0x0010;
        public const uint BIF_VALIDATE = 0x0020;
        public const uint BIF_NEWDIALOGSTYLE = 0x0040;
        public const uint BIF_USENEWUI = (BIF_NEWDIALOGSTYLE | BIF_EDITBOX);
        public const uint BIF_BROWSEINCLUDEURLS = 0x0080;
        public const uint BIF_BROWSEFORCOMPUTER = 0x1000;
        public const uint BIF_BROWSEFORPRINTER = 0x2000;
        public const uint BIF_BROWSEINCLUDEFILES = 0x4000;
        public const uint BIF_SHAREABLE = 0x8000;
        public const uint SHGFI_ICON = 0x000000100;     // get icon
        public const uint SHGFI_DISPLAYNAME = 0x000000200;     // get display name
        public const uint SHGFI_TYPENAME = 0x000000400;     // get type name
        public const uint SHGFI_ATTRIBUTES = 0x000000800;     // get attributes
        public const uint SHGFI_ICONLOCATION = 0x000001000;     // get icon location
        public const uint SHGFI_EXETYPE = 0x000002000;     // return exe type
        public const uint SHGFI_SYSICONINDEX = 0x000004000;     // get system icon index
        public const uint SHGFI_LINKOVERLAY = 0x000008000;     // put a link overlay on icon
        public const uint SHGFI_SELECTED = 0x000010000;     // show icon in selected state
        public const uint SHGFI_ATTR_SPECIFIED = 0x000020000;     // get only specified attributes
        public const uint SHGFI_LARGEICON = 0x000000000;     // get large icon
        public const uint SHGFI_SMALLICON = 0x000000001;     // get small icon
        public const uint SHGFI_OPENICON = 0x000000002;     // get open icon
        public const uint SHGFI_SHELLICONSIZE = 0x000000004;     // get shell size icon
        public const uint SHGFI_PIDL = 0x000000008;     // pszPath is a pidl
        public const uint SHGFI_USEFILEATTRIBUTES = 0x000000010;     // use passed dwFileAttribute
        public const uint SHGFI_ADDOVERLAYS = 0x000000020;     // apply the appropriate overlays
        public const uint SHGFI_OVERLAYINDEX = 0x000000040;     // Get the index of the overlay
        public const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
        public const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;
        #endregion

        #region Public class externs
        [DllImport("Shell32.dll")]
        public static extern IntPtr SHGetFileInfo(
            string pszPath,
            uint dwFileAttributes,
            ref SHFILEINFO psfi,
            uint cbFileInfo,
            uint uFlags
        );
        [DllImport("shell32.dll")]
        public static extern int SHGetKnownFolderPath(
             [MarshalAs(UnmanagedType.LPStruct)] Guid rfid,
             uint dwFlags,
             IntPtr hToken,
             out IntPtr pszPath
        );
        #endregion

        #region Public class structures
        [StructLayout(LayoutKind.Sequential)]
        public struct SHITEMID
        {
            public ushort cb;
            [MarshalAs(UnmanagedType.LPArray)]
            public byte[] abID;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct ITEMIDLIST
        {
            public SHITEMID mkid;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct BROWSEINFO
        {
            public IntPtr hwndOwner;
            public IntPtr pidlRoot;
            public IntPtr pszDisplayName;
            [MarshalAs(UnmanagedType.LPTStr)]
            public string lpszTitle;
            public uint ulFlags;
            public IntPtr lpfn;
            public int lParam;
            public IntPtr iImage;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct SHFILEINFO
        {
            public const int NAMESIZE = 80;
            public IntPtr hIcon;
            public int iIcon;
            public uint dwAttributes;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
            public string szDisplayName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = NAMESIZE)]
            public string szTypeName;
        }
        #endregion

        #region Public classes
        public static class KnownFolder
        {
            public static readonly Guid AddNewPrograms = new Guid("de61d971-5ebc-4f02-a3a9-6c82895e5c04");
            public static readonly Guid AdminTools = new Guid("724EF170-A42D-4FEF-9F26-B60E846FBA4F");
            public static readonly Guid AppUpdates = new Guid("a305ce99-f527-492b-8b1a-7e76fa98d6e4");
            public static readonly Guid CDBurning = new Guid("9E52AB10-F80D-49DF-ACB8-4330F5687855");
            public static readonly Guid ChangeRemovePrograms = new Guid("df7266ac-9274-4867-8d55-3bd661de872d");
            public static readonly Guid CommonAdminTools = new Guid("D0384E7D-BAC3-4797-8F14-CBA229B392B5");
            public static readonly Guid CommonOEMLinks = new Guid("C1BAE2D0-10DF-4334-BEDD-7AA20B227A9D");
            public static readonly Guid CommonPrograms = new Guid("0139D44E-6AFE-49F2-8690-3DAFCAE6FFB8");
            public static readonly Guid CommonStartMenu = new Guid("A4115719-D62E-491D-AA7C-E74B8BE3B067");
            public static readonly Guid CommonStartup = new Guid("82A5EA35-D9CD-47C5-9629-E15D2F714E6E");
            public static readonly Guid CommonTemplates = new Guid("B94237E7-57AC-4347-9151-B08C6C32D1F7");
            public static readonly Guid ComputerFolder = new Guid("0AC0837C-BBF8-452A-850D-79D08E667CA7");
            public static readonly Guid ConflictFolder = new Guid("4bfefb45-347d-4006-a5be-ac0cb0567192");
            public static readonly Guid ConnectionsFolder = new Guid("6F0CD92B-2E97-45D1-88FF-B0D186B8DEDD");
            public static readonly Guid Contacts = new Guid("56784854-C6CB-462b-8169-88E350ACB882");
            public static readonly Guid ControlPanelFolder = new Guid("82A74AEB-AEB4-465C-A014-D097EE346D63");
            public static readonly Guid Cookies = new Guid("2B0F765D-C0E9-4171-908E-08A611B84FF6");
            public static readonly Guid Desktop = new Guid("B4BFCC3A-DB2C-424C-B029-7FE99A87C641");
            public static readonly Guid Documents = new Guid("FDD39AD0-238F-46AF-ADB4-6C85480369C7");
            public static readonly Guid Downloads = new Guid("374DE290-123F-4565-9164-39C4925E467B");
            public static readonly Guid Favorites = new Guid("1777F761-68AD-4D8A-87BD-30B759FA33DD");
            public static readonly Guid Fonts = new Guid("FD228CB7-AE11-4AE3-864C-16F3910AB8FE");
            public static readonly Guid Games = new Guid("CAC52C1A-B53D-4edc-92D7-6B2E8AC19434");
            public static readonly Guid GameTasks = new Guid("054FAE61-4DD8-4787-80B6-090220C4B700");
            public static readonly Guid History = new Guid("D9DC8A3B-B784-432E-A781-5A1130A75963");
            public static readonly Guid InternetCache = new Guid("352481E8-33BE-4251-BA85-6007CAEDCF9D");
            public static readonly Guid InternetFolder = new Guid("4D9F7874-4E0C-4904-967B-40B0D20C3E4B");
            public static readonly Guid Links = new Guid("bfb9d5e0-c6a9-404c-b2b2-ae6db6af4968");
            public static readonly Guid LocalAppData = new Guid("F1B32785-6FBA-4FCF-9D55-7B8E7F157091");
            public static readonly Guid LocalAppDataLow = new Guid("A520A1A4-1780-4FF6-BD18-167343C5AF16");
            public static readonly Guid LocalizedResourcesDir = new Guid("2A00375E-224C-49DE-B8D1-440DF7EF3DDC");
            public static readonly Guid Music = new Guid("4BD8D571-6D19-48D3-BE97-422220080E43");
            public static readonly Guid NetHood = new Guid("C5ABBF53-E17F-4121-8900-86626FC2C973");
            public static readonly Guid NetworkFolder = new Guid("D20BEEC4-5CA8-4905-AE3B-BF251EA09B53");
            public static readonly Guid OriginalImages = new Guid("2C36C0AA-5812-4b87-BFD0-4CD0DFB19B39");
            public static readonly Guid PhotoAlbums = new Guid("69D2CF90-FC33-4FB7-9A0C-EBB0F0FCB43C");
            public static readonly Guid Pictures = new Guid("33E28130-4E1E-4676-835A-98395C3BC3BB");
            public static readonly Guid Playlists = new Guid("DE92C1C7-837F-4F69-A3BB-86E631204A23");
            public static readonly Guid PrintersFolder = new Guid("76FC4E2D-D6AD-4519-A663-37BD56068185");
            public static readonly Guid PrintHood = new Guid("9274BD8D-CFD1-41C3-B35E-B13F55A758F4");
            public static readonly Guid Profile = new Guid("5E6C858F-0E22-4760-9AFE-EA3317B67173");
            public static readonly Guid ProgramData = new Guid("62AB5D82-FDC1-4DC3-A9DD-070D1D495D97");
            public static readonly Guid ProgramFiles = new Guid("905e63b6-c1bf-494e-b29c-65b732d3d21a");
            public static readonly Guid ProgramFilesX64 = new Guid("6D809377-6AF0-444b-8957-A3773F02200E");
            public static readonly Guid ProgramFilesX86 = new Guid("7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E");
            public static readonly Guid ProgramFilesCommon = new Guid("F7F1ED05-9F6D-47A2-AAAE-29D317C6F066");
            public static readonly Guid ProgramFilesCommonX64 = new Guid("6365D5A7-0F0D-45E5-87F6-0DA56B6A4F7D");
            public static readonly Guid ProgramFilesCommonX86 = new Guid("DE974D24-D9C6-4D3E-BF91-F4455120B917");
            public static readonly Guid Programs = new Guid("A77F5D77-2E2B-44C3-A6A2-ABA601054A51");
            public static readonly Guid Public = new Guid("DFDF76A2-C82A-4D63-906A-5644AC457385");
            public static readonly Guid PublicDesktop = new Guid("C4AA340D-F20F-4863-AFEF-F87EF2E6BA25");
            public static readonly Guid PublicDocuments = new Guid("ED4824AF-DCE4-45A8-81E2-FC7965083634");
            public static readonly Guid PublicDownloads = new Guid("3D644C9B-1FB8-4f30-9B45-F670235F79C0");
            public static readonly Guid PublicGameTasks = new Guid("DEBF2536-E1A8-4c59-B6A2-414586476AEA");
            public static readonly Guid PublicMusic = new Guid("3214FAB5-9757-4298-BB61-92A9DEAA44FF");
            public static readonly Guid PublicPictures = new Guid("B6EBFB86-6907-413C-9AF7-4FC2ABF07CC5");
            public static readonly Guid PublicVideos = new Guid("2400183A-6185-49FB-A2D8-4A392A602BA3");
            public static readonly Guid QuickLaunch = new Guid("52a4f021-7b75-48a9-9f6b-4b87a210bc8f");
            public static readonly Guid Recent = new Guid("AE50C081-EBD2-438A-8655-8A092E34987A");
            public static readonly Guid RecycleBinFolder = new Guid("B7534046-3ECB-4C18-BE4E-64CD4CB7D6AC");
            public static readonly Guid ResourceDir = new Guid("8AD10C31-2ADB-4296-A8F7-E4701232C972");
            public static readonly Guid RoamingAppData = new Guid("3EB685DB-65F9-4CF6-A03A-E3EF65729F3D");
            public static readonly Guid SampleMusic = new Guid("B250C668-F57D-4EE1-A63C-290EE7D1AA1F");
            public static readonly Guid SamplePictures = new Guid("C4900540-2379-4C75-844B-64E6FAF8716B");
            public static readonly Guid SamplePlaylists = new Guid("15CA69B3-30EE-49C1-ACE1-6B5EC372AFB5");
            public static readonly Guid SampleVideos = new Guid("859EAD94-2E85-48AD-A71A-0969CB56A6CD");
            public static readonly Guid SavedGames = new Guid("4C5C32FF-BB9D-43b0-B5B4-2D72E54EAAA4");
            public static readonly Guid SavedSearches = new Guid("7d1d3a04-debb-4115-95cf-2f29da2920da");
            public static readonly Guid SEARCH_CSC = new Guid("ee32e446-31ca-4aba-814f-a5ebd2fd6d5e");
            public static readonly Guid SEARCH_MAPI = new Guid("98ec0e18-2098-4d44-8644-66979315a281");
            public static readonly Guid SearchHome = new Guid("190337d1-b8ca-4121-a639-6d472d16972a");
            public static readonly Guid SendTo = new Guid("8983036C-27C0-404B-8F08-102D10DCFD74");
            public static readonly Guid SidebarDefaultParts = new Guid("7B396E54-9EC5-4300-BE0A-2482EBAE1A26");
            public static readonly Guid SidebarParts = new Guid("A75D362E-50FC-4fb7-AC2C-A8BEAA314493");
            public static readonly Guid StartMenu = new Guid("625B53C3-AB48-4EC1-BA1F-A1EF4146FC19");
            public static readonly Guid Startup = new Guid("B97D20BB-F46A-4C97-BA10-5E3608430854");
            public static readonly Guid SyncManagerFolder = new Guid("43668BF8-C14E-49B2-97C9-747784D784B7");
            public static readonly Guid SyncResultsFolder = new Guid("289a9a43-be44-4057-a41b-587a76d7e7f9");
            public static readonly Guid SyncSetupFolder = new Guid("0F214138-B1D3-4a90-BBA9-27CBC0C5389A");
            public static readonly Guid System = new Guid("1AC14E77-02E7-4E5D-B744-2EB1AE5198B7");
            public static readonly Guid SystemX86 = new Guid("D65231B0-B2F1-4857-A4CE-A8E7C6EA7D27");
            public static readonly Guid Templates = new Guid("A63293E8-664E-48DB-A079-DF759E0509F7");
            public static readonly Guid TreeProperties = new Guid("5b3749ad-b49f-49c1-83eb-15370fbd4882");
            public static readonly Guid UserProfiles = new Guid("0762D272-C50A-4BB0-A382-697DCD729B80");
            public static readonly Guid UsersFiles = new Guid("f3ce0f7c-4901-4acc-8648-d5d44b04ef8f");
            public static readonly Guid Videos = new Guid("18989B1D-99B5-455B-841C-AB7C74E4DDFC");
            public static readonly Guid Windows = new Guid("F38BF404-1D43-42F2-9305-67DE0B28FC23");
        }
        #endregion
        #endregion

        #region User32
        #region Public class externs
        [DllImport("User32.dll")]
        public static extern int DestroyIcon(IntPtr hIcon);
        #endregion
        #endregion
    }
}

SpecialFolders.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Diagnostics;
using WinAPIs;

namespace FileFolderWorker
{
    #region Classes used as return values
    public class FolderProperties
    {
        #region Private class variables
        private string m_sPath = "";
        private Icon m_oIcon = null;
        #endregion

        #region Public class properties
        public string Path
        {
            get
            {
                return m_sPath;
            }
            set
            {
                m_sPath = value;
            }
        }

        public Icon Icon
        {
            get
            {
                return m_oIcon;
            }
            set
            {
                m_oIcon = value;
            }
        }
        #endregion
    }
    #endregion

    public static class SpecialFolders
    {
        #region Enums
        public enum FolderList
        {
            None,
            AdminTools,
            ApplicationData,
            CDBurning,
            CommonAdminTools,
            CommonApplicationData,
            CommonDesktopDirectory,
            CommonDocuments,
            CommonMusic,
            CommonOemLinks,
            CommonPictures,
            CommonProgramFiles,
            CommonProgramFilesX86,
            CommonPrograms,
            CommonStartMenu,
            CommonStartup,
            CommonTemplates,
            CommonVideos,
            Cookies,
            Desktop,
            DesktopDirectory,
            Favorites,
            Fonts,
            History,
            InternetCache,
            LocalApplicationData,
            LocalizedResources,
            MyComputer,
            MyDocuments,
            MyMusic,
            MyPictures,
            MyVideos,
            NetworkShortcuts,
            Personal,
            PrinterShortcuts,
            ProgramFiles,
            ProgramFilesX86,
            Programs,
            Recent,
            Resources,
            SendTo,
            StartMenu,
            Startup,
            System,
            SystemX86,
            Templates,
            UserProfile,
            Windows,
            Links,
        }

        public enum FolderType
        {
            None,
            System,
            Custom,
        }
        #endregion

        #region Public static class methods
        public static FolderProperties GetPath(string sFolderKey)
        {
            //Overloaded
            FolderList FolderKey = FolderList.None;
            //Determine the folder type
            switch (sFolderKey)
            {
                #region System's Environment.SpecialFolder elements
                //There was more code here but had to
                //remove due to SO's character limit
                //Full code: http://pastebin.com/dE0Y6tFB
                case "System":
                    FolderKey = FolderList.System;
                    break;
                case "SystemX86":
                    FolderKey = FolderList.SystemX86;
                    break;
                case "Templates":
                    FolderKey = FolderList.Templates;
                    break;
                case "UserProfile":
                    FolderKey = FolderList.UserProfile;
                    break;
                case "Windows":
                    FolderKey = FolderList.Windows;
                    break;
                #endregion

                #region Custom elements
                case "Links":
                    FolderKey = FolderList.Links;
                    break;
                #endregion
            }

            return GetPath(FolderKey);
        }
        public static FolderProperties GetPath(FolderList FolderKey)
        {
            FolderProperties fp = new FolderProperties();
            FolderType sfType = FolderType.None;
            Environment.SpecialFolder sf = Environment.SpecialFolder.AdminTools;

            //Determine the folder type
            switch (FolderKey)
            {
                #region System's Environment.SpecialFolder elements
                //There was more code here but had to
                //remove due to SO's character limit
                //Full code: http://pastebin.com/dE0Y6tFB
                case FolderList.System:
                    sfType = FolderType.System;
                    sf = Environment.SpecialFolder.System;
                    break;
                case FolderList.SystemX86:
                    sfType = FolderType.System;
                    sf = Environment.SpecialFolder.SystemX86;
                    break;
                case FolderList.Templates:
                    sfType = FolderType.System;
                    sf = Environment.SpecialFolder.Templates;
                    break;
                case FolderList.UserProfile:
                    sfType = FolderType.System;
                    sf = Environment.SpecialFolder.UserProfile;
                    break;
                case FolderList.Windows:
                    sfType = FolderType.System;
                    sf = Environment.SpecialFolder.Windows;
                    break;
                #endregion

                #region Custom elements
                case FolderList.Links:
                    sfType = FolderType.Custom;
                    break;
                #endregion
            }

            //Build the folder object's path
            switch (sfType)
            {
                case FolderType.System:
                    fp.Path = Environment.GetFolderPath(sf);
                    break;
                case FolderType.Custom:
                    fp.Path = "LINKS";
                    fp.Path = GetSpecialFolderPath(WinAPI.KnownFolder.Links);
                    break;
            }

            //Build the folder object's icon
            //more to be done here...

            return fp;
        }

        public static void DebugShowAllFolders()
        {
            foreach (SpecialFolders.FolderList sf in (SpecialFolders.FolderList[])Enum.GetValues(typeof(SpecialFolders.FolderList)))
            {
                Debug.WriteLine("SpecialFolder: " + sf + "\n  Path: " + SpecialFolders.GetPath(sf.ToString()).Path + "\n");
            }
        }

        public static string GetSpecialFolderPath(Guid kFolderID)
        {
            string sRet = "";

            IntPtr pPath;
            if (WinAPI.SHGetKnownFolderPath(kFolderID, 0, IntPtr.Zero, out pPath) == 0)
            {
                sRet = System.Runtime.InteropServices.Marshal.PtrToStringUni(pPath);
                System.Runtime.InteropServices.Marshal.FreeCoTaskMem(pPath);
            }

            return sRet;
        }
        #endregion
    }
}



回答2:


The only applicable environmental variable would be %userprofile% which replaces all but the links sub-folder in your path:

%userprofile%\Links

I think there's a registry key containing the full path if you want to read that as well, I'll look around and see if I can remember where it's at.

Edit

I can confirm @Malk's comment (though I can't comment yet) the full path is stored in Registry key HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders{BFB9D5E0-C6A9-404C-B2B2-AE6DB6AF4968}




回答3:


Environment.GetFolderPath actually calls SHGetFolderPath. The SpecialFolder enums contains several folders under user profile folder but not the Links folder. To get the Links folder you need to use new API called SHGetKnownFolderPath. Here's the link from MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/bb776911(v=vs.85).aspx

The Links folder's guid is {bfb9d5e0-c6a9-404c-b2b2-ae6db6af4968}. You can find it here: http://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx

However it seems the SHGetKnownFolderPath is not available in the built-in .net class library. You have to P/Invoke it.

EDIT: To get the icon, you can look for the desktop.ini file in the folder. It contains information the DLL and resource id used as the icon of the folder.



来源:https://stackoverflow.com/questions/27910592/get-path-to-links-aka-favorites-folder

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!