使用 C# 将 *.lnk 文件固定到 Windows 7 任务栏

发布于 2024-11-27 10:42:21 字数 1333 浏览 2 评论 0 原文

即使在 Windows 7 中以编程方式固定图标似乎也是不允许的(就像这里所说的:http://msdn.microsoft.com/en-us/library/dd378460(v=VS.85).aspx),有一些方法通过使用一些 VB 脚本来完成此操作。 有人在 C# 中找到了一种方法,如下所示:

private static void PinUnpinTaskBar(string filePath, bool pin)
{
     if (!File.Exists(filePath)) throw new FileNotFoundException(filePath);

     // create the shell application object
     dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));

     string path = Path.GetDirectoryName(filePath);
     string fileName = Path.GetFileName(filePath);

     dynamic directory = shellApplication.NameSpace(path);
     dynamic link = directory.ParseName(fileName);

     dynamic verbs = link.Verbs();
     for (int i = 0; i < verbs.Count(); i++)
        {
            dynamic verb = verbs.Item(i);
            string verbName = verb.Name.Replace(@"&", string.Empty).ToLower();

            if ((pin && verbName.Equals("pin to taskbar")) || (!pin && verbName.Equals("unpin from taskbar")))
            {

                verb.DoIt();
            }
        }

        shellApplication = null;
}

可以看出,代码利用了 .NET Framework 4.0 功能。我想问的问题是:这个函数是否可以进行转换,以便它可以做出同样的事情,但只使用 3.5 框架?有什么想法吗?

Even the programmatic pinning of icons in Windows 7 seems it's not permitted (like it says here: http://msdn.microsoft.com/en-us/library/dd378460(v=VS.85).aspx), there are some methods for doing this by using some VB scripts.
Someone found a way of doing this in C# like this:

private static void PinUnpinTaskBar(string filePath, bool pin)
{
     if (!File.Exists(filePath)) throw new FileNotFoundException(filePath);

     // create the shell application object
     dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));

     string path = Path.GetDirectoryName(filePath);
     string fileName = Path.GetFileName(filePath);

     dynamic directory = shellApplication.NameSpace(path);
     dynamic link = directory.ParseName(fileName);

     dynamic verbs = link.Verbs();
     for (int i = 0; i < verbs.Count(); i++)
        {
            dynamic verb = verbs.Item(i);
            string verbName = verb.Name.Replace(@"&", string.Empty).ToLower();

            if ((pin && verbName.Equals("pin to taskbar")) || (!pin && verbName.Equals("unpin from taskbar")))
            {

                verb.DoIt();
            }
        }

        shellApplication = null;
}

As can be seen, the code makes use of .NET Framework 4.0 features. The question I want to ask is: can this function be transformed so it would make the same thing, but using just 3.5 Framework? Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

好菇凉咱不稀罕他 2024-12-04 10:42:21

简单...

    private static void PinUnpinTaskBar(string filePath, bool pin) {
        if (!File.Exists(filePath)) throw new FileNotFoundException(filePath);

        // create the shell application object
        Shell shellApplication = new ShellClass();

        string path = Path.GetDirectoryName(filePath);
        string fileName = Path.GetFileName(filePath);

        Folder directory = shellApplication.NameSpace(path);
        FolderItem link = directory.ParseName(fileName);

        FolderItemVerbs verbs = link.Verbs();
        for (int i = 0; i < verbs.Count; i++) {
            FolderItemVerb verb = verbs.Item(i);
            string verbName = verb.Name.Replace(@"&", string.Empty).ToLower();

            if ((pin && verbName.Equals("pin to taskbar")) || (!pin && verbName.Equals("unpin from taskbar"))) {

                verb.DoIt();
            }
        }

        shellApplication = null;
    }

一定要添加对“Microsoft Shell Controls And Automation”的 COM 引用。

如果您想保留使用 Activator.CreateInstance 的现有方法,这样您就不必拥有额外的 COM 互操作 DLL,那么您必须使用反射。但这会使代码变得更加难看。

Simple...

    private static void PinUnpinTaskBar(string filePath, bool pin) {
        if (!File.Exists(filePath)) throw new FileNotFoundException(filePath);

        // create the shell application object
        Shell shellApplication = new ShellClass();

        string path = Path.GetDirectoryName(filePath);
        string fileName = Path.GetFileName(filePath);

        Folder directory = shellApplication.NameSpace(path);
        FolderItem link = directory.ParseName(fileName);

        FolderItemVerbs verbs = link.Verbs();
        for (int i = 0; i < verbs.Count; i++) {
            FolderItemVerb verb = verbs.Item(i);
            string verbName = verb.Name.Replace(@"&", string.Empty).ToLower();

            if ((pin && verbName.Equals("pin to taskbar")) || (!pin && verbName.Equals("unpin from taskbar"))) {

                verb.DoIt();
            }
        }

        shellApplication = null;
    }

Be sure to add a COM reference to "Microsoft Shell Controls And Automation".

If you want to keep the existing method of using Activator.CreateInstance so you don't have to have the extra COM interop DLL then you'll have to use reflection. But that would make the code a lot uglier.

酒绊 2024-12-04 10:42:21

无论 Windows 用户使用哪种本地化:

        int MAX_PATH = 255;
        var actionIndex = pin ? 5386 : 5387; // 5386 is the DLL index for"Pin to Tas&kbar", ref. http://www.win7dll.info/shell32_dll.html
        StringBuilder szPinToStartLocalized = new StringBuilder(MAX_PATH);
        IntPtr hShell32 = LoadLibrary("Shell32.dll");
        LoadString(hShell32, (uint)actionIndex, szPinToStartLocalized, MAX_PATH);
        string localizedVerb = szPinToStartLocalized.ToString();

        // create the shell application object
        dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));

        string path = Path.GetDirectoryName(filePath);
        string fileName = Path.GetFileName(filePath);

        dynamic directory = shellApplication.NameSpace(path);
        dynamic link = directory.ParseName(fileName);

        dynamic verbs = link.Verbs();
        for (int i = 0; i < verbs.Count(); i++)
        {
            dynamic verb = verbs.Item(i);

            if ((pin && verb.Name.Equals(localizedVerb)) || (!pin && verb.Name.Equals(localizedVerb)))
            {
                verb.DoIt();
                break;
            }
        }

regardless what localization the Windows user was using:

        int MAX_PATH = 255;
        var actionIndex = pin ? 5386 : 5387; // 5386 is the DLL index for"Pin to Tas&kbar", ref. http://www.win7dll.info/shell32_dll.html
        StringBuilder szPinToStartLocalized = new StringBuilder(MAX_PATH);
        IntPtr hShell32 = LoadLibrary("Shell32.dll");
        LoadString(hShell32, (uint)actionIndex, szPinToStartLocalized, MAX_PATH);
        string localizedVerb = szPinToStartLocalized.ToString();

        // create the shell application object
        dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));

        string path = Path.GetDirectoryName(filePath);
        string fileName = Path.GetFileName(filePath);

        dynamic directory = shellApplication.NameSpace(path);
        dynamic link = directory.ParseName(fileName);

        dynamic verbs = link.Verbs();
        for (int i = 0; i < verbs.Count(); i++)
        {
            dynamic verb = verbs.Item(i);

            if ((pin && verb.Name.Equals(localizedVerb)) || (!pin && verb.Name.Equals(localizedVerb)))
            {
                verb.DoIt();
                break;
            }
        }
屋顶上的小猫咪 2024-12-04 10:42:21

在Windows 10中上述方法不起作用。 “固定到任务栏”动词不会出现在程序的列表中,仅出现在资源管理器中。要使其在 Windows 10 中运行,您有两种选择。要么将您的程序重命名为 explorer.exe,要么您必须欺骗该对象,让其认为您的程序名为 explorer.exe。您必须找到 PEB 并更改图像路径字段。我在此处写了一篇关于如何做到这一点的文章。

In windows 10 the above methods don't work. The "Pin to Taskbar" verb doesn't appear in the list in your program, only in explorer. For this to work in windows 10, you have two options. Either rename you program to explorer.exe, or you have to fool the object in to thinking your program is called explorer.exe. You have to find the PEB and change the Image Path Field. I wrote a post here on how to do it.

仙女山的月亮 2024-12-04 10:42:21

使用秋季创意者更新(内部版本 16299 或更高版本)更新在 Windows 10 上运行的 UWP 应用:

您可以通过编程方式将自己的应用固定到任务栏,就像您可以将应用固定到“开始”菜单一样。您还可以检查您的应用当前是否已固定,以及任务栏是否允许固定。

您可以直接访问 TaskbarManager API,如 MS 文档中描述

我想使用 WinForms 应用程序执行此操作,但似乎行不通,因为我无法引用 Windows.Foundation API。

Update for UWP apps running on Windows 10 with the Fall Creators Update (Build 16299 or higher):

You can programmatically pin your own app to the taskbar, just like you can pin your app to the Start menu. And you can check whether your app is currently pinned, and whether the taskbar allows pinning.

You can access the TaskbarManager API directly, as described in MS docs.

I wanted to do this with a WinForms application, but it does not seem like it is going to work because I cannot reference the Windows.Foundation APIs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文