2017-02-28 27 views
10

Windows dosya sistemimde bir kısayol (.lnk) oluşturmaya çalışıyorum. Sahip olduğum kod çalışıyor. Ancak, bir Windows 2008R2 Sunucusu'nda numaralı aynı konsol uygulamasını çalıştırdığımda, farklı davranır.

Kısayol oluşturma, hedefleme yolunu değiştirir

Yani benim konsol uygulaması var ve burada olur:
Programım sadece bir .docx uzantılı masaüstüne kısayol oluşturur ve tüm yerel makinede ince gider. Sunucumda aynı konsol uygulamasını çalıştırdığımda, aynı kısayolu oluşturur ancak hedefi değiştirildi ... hedefi .doc dosyasına değiştirdi. Ben konsol uygulaması çalıştırdığınızda başka deyişle

,: \ test.docx

Sunucu:

LocalMachine

MyWordFile.lnk U işaret oluşturur

\ Test.doc


Bu garip bir davranıştır:

MyWordFile.lnk U işaret oluşturur. İşte 4 karakter hedefin uzantısından kaldırılırsa fark

kod

Kod

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



Güncelleme olduğunu. Yani, "file.abcdef" bir dosyam olduğunda, link "file.abc" de işaret ediyor. Ayrıca alanlarda alt çizgi için yer değiştirirler, böylece "my file.abcd" işaretçi "my_file.abc"

cevap

6

hedefin adını değiştirmez bir kısayol oluşturma haline gelir.

Başka bir şey görüyorsunuz, "my_file.abc" "file.abcd" öğesinin short name'udur. Bu isimler, her zaman kısa ad oluşturma özelliği açık olan bir dosya sistemi üzerinde oluşturulur. Hemen hemen hepsi hala, bugün çok nadiren gerekli olsa da hala yapıyor. Yalnızca MS-Dos isimlerini işleyebilen programlarla uyumlu "my file.abcd" işlevinin tutulması, alanın değiştirilmesini ve uzantının 3 harfe kısaltılmasını gerektirir. Dosya adlarını 8 harfe çevirmek için sık sık kullanılan adlarda "~ 1" görürsünüz.

DIR /x ile kısa adları görebilirsiniz.

Bu dosya için kısa adı tam olarak nasıl görmeniz gerektiği konusunda açık değildir. Ancak IShellLink arabirimi bildirimi kesinlikle yanlıştır, yöntemler doğru sırada listelenmez. Bir ComInterfaceType.InterfaceIsIUnknown arabirimi için oldukça çarpıcı sonuçları vardır, çalışma zamanında yanlış yöntemi çağırırsınız. Yol özellik belirleyicisi aslında 2. yöntemdir. Şimdi 18 yöntemini çağırıyorsunuz, ne yapabileceğini tahmin etmek çok zor değil. Eh, bir istisna atarsanız çok şaşırtıcı bir şey, bu nitelendirir :) Bu tamamen imkansız btw değil, eklenen 17 yöntemi, arabirimin sonraki bir sürümünde eklenen Target property için alıcı oldu. Yanlışlıkla belgesiz diziye çarpmış olabilirsiniz. Kasıtlı olarak belgesiz.

Yalnızca arabirimi kendiniz bildirmeyin. Bunu yapmanın en iyi yolu, Proje> Başvuru Ekle> Gözat düğmesi> C: \ Windows \ System32 \ Shell32.dll seçin. this post'da daha ayrıntılı olarak tarif edilmiştir.

+0

Çok ama çok açık bir açıklama için teşekkür ederiz! –