从本地路径或映射路径获取UNC路径

问题描述:

在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然后手动检查那些不会被映射的那些?

BCL中没有内置功能,它可以完成同等功能。我认为你拥有的最好的选择是按照你的建议进入WNetGetConnection。

P/Invoke WNetGetUniversalName()

我已经做了它从www.pinvoke.net修改this code

试试这个代码,写在德尔福净

你必须把它翻译成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

下面是一些包装函数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