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

时间:2009-09-11 15:25:43

标签: c# unc

在Delphi中有一个函数ExpandUNCFileName,它接受一个文件名并将其转换为UNC等价物。它扩展了映射驱动器并跳过本地和已扩展的位置。

样品

C:\ Folder \ Text.txt - > C:\文件夹\ TEXT.TXT
L:\ Folder \ Sample.txt - > \\ server \ Folder1 \ Folder \ Sample.txt其中L:映射到\\ server \ Folder1 \
\\ server \ Folder \ Sample.odf - > \服务器\文件夹\ Sample.odf

有没有一种简单的方法可以在C#中执行此操作,还是必须使用Windows api调用WNetGetConnection,然后手动检查那些无法映射的?

4 个答案:

答案 0 :(得分:5)

P / Invoke WNetGetUniversalName()

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

答案 1 :(得分: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);
        }
    }

答案 2 :(得分:2)

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

答案 3 :(得分:0)

试试这段代码,用 Delphi .Net

编写

您必须将其翻译为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;

再见。