创build快捷方式会修改目标path

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

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

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

LOCALMACHINE

创build指向U:\ test.docx的 MyWordFile.lnk

服务器

创build指向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); } } 

更新

我注意到第四个字符被从目标的扩展中删除 。 所以,当我有一个文件“file.abcdef”,链接指向“file.abc”。 空格也被replace为下划线 ,所以“我的file.abcd”指针变成了“my_file.abc”

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

你看到别的东西,“my_file.abc”是“my file.abcd”的简称 。 这样的名称总是在文件系统上创建,该文件系统仍然具有打开短名称生成功能的功能。 几乎所有的人仍然这样做,尽管今天很少有必要。 保持“我的file.abcd”与只能处理MS-DOS名称的程序兼容确实需要空间被替换,扩展缩写为3个字母。 你也经常在这样的名字中看到“〜1”,用来截取文件名为8个字母。

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

你究竟如何看到这个文件的简称并不明显。 但是,IShellLink接口声明肯定是错误的,方法没有按照正确的顺序列出。 这对ComInterfaceType.InterfaceIsIUnknown接口有非常严重的后果,您将在运行时调用错误的方法。 Path属性设置器实际上是第二种方法。 你现在正在调用第十八种方法,并不是很难猜测它会做什么。 那么,如果它不抛出异常,这是非常令人惊讶的,这是合格:)这是不完全令人难以置信的顺便说一句,被添加的第17个方法是Target属性的getter,添加到接口的更高版本。 你可能会无意中碰到无证的二传手。 故意没有记录。

只是不要自己声明接口。 最好的方法是使用Project> Add Reference> Browse按钮>选择C:\ Windows \ System32 \ Shell32.dll。 在这篇文章中有更详细的描述。