2017-02-28 88 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

非常感謝,非常清楚的解釋! –