2009-09-11 325 views
7

在Delphi中有一個函數ExpandUNCFileName,它接受一個文件名並將其轉換爲UNC等效項。它擴展映射的驅動器並跳過本地和已擴展的位置。從本地路徑或映射路徑獲取UNC路徑

樣品

C:\文件夾\ TEXT.TXT - > C:\文件夾\ TEXT.TXT
L:\文件夾\ Sample.txt的 - > \\服務器\ Folder1中\文件夾\ Sample.txt的L:映射到\\ server \ Folder1 \
\\ server \ Folder \ Sample.odf - > \ server \ Folder \ Sample.odf

是否有一種簡單的方法可以在C#中執行此操作,必須使用Windows API調用WNetGetConnection然後手動檢查那些不會被映射的那些?

回答

2

BCL中沒有內置功能,它可以完成同等功能。我認爲你擁有的最好的選擇是按照你的建議進入WNetGetConnection。

5

P/Invoke WNetGetUniversalName()

我已經做了它從www.pinvoke.net修改this code

0

試試這個代碼,寫在德爾福淨

你必須把它翻譯成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; 

再見。

+0

非常感謝這麼多 – 2010-08-30 05:47:31

5

下面是一些包裝函數LocalToUNC的C#代碼,它似乎工作正常,但我沒有廣泛地測試它。

[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因爲'Marshal.ReadIntPtr(lpBuff)'得到字符串緩衝區。這比pinvoke.net上的頂部例子更清晰,他們在這裏做了一些很靈活的指針算術,因爲他們做了一個無法證明的假設,即字符串緩衝區直接位於'UNIVERSAL_NAME_INFO'結構之後。 – herzbube 2014-04-14 16:32:58