2017-02-28 92 views
10

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

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

所以,我有我的控制台应用程序,并会出现以下情况:
我的程序简单,配有的.docx扩展在桌面上创建快捷方式和我的本地机器上的一切都很好。当我在我的服务器上运行相同的控制台应用程序时,它会创建相同的快捷方式,但目标已修改为 ...它将目标更改为.doc文件。

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

LOCALMACHINE

创建MyWordFile.lnk指着U:\ test.docx

服务器

创建MyWordFile.lnk指着U:\ Test.doc的


这是奇怪的行为。下面是代码

代码

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”。此外空间会被替换为下划线,所以“我file.abcd”指针变成“my_file.abc”

回答

6

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

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

您可以通过DIR /x查看短名称。

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

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

+0

非常感谢,非常清楚的解释! –