【问题标题】:Pin *.lnk file to Windows 7 Taskbar using C#使用 C# 将 *.lnk 文件固定到 Windows 7 任务栏
【发布时间】:2011-10-15 20:55:33
【问题描述】:

即使在 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 框架吗?有什么想法吗?

【问题讨论】:

标签: c# windows-7 taskbar


【解决方案1】:

使用 Fall Creators Update(Build 16299 或更高版本)在 Windows 10 上运行的 UWP 应用的更新:

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

您可以直接访问TaskbarManager API,如described in MS docs

我想使用 WinForms 应用程序来执行此操作,但它似乎无法正常工作,因为我无法引用 Windows.Foundation API。

【讨论】:

    【解决方案2】:

    在 Windows 10 中,上述方法不起作用。 “固定到任务栏”动词不会出现在程序的列表中,只会出现在资源管理器中。要使其在 Windows 10 中运行,您有两个选择。要么将您的程序重命名为 explorer.exe,要么您必须欺骗对象以为您的程序称为 explorer.exe。您必须找到PEB 并更改图像路径字段。我写了一个帖子here 说明如何做到这一点。

    【讨论】:

      【解决方案3】:

      无论 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;
                  }
              }
      

      【讨论】:

        【解决方案4】:

        简单...

            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 控件和自动化”的 COM 引用。

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

        【讨论】:

        • 但这实在是太老套了。必须有更好的方法!
        • @James,这似乎已针对 Windows 10 进行了更改。verbName 只是空白,无法调用“DoIt”方法。微软会阻止它吗?
        • @Tsury 是的,微软阻止了它。但是有一些方法可以解决这个问题,请参阅我的answer
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-04-12
        • 2010-12-22
        • 2012-03-09
        • 2010-11-30
        • 1970-01-01
        • 2010-11-01
        • 2010-11-18
        相关资源
        最近更新 更多