获取快捷方式文件夹目标

问题描述 投票:0回答:8

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

c# directory target shortcut
8个回答
32
投票

我认为您需要使用 COM 并添加对“Microsoft Shell 控制和自动化”的引用,如此博客文章中所述:

这是使用此处提供的代码的示例:

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

7
投票

在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);
  }
}

0
投票

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

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 文件格式发生变化,它当然会崩溃。


0
投票
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;
    }
}

0
投票

我已经使用了这个,始终基于内置的Windows“Shell.Application”COM对象,但使用纯后期绑定和反射来实现,因此不需要添加对现有项目的引用,并且没有任何依赖项。

    public static string GetLnkTarget(string lnkPath)
    {
        if (!System.IO.File.Exists(lnkPath))
            throw new FileNotFoundException();

        Type shlType;
        object shl = null;
        object dir = null;
        object items = null;
        object itm = null;
        object lnk = null;

        try
        {
            //var shl = new Shell();
            shlType = Type.GetTypeFromProgID("Shell.Application");
            shl = Activator.CreateInstance(shlType);

            string dirName = Path.GetDirectoryName(lnkPath);
            string lnkFile = Path.GetFileName(lnkPath);

            //var dir = shl.NameSpace(dirName);
            dir = shlType.InvokeMember("NameSpace", System.Reflection.BindingFlags.InvokeMethod, null, shl, new object[] { dirName });

            //var itm = dir.Items().Item(lnkFile);
            items = dir.GetType().InvokeMember("Items", System.Reflection.BindingFlags.InvokeMethod, null, dir, null);
            itm = items.GetType().InvokeMember("Item", System.Reflection.BindingFlags.InvokeMethod, null, items, new object[] { lnkFile });

            //var lnk = (ShellLinkObject)itm.GetLink;
            lnk = itm.GetType().InvokeMember("GetLink", System.Reflection.BindingFlags.GetProperty, null, itm, null);

            //return lnk.Path;
            object path = lnk.GetType().InvokeMember("Path", System.Reflection.BindingFlags.GetProperty, null, lnk, null);
            return (string)path;
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            if (lnk != null) Marshal.ReleaseComObject(lnk);
            if (itm != null) Marshal.ReleaseComObject(itm);
            if (items != null) Marshal.ReleaseComObject(items);
            if (dir != null) Marshal.ReleaseComObject(dir);
            if (shl != null) Marshal.ReleaseComObject(shl);
        }
    }

-1
投票

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

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

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


-1
投票

感谢 Mohsen.Sharify 的回答我得到了更简洁的代码:

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

-3
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.