2009-09-11 46 views
7

Trong Delphi có hàm expandUNCFileName lấy tên tệp và chuyển đổi nó thành tương đương UNC. Nó mở rộng các ổ đĩa được ánh xạ và bỏ qua các vị trí cục bộ và đã được mở rộng.Nhận đường dẫn UNC từ đường dẫn cục bộ hoặc đường dẫn được ánh xạ

mẫu

C: \ Folder \ text.txt -> C: \ Folder \ text.txt
L: \ Folder \ Sample.txt -> \\ server \ folder1 \ Folder \ Sample.txt Trong đó L: được ánh xạ tới \\ server \ Folder1 \
\\ máy chủ \ Thư mục \ Sample.odf -> \ server \ Thư mục \ Sample.odf

Có cách nào đơn giản để làm điều này trong C# hay tôi phải sử dụng Windows api gọi WNetGetConnection và sau đó tự kiểm tra những cái mà sẽ không nhận được ánh xạ?

Trả lời

2

Không có hàm tích hợp trong BCL sẽ thực hiện tương đương. Tôi nghĩ rằng các tùy chọn tốt nhất mà bạn có là pInvoking vào WNetGetConnection như bạn đề nghị.

5

P/Gọi WNetGetUniversalName().

Tôi đã sửa đổi this code từ www.pinvoke.net.

0

Hãy thử mã này, được viết bằng Delphi Net

bạn phải dịch nó để C#

function WNetGetUniversalName; external; 
[SuppressUnmanagedCodeSecurity, DllImport(mpr, CharSet = CharSet.Ansi, SetLastError = True, EntryPoint = 'WNetGetUniversalNameA')] 


function ExpandUNCFileName(const FileName: string): string; 

function GetUniversalName(const FileName: string): string; 
const 
UNIVERSAL_NAME_INFO_LEVEL = 1;  
var 
    Buffer: IntPtr; 
    BufSize: DWORD; 
begin 
    Result := FileName; 
    BufSize := 1024; 
    Buffer := Marshal.AllocHGlobal(BufSize); 
    try 
    if WNetGetUniversalName(FileName, UNIVERSAL_NAME_INFO_LEVEL, 
     Buffer, BufSize) <> NO_ERROR then Exit; 
    Result := TUniversalNameInfo(Marshal.PtrToStructure(Buffer, 
     TypeOf(TUniversalNameInfo))).lpUniversalName; 
    finally 
    Marshal.FreeHGlobal(Buffer); 
    end; 
end; 

begin 
    Result :=System.IO.Path.GetFullPath(FileName); 
    if (Length(Result) >= 3) and (Result[2] = ':') and (Upcase(Result[1]) >= 'A') 
    and (Upcase(Result[1]) <= 'Z') then 
    Result := GetUniversalName(Result); 
end; 

Bye.

+0

cảm ơn rất tốt –

5

Dưới đây là một số mã C# có hàm bao bọc LocalToUNC, có vẻ như hoạt động OK, mặc dù tôi chưa thử nghiệm rộng rãi.

[DllImport("mpr.dll")] 
    static extern int WNetGetUniversalNameA(
     string lpLocalPath, int dwInfoLevel, IntPtr lpBuffer, ref int lpBufferSize 
    ); 

    // I think max length for UNC is actually 32,767 
    static string LocalToUNC(string localPath, int maxLen = 2000) 
    { 
     IntPtr lpBuff; 

     // Allocate the memory 
     try 
     { 
      lpBuff = Marshal.AllocHGlobal(maxLen); 
     } 
     catch (OutOfMemoryException) 
     { 
      return null; 
     } 

     try 
     { 
      int res = WNetGetUniversalNameA(localPath, 1, lpBuff, ref maxLen); 

      if (res != 0) 
       return null; 

      // lpbuff is a structure, whose first element is a pointer to the UNC name (just going to be lpBuff + sizeof(int)) 
      return Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(lpBuff)); 
     } 
     catch (Exception) 
     { 
      return null; 
     } 
     finally 
     { 
      Marshal.FreeHGlobal(lpBuff); 
     } 
    } 
+0

+1 vì 'Marshal.ReadIntPtr (lpBuff)' để lấy bộ đệm chuỗi. Điều này là sạch hơn ví dụ trên trên pinvoke.net, nơi họ làm một số số học con trỏ shifty bởi vì họ làm cho giả định không có giấy tờ rằng bộ đệm chuỗi nằm ngay phía sau cấu trúc 'UNIVERSAL_NAME_INFO'. – herzbube

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