2017-02-28 27 views
10

Tôi đang cố gắng tạo lối tắt (.lnk) trên hệ thống tệp của cửa sổ. Mã tôi đang hoạt động tốt. Tuy nhiên, khi tôi chạy cùng một ứng dụng bảng điều khiển trên Máy chủ Windows 2008R2, nó hoạt động khác nhau.

Tạo lối tắt sửa đổi đường dẫn để nhắm mục tiêu

Vì vậy, tôi có ứng dụng giao diện điều khiển của tôi và đây là những gì sẽ xảy ra:
chương trình của tôi chỉ đơn giản là tạo ra một shortcut trên desktop với một phần mở rộng .docx và mọi việc suôn sẻ tốt trên máy tính địa phương của tôi. Khi tôi chạy cùng một ứng dụng giao diện điều khiển trên Máy chủ của mình, nó tạo ra cùng một lối tắt nhưng mục tiêu đã được sửa đổi ... nó đã thay đổi mục tiêu thành tệp .doc.

Nói cách khác, khi tôi chạy ứng dụng giao diện điều khiển:

LocalMachine

Tạo MyWordFile.lnk trỏ đến U: \ test.docx

server

Tạo MyWordFile.lnk trỏ đến U: \ test.doc


Đây là hành vi kỳ lạ. Đây là mã

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



Cập nhật

tôi nhận thấy rằng nhân vật thứ 4 sẽ bị gỡ từ phần mở rộng của mục tiêu. Vì vậy, khi tôi có một tập tin "file.abcdef", các điểm liên kết tại "file.abc". Cũng không gian được thay thế cho dấu gạch, vì vậy "file.abcd của tôi" con trỏ trở thành "my_file.abc"

Trả lời

6

Tạo một shortcut không thay đổi tên của mục tiêu.

Bạn đang thấy nội dung khác "my_file.abc" là short name trong "tệp của tôi.abcd". Các tên như vậy luôn được tạo trên hệ thống tệp vẫn còn bật tính năng tạo tên ngắn. Hầu như tất cả trong số họ vẫn làm, mặc dù nó là rất hiếm khi cần thiết nữa ngày hôm nay. Việc giữ "tệp của tôi.abcd" tương thích với các chương trình chỉ có thể xử lý tên MS-Dos yêu cầu không gian được thay thế và phần mở rộng được rút ngắn thành 3 chữ cái. Bạn cũng thường thấy "~ 1" trong các tên như vậy, được sử dụng để cắt ngắn tên tệp thành 8 chữ cái.

Bạn có thể xem các tên ngắn bằng DIR /x.

Chính xác cách bạn nhận thấy tên viết tắt của tệp này không rõ ràng từ câu hỏi. Nhưng tuyên bố giao diện IShellLink chắc chắn là sai, các phương thức không được liệt kê theo đúng thứ tự. Điều đó có hậu quả khá nghiêm trọng cho một giao diện ComInterfaceType.InterfaceIsIUnknown, bạn sẽ gọi phương thức sai khi chạy. Thiết lập thuộc tính Path thực sự là phương thức thứ 2. Bây giờ bạn đang gọi phương thức 18, nó không được khai báo quá khó để đoán nó có thể làm gì. Vâng, một cái gì đó rất đáng ngạc nhiên nếu nó không ném một ngoại lệ, điều này đủ điều kiện :) Nó không phải là hoàn toàn không hợp lý btw, phương pháp 17 được thêm vào là getter cho Target property, được thêm vào trong một phiên bản sau của giao diện. Bạn có thể vô tình nhấn setter không có giấy tờ. Cố ý không có giấy tờ.

Chỉ cần không tự khai báo giao diện. Cách tốt nhất để làm điều đó là sử dụng Project> Add Reference> Browse button> chọn C: \ Windows \ System32 \ Shell32.dll. Được mô tả chi tiết hơn trong this post.

+0

Cảm ơn bạn rất nhiều, giải thích rất rõ ràng! –

Các vấn đề liên quan