创建快捷方式会修改目标路径

时间:2017-02-28 13:27:52

标签: c# .net windows windows-server-2008 shortcut

我正在尝试在我的Windows文件系统上创建一个快捷方式(.lnk)。 我的代码工作正常。但是,当我在Windows 2008R2服务器上运行相同的控制台应用程序时,它的行为不同

所以我有我的控制台应用程序,这是发生的事情:
我的程序只是在桌面上创建一个带有 .docx 扩展名的快捷方式,并且在我的本地计算机上一切正常。当我在我的服务器上运行相同的控制台应用程序时,它会创建相同的快捷方式,但目标已被修改 ...它将目标更改为 .doc 文件。

换句话说,当我运行控制台应用程序时:

LOCALMACHINE

  

创建指向 U:\ test.docx

的MyWordFile.lnk

服务器

  

创建指向 U:\ test.doc

的MyWordFile.lnk


这是一种奇怪的行为。这是代码

代码

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;

namespace TestShortcut
{
    class Program
    {
        static void Main(string[] args)
        {
            //ShortcutTarget
            var sTarget = @"U:\test.docx";

            //ShortCutName
            var sName = @"MyWordFile.lnk";

            IShellLink link = (IShellLink)new ShellLink();
            link.SetPath(sTarget);

            IPersistFile file = (IPersistFile)link;
            string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
            file.Save(Path.Combine(desktopPath, sName), false);
        }
    }

    [ComImport]
    [Guid("00021401-0000-0000-C000-000000000046")]
    internal class ShellLink
    {
    }

    [ComImport]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("000214F9-0000-0000-C000-000000000046")]
    internal interface IShellLink
    {
        void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out IntPtr pfd, int fFlags);
        void GetIDList(out IntPtr ppidl);
        void SetIDList(IntPtr pidl);
        void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName);
        void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
        void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);
        void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
        void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);
        void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
        void GetHotkey(out short pwHotkey);
        void SetHotkey(short wHotkey);
        void GetShowCmd(out int piShowCmd);
        void SetShowCmd(int iShowCmd);
        void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cchIconPath, out int piIcon);
        void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
        void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved);
        void Resolve(IntPtr hwnd, int fFlags);
        void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
    }
}



更新

  

我注意到第4个字符已被删除来自目标的扩展程序。所以,当我有一个文件“file.abcdef”时,链接指向“file.abc”。另外空格会替换为下划线,因此“my file.abcd”指针变为“my_file.abc”

1 个答案:

答案 0 :(得分:6)

创建快捷方式不会修改目标的名称。

您正在看到其他内容,“my_file.abc”是“my file.abcd”的short name。此类名称始终在仍具有短名称生成功能的文件系统上创建。几乎所有人都做了,尽管今天已经很少需要了。保持“my file.abcd”与只能处理MS-Dos名称的程序兼容,需要更换空间并将扩展名缩短为3个字母。您还经常在这些名称中看到“~1”,用于将文件名截断为8个字母。

您可以使用DIR /x看到短名称。

从这个问题来看,你究竟如何看到这个文件的短名称并不明显。但是IShellLink接口声明肯定是错误的,方法没有按正确的顺序列出。这对于ComInterfaceType.InterfaceIsIUnknown接口有相当严重的后果,您将在运行时调用错误的方法。 Path属性设置器实际上是第二种方法。你现在正在调用第18种方法,并不是很难猜出它可能会做什么。好吧,如果它没有抛出异常就会出现非常令人惊讶的事情,这有资格:)这不是完全不可信的顺便说一下,添加的第17个方法是Target property的getter,在更高版本的界面中添加。您可能会意外地击中未记录的二传手。故意无证。

请勿自行声明界面。最好的方法是使用Project>添加参考>浏览按钮>选择C:\ Windows \ System32 \ Shell32.dll。在this post中有更详细的描述。