是否可以在资源管理器窗口中以编程方式将文件夹添加到 Windows 10 快速访问面板?

Posted

技术标签:

【中文标题】是否可以在资源管理器窗口中以编程方式将文件夹添加到 Windows 10 快速访问面板?【英文标题】:Is it possible programmatically add folders to the Windows 10 Quick Access panel in the explorer window? 【发布时间】:2015-07-15 02:35:41 【问题描述】:

显然,微软已经(在某种程度上)用快速访问项目替换了“收藏夹”Windows 资源管理器项目。但是我还没有找到一种以编程方式向其中添加文件夹的方法(在 Google 和 MSDN 上都没有)。有没有办法做到这一点?

【问题讨论】:

我不知道答案,对不起,但是I would not be surprisedif there was no such interface。祝你好运。 你不应该这样做。 请更新已接受的答案,因为这可以通过 powershell 实现。请参阅@YohanNey 的回答:***.com/a/43658032/4233593 【参考方案1】:

在powershell中有一个简单的方法(至少):

$o = new-object -com shell.application
$o.Namespace('c:\My Folder').Self.InvokeVerb("pintohome")

希望对你有帮助。

【讨论】:

这行得通,但您必须确保将 C:\My Folder 更改为系统上存在的位置。 这适用于路径,但不适用于库。如果我将 c:/my 文件夹替换为 '%appdata%\Microsoft\Windows\Libraries\myLibrary.library-ms' 它不起作用,知道吗? 作为其他用户有什么想法吗? (即 ps-remoting ) 谢谢。它有效,但我确实收到了一条奇怪的消息。这是在 Windows 11 上。“[38820:ShellIpcClient] simple_message_loop.cc:127:Run Run 调用了已经退出的 MessageLoop!”【参考方案2】:

Yohan Ney 对固定项目的回答是正确的。要取消固定项目,您可以这样做:

$QuickAccess = New-Object -ComObject shell.application 
($QuickAccess.Namespace("shell:::679f85cb-0220-4080-b29b-5540cc05aab6").Items() | where $_.Path -eq "C:\Temp").InvokeVerb("unpinfromhome")

这是我编写的一个脚本,可以让 pin/unpin 更容易一些:

https://gallery.technet.microsoft.com/Set-QuickAccess-117e9a89

【讨论】:

【参考方案3】:

也许在 MS 发布 API 之前它会对某人有所帮助。 我跑了procmon,似乎涉及到这些注册表项

固定到快速访问:

HKEY_CLASSES_ROOT\Folder\shell\pintohome

取消固定时:

HKEY_CLASSES_ROOT\PinnedFrequentPlace\shell\unpinfromhome\command

固定时也使用此资源:(EDIT1:再也找不到它了..)

AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations\SOME_SORT_OF_GUID.automaticDestinations-ms

你可以尝试用 7-zip 打开它,里面有几个适合目标的文件

EDIT2:我发现在“运行”中运行它会打开快速访问:

shell:::679F85CB-0220-4080-B29B-5540CC05AAB6

【讨论】:

【参考方案4】:

我在这里得到了答案:

Windows 10 - Programmatically use Quick Access

显然,目前还不可能,但已经提出了这样一个 API 的提议。

【讨论】:

现在可以通过 powershell 实现,请参阅@YohanNey 的回答:***.com/a/43658032/4233593【参考方案5】:

我喜欢 Johan 的回答,但我添加了一些内容,以免删除一些已经存在的项目。我不小心在里面钉了很多东西,我一定是选择了 pin 文件夹或其他东西来快速访问。

$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");

【讨论】:

【参考方案6】:
void PinToHome(const std::wstring& folder)

    ShellExecute(0, L"pintohome", folder.c_str(), L"", L"", SW_HIDE);

这是最简单的部分,仍然无法从家里取消固定

【讨论】:

【参考方案7】:

基于其他人所说...这允许您删除所有固定文件夹(不仅仅是所有/最近的文件夹/项目):

$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")

我需要这个,以便我可以快速备份/恢复我的快速访问链接列表。所以我把它放在我的脚本的顶部(删除所有固定的项目,然后脚本的其余部分重新添加它们。这样可以确保顺序正确。

是的,我确信上面的代码有更好的语法。

【讨论】:

【参考方案8】:

根据这篇文章中的信息以及来自这篇文章https://***.com/a/19035049的一些关于 shell32 的信息,我能够使用 shell32 在 C# 中使用它。

您需要添加对“Microsoft Shell 控件和自动化”的引用。

这将添加一个链接

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");

这将按名称删除链接

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");
    

【讨论】:

【参考方案9】:

编辑:经过进一步调查,我意识到快速访问包含两个“部分”。一个是固定项目,另一个是常用文件夹。出于某种原因,MusicVideos 默认出现在第二部分(至少在 1909 年),与其他部分(桌面/下载/文档/图片)不同。所以调用的动词从unpinfromhome 变为removefromhome(定义在HKEY_CLASSES_ROOT\FrequentPlace,CLSID:b918dbc4-162c-43e5-85bf-19059a776e9e)。在 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')

在 Windows 1909 中,您无法使用建议的 PowerShell 解决方案从快速访问中取消固定 MusicVideos 链接。看起来它们很特别,因为它们不像其他的那样包含“图钉”图标。

解决方案是固定和取消固定它们。我对 Windows API 或 PowerShell 了解不多,因此可能有一种不那么复杂的方式。

$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')

另一种方法是重命名f01b4d95cf55d32a.automaticDestinations-ms,然后注销/重新启动以重新创建它。但是不知道有没有副作用。批处理脚本:

:: f01b4d95cf55d32a => Frequent Folders
:: 5f7b5f1e01b83767 => Recent Files
rename "%APPDATA%\Microsoft\Windows\Recent\AutomaticDestinations\f01b4d95cf55d32a.automaticDestinations-ms" f01b4d95cf55d32a.automaticDestinations-ms.bak

【讨论】:

【参考方案10】:

对于那些使用 .NET Core 的人:

遗憾的是,您不能在构建过程中包含对“Microsoft Shell 控件和自动化”的引用。

但您可以改为使用动态,并省略引用:

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");

然后取消固定:

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");
        
    

【讨论】:

以上是关于是否可以在资源管理器窗口中以编程方式将文件夹添加到 Windows 10 快速访问面板?的主要内容,如果未能解决你的问题,请参考以下文章

在recyclerview android中以编程方式更改布局管理器

在 WordPress 中以编程方式将文件上传给用户

是否可以在 android 中以编程方式创建 string.xml 文件?

如何在 iPhone 中以编程方式在 plist 文件中添加多个数组

在 Woocommerce 管理订单编辑页面中以编程方式添加自定义订单备注

如何在 ios 4 中以编程方式将图像数组添加到 Imageview?