Apparently Microsoft has (sort of) replaced the "Favorites" Windows explorer item with the Quick Access item. But I haven't been able to find a way to programmatically add folders to it (neither on Google not MSDN). Is there no way to do this yet?
-
2I do not know the answer, sorry, but [I would not be surprised](http://blogs.msdn.com/b/oldnewthing/archive/2003/09/03/54760.aspx) [if there was no such interface](http://blogs.msdn.com/b/oldnewthing/archive/2014/10/29/10568120.aspx). Good luck. – andlabs May 11 '15 at 21:09
-
You are expected not to do this. – David Heffernan Sep 04 '15 at 16:37
-
Please update the accepted answer now that this is possible via powershell. See @YohanNey's answer: https://stackoverflow.com/a/43658032/4233593 – Jeff Puckett Nov 01 '17 at 16:18
11 Answers
There is a simple way to do it in powershell (at least) :
$o = new-object -com shell.application
$o.Namespace('c:\My Folder').Self.InvokeVerb("pintohome")
Hope it helps.

- 37,464
- 17
- 118
- 167

- 546
- 5
- 2
-
1This worked, but you have to make sure that you change `C:\My Folder` to a location that exists on your system. – Chris Magnuson Jun 02 '17 at 14:27
-
1This works with paths, but not with Libraries. If I replace c:/my folder with '%appdata%\Microsoft\Windows\Libraries\myLibrary.library-ms' it does not work, any idea? – user1892410 Aug 09 '17 at 11:50
-
1
-
Thanks for that. It works, but I do get a strange message back. This is on Windows 11. "[38820:ShellIpcClient] simple_message_loop.cc:127:Run Run called on MessageLoop that's already been Quit!" – NER1808 Jan 31 '22 at 16:17
-
It is possible to give a name to the entry? Different from the folder name like defining a handy name... – Peter Jun 21 '22 at 13:48
-
@user1892410 try this: $o.Namespace("$env:APPDATA\Microsoft\Windows\Libraries") – Jimmy He Jul 11 '23 at 23:47
Yohan Ney's answer for pinning an item is correct. To unpin an item you can do this:
$QuickAccess = New-Object -ComObject shell.application
($QuickAccess.Namespace("shell:::{679f85cb-0220-4080-b29b-5540cc05aab6}").Items() | where {$_.Path -eq "C:\Temp"}).InvokeVerb("unpinfromhome")
Here's a script I wrote to make pin/unpin a little easier:
https://gallery.technet.microsoft.com/Set-QuickAccess-117e9a89

- 141
- 1
- 3
-
-
https://gallery.technet.microsoft.com/Set-QuickAccess-117e9a89 not found – Kiquenet Aug 13 '22 at 12:41
-
-
@Kiquenet is the shell id for quick access, if you paste shell:{67... from the example above into the address bar it will lead you to quick access links list. – JasonXA Jan 12 '23 at 00:24
Maybe it will help someone until MS releases an API. I ran procmon and it seems that these registry keys are involved
Pin to Quick access:
HKEY_CLASSES_ROOT\Folder\shell\pintohome
When unpin:
HKEY_CLASSES_ROOT\PinnedFrequentPlace\shell\unpinfromhome\command
Also this resource is used when pinning: (EDIT1: can't find it any longer..)
AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations\{SOME_SORT_OF_GUID}.automaticDestinations-ms
You can try opening it with 7-zip, there are several files in there which fit the destination
EDIT2: I found running this in the 'Run' opens up Quick access:
shell:::{679F85CB-0220-4080-B29B-5540CC05AAB6}

- 484
- 1
- 3
- 16
I got an answer here:
Windows 10 - Programmatically use Quick Access
Apparently, it's not possible yet, but a proposition for such an API has been made.

- 555,201
- 31
- 458
- 770

- 2,694
- 6
- 28
- 50
-
This is now possible via powershell, see @YohanNey's answer: https://stackoverflow.com/a/43658032/4233593 – Jeff Puckett Nov 01 '17 at 16:19
I like Johan's answer but I added a little bit to make not remove some of the items that were already in there. I had a ton pinned in there by accident I must have selected pin folder or something to quick access.
$QuickAccess = New-Object -ComObject shell.application
$okItems = @("Desktop","Downloads","Documents","Pictures","iCloud Photos","iCloud Drive","PhpstormProjects","Wallpapers 5","Videos", "Schedules for testing")
($QuickAccess.Namespace("shell:::{679f85cb-0220-4080-b29b-5540cc05aab6}").Items() | where {$_.name -notin $okItems}).InvokeVerb("unpinfromhome");

- 235
- 2
- 6
Building on what others have said... This allows you to remove all pinned folders (not just all/recent folders/items):
$o = new-object -com shell.application
$($o.Namespace("shell:::{679f85cb-0220-4080-b29b-5540cc05aab6}").Items() | where { $_.IsFolder -eq "True" -and ($($_.Verbs() | Where-Object {$_.Name -in "Unpin from Quick access"}) -ne $null)}).InvokeVerb("unpinfromhome")
I needed this so I could backup / restore my list of Quick Access links quickly. So I put this at the top of my script (to remove all pinned items, then the rest of the script re-adds them. This ensures the order is correct.
And yes, I'm sure there's a better syntax for the above code.

- 31
- 1
- 2
EDIT: After further investigation, I have realized Quick Access contains two "sections". One is Pinned Items, and the other is Frequent Folders. For some reason, Music
and Videos
come by default on the second section (at least in 1909), unlike the rest (Desktop/Downloads/Documents/Pictures). So the verb to invoke changes from unpinfromhome
to removefromhome
(defined in HKEY_CLASSES_ROOT\FrequentPlace
, CLSID: {b918dbc4-162c-43e5-85bf-19059a776e9e}
). In PowerShell:
$Unpin = @("$env:USERPROFILE\Videos","$env:USERPROFILE\Music")
$qa = New-Object -ComObject shell.application
$ob = $qa.Namespace('shell:::{679f85cb-0220-4080-b29b-5540cc05aab6}').Items() | ? {$_.Path -in $Unpin}
$ob.InvokeVerb('removefromhome')
In Windows 1909, you can't unpin the Music
or Videos
links from Quick Access with the proposed PowerShell solution. It seems they're special because they don't include the "pin" icon, unlike the rest.
The solution is to pin and unpin them. I don't know much about the Windows API or PowerShell so there may be a less convoluted way.
$Unpin = @("$env:USERPROFILE\Videos","$env:USERPROFILE\Music")
$qa = New-Object -ComObject shell.application
ForEach ($dir in $Unpin) { $qa.Namespace($dir).Self.InvokeVerb('pintohome') }
$ob = $qa.Namespace('shell:::{679f85cb-0220-4080-b29b-5540cc05aab6}').Items() | ? {$_.Path -in $Unpin}
$ob.InvokeVerb('unpinfromhome')
Another way is renaming f01b4d95cf55d32a.automaticDestinations-ms
, then logging off/rebooting so that it's recreated. But I don't know if it has side effects. Batch script:
:: f01b4d95cf55d32a => Frequent Folders
:: 5f7b5f1e01b83767 => Recent Files
rename "%APPDATA%\Microsoft\Windows\Recent\AutomaticDestinations\f01b4d95cf55d32a.automaticDestinations-ms" f01b4d95cf55d32a.automaticDestinations-ms.bak

- 95
- 6
void PinToHome(const std::wstring& folder)
{
ShellExecute(0, L"pintohome", folder.c_str(), L"", L"", SW_HIDE);
}
that was the easy part, still unable to do an unpinfromhome

- 213
- 2
- 9
I was able to get this to work in C# using shell32 based on the information in this post and some info on shell32 from this post https://stackoverflow.com/a/19035049
You need to add a reference to "Microsoft Shell Controls and Automation".
This will add a link
Type shellAppType = Type.GetTypeFromProgID("Shell.Application");
Object shell = Activator.CreateInstance(shellAppType);
Shell32.Folder2 f = (Shell32.Folder2)shellAppType.InvokeMember("NameSpace", System.Reflection.BindingFlags.InvokeMethod, null, shell, new object[] { "C:\\temp" });
f.Self.InvokeVerb("pintohome");
This will remove a link by name
Type shellAppType = Type.GetTypeFromProgID("Shell.Application");
Object shell = Activator.CreateInstance(shellAppType);
Shell32.Folder2 f2 = (Shell32.Folder2)shellAppType.InvokeMember("NameSpace", System.Reflection.BindingFlags.InvokeMethod, null, shell, new object[] { "shell:::{679f85cb-0220-4080-b29b-5540cc05aab6}" });
Console.WriteLine("item count: " + f2.Items().Count);
foreach (FolderItem fi in f2.Items())
{
Console.WriteLine(fi.Name);
if (fi.Name == "temp")
{
((FolderItem)fi).InvokeVerb("unpinfromhome");
}
}

- 71
- 4
I'd like to share my successful approach to pinning a folder to the Quick Access section in Python. After exploring different methods suggested by others, I discovered a solution that directly utilizes the PowerShell console. By running a small script, the folder's path can be added to the Quick Access section in File Explorer. I want to acknowledge and thank those who shared similar methods earlier, as their contributions helped me achieve the desired functionality.
import subprocess
#pins the given directory to "Quick Access" in the "File Explorer"
def pin_to_quick_access(path):
ps_command = f"""
$o = new-object -com shell.application
$o.Namespace('{path}').Self.InvokeVerb('pintohome')
"""
subprocess.run(["powershell", "-Command", ps_command], capture_output=True)
pin_to_quick_access('c:\\My Folder Path')

- 11
- 1
For those that work with .NET Core:
Sadly, you cannot include a reference to "Microsoft Shell Controls and Automation" in the build-process.
But you can instead use dynamic, and omit the reference:
public static void PinToQuickAccess(string folder)
{
// You need to include "Microsoft Shell Controls and Automation" reference
// Cannot include reference in .NET Core
System.Type shellAppType = System.Type.GetTypeFromProgID("Shell.Application");
object shell = System.Activator.CreateInstance(shellAppType);
// Shell32.Folder2 f = (Shell32.Folder2)shellAppType.InvokeMember("NameSpace", System.Reflection.BindingFlags.InvokeMethod, null, shell, new object[] { folder });
dynamic f = shellAppType.InvokeMember("NameSpace", System.Reflection.BindingFlags.InvokeMethod, null, shell, new object[] { folder });
f.Self.InvokeVerb("pintohome");
}
And to unpin:
public static void UnpinFromQuickAccess(string folder)
{
// You need to include "Microsoft Shell Controls and Automation" reference
System.Type shellAppType = System.Type.GetTypeFromProgID("Shell.Application");
object shell = System.Activator.CreateInstance(shellAppType);
// Shell32.Folder2 f2 = (Shell32.Folder2)shellAppType.InvokeMember("NameSpace", System.Reflection.BindingFlags.InvokeMethod, null, shell, new object[] { "shell:::{679f85cb-0220-4080-b29b-5540cc05aab6}" });
dynamic f2 = shellAppType.InvokeMember("NameSpace", System.Reflection.BindingFlags.InvokeMethod, null, shell, new object[] { "shell:::{679f85cb-0220-4080-b29b-5540cc05aab6}" });
foreach (dynamic fi in f2.Items())
{
if (string.Equals(fi.Path, folder))
{
fi.InvokeVerb("unpinfromhome");
}
}
}

- 78,642
- 66
- 377
- 442