【问题标题】:Get target of shortcut folder获取快捷方式文件夹的目标
【发布时间】:2012-02-23 13:37:39
【问题描述】:

如何获取快捷方式文件夹的目录目标?我到处搜索,只找到快捷方式文件的目标。

【问题讨论】:

标签: c# directory target shortcut


【解决方案1】:

我认为您需要使用 COM 并添加对“Microsoft Shell 控制和自动化”的引用,如this blog post 中所述:

这是一个使用那里提供的代码的示例:

namespace Shortcut
{
    using System;
    using System.Diagnostics;
    using System.IO;
    using Shell32;

    class Program
    {
        public static string GetShortcutTargetFile(string shortcutFilename)
        {
            string pathOnly = System.IO.Path.GetDirectoryName(shortcutFilename);
            string filenameOnly = System.IO.Path.GetFileName(shortcutFilename);

            Shell shell = new Shell();
            Folder folder = shell.NameSpace(pathOnly);
            FolderItem folderItem = folder.ParseName(filenameOnly);
            if (folderItem != null)
            {
                Shell32.ShellLinkObject link = (Shell32.ShellLinkObject)folderItem.GetLink;
                return link.Path;
            }

            return string.Empty;
        }

        static void Main(string[] args)
        {
            const string path = @"C:\link to foobar.lnk";
            Console.WriteLine(GetShortcutTargetFile(path));
        }
    }
}

【讨论】:

  • 谢谢!现在我只需要找出如何以编程方式查找快捷方式文件夹:)
  • 我在 Windows 7 64 位上工作,它无法找到安装在 C:\Program Files\Oracle\VirtualBoxOSX 中的 VirtualBox 的快捷方式。它不断将目标返回到C:\Program Files (x86)\Oracle\VirtualBoxOSX\VirtualBox.exe。对此行为有何解释?
  • 在此方法中使用 Shell32 仅允许在单线程应用程序中使用。您必须在主入口点中包含 [STAThread]。您将在使用此代码进行单元测试时遇到异常,因为单元测试不允许 STAThread。见answer。还有在单元测试中运行此代码的解决方案,请参阅haacked.com/archive/2014/11/20/xunit-and-sta
【解决方案2】:

在windows 10中需要这样做,首先将COM引用添加到“Microsoft Shell Control And Automation”

// new way for windows 10
string targetname;
string pathOnly = System.IO.Path.GetDirectoryName(LnkFileName);
string filenameOnly = System.IO.Path.GetFileName(LnkFileName);

Shell shell = new Shell();
Shell32.Folder folder = shell.NameSpace(pathOnly);
FolderItem folderItem = folder.ParseName(filenameOnly);
if (folderItem != null) {
  Shell32.ShellLinkObject link = (Shell32.ShellLinkObject)folderItem.GetLink;
  targetname = link.Target.Path;  // <-- main difference
  if (targetname.StartsWith("{")) { // it is prefixed with {54A35DE2-guid-for-program-files-x86-QZ32BP4}
    int endguid = targetname.IndexOf("}");
    if (endguid > 0) {
      targetname = "C:\\program files (x86)" + targetname.Substring(endguid + 1);
  }
}

【讨论】:

  • Windows 10 是一块垃圾。这可能就是为什么 Windows 10 上的链接存在如此多问题的原因。
【解决方案3】:

如果你不想使用依赖,你可以使用https://blez.wordpress.com/2013/02/18/get-file-shortcuts-target-with-c/ 但是 lnk 格式是无证的,所以只有在你了解风险的情况下才这样做。

【讨论】:

    【解决方案4】:

    如果您想在桌面上找到具有快捷方式的应用程序路径,我使用的一种简单方法如下:

    Process.GetCurrentProcess().MainModule.FileName.Substring(0, Process.GetCurrentProcess().MainModule.FileName.LastIndexOf("\\")
    

    此代码返回任何正在运行的 exe 路径,无论是谁请求的文件

    【讨论】:

      【解决方案5】:

      获取我使用的链接路径的更简单方法是:

      private static string LnkToFile(string fileLink)
      {
          string link = File.ReadAllText(fileLink);
          int i1 = link.IndexOf("DATA\0");
          if (i1 < 0)
              return null;
          i1 += 5;
          int i2 = link.IndexOf("\0", i1);
          if (i2 < 0)
              return link.Substring(i1);
          else
              return link.Substring(i1, i2 - i1);
      }
      

      但如果 lnk 文件格式发生变化,它当然会中断。

      【讨论】:

      • 这仅适用于琐碎的 *.lnk 文件 - 它不适用于由 Windows Installer 创建的 *.lnk 文件(无论如何都不指向文件)以及某些其他类型的 @ 987654325@ 不将路径存储为单个字符串的文件 - 不幸的是,二进制文件格式有点复杂:docs.microsoft.com/en-us/openspecs/windows_protocols/ms-shllink/…
      • 在我的情况下不起作用,该函数已经在我的 .lnk 文件上返回 null。
      【解决方案6】:

      感谢Mohsen.Sharify's answer我得到了更简洁的代码:

      var fileName = Process.GetCurrentProcess().MainModule.FileName;
      var folderName = Path.Combine(fileName, ".."); //origin folder
      

      【讨论】:

        【解决方案7】:
        public static string GetLnkTarget(string lnkPath)
        {
            var shl = new Shell();
            var dir = shl.NameSpace(Path.GetDirectoryName(lnkPath));
            var itm = dir.Items().Item(Path.GetFileName(lnkPath));
            var lnk = (ShellLinkObject)itm.GetLink;
        
            if (!File.Exists(lnk.Path)){
               return lnk.Path.Replace("Program Files (x86)", "Program Files");
            }
            else{
               return lnk.Path;
            }
        }
        

        【讨论】:

        • 请解释您的解决方案。没有解释且只有代码的答案会被标记为省力。
        • 请添加更多详细信息以扩展您的答案,例如工作代码或文档引用。
        【解决方案8】:

        所有文件快捷方式都有一个可以检查的 .lnk 文件扩展名。例如,使用字符串,您可以使用 string.EndsWith(".lnk") 作为过滤器。

        所有 URL 快捷方式都有一个 .url 文件扩展名,因此如果需要,您还需要考虑这些。

        【讨论】:

        • OP询问如何获取快捷方式的目标目录,而不是如何检查是否是快捷方式。
        猜你喜欢
        • 2020-12-22
        • 1970-01-01
        • 1970-01-01
        • 2021-06-11
        • 2018-09-22
        • 2020-07-05
        • 2014-05-24
        • 2016-07-14
        • 2021-10-24
        相关资源
        最近更新 更多