2009-09-11 13 views
7

W Delphi znajduje się funkcja ExpandUNCFileName, która przyjmuje nazwę pliku i konwertuje ją na odpowiednik UNC. Rozszerza zmapowane dyski i pomija lokalne i już rozwinięte lokalizacje.Uzyskaj ścieżkę UNC ze ścieżki lokalnej lub zmapowanej ścieżki

Próbki

folder C: \ \ text.txt -> C: \ Folder \ text.txt
L: \ Folder \ sample.txt -> \\ serwer \ Folder1 \ Folder \ sample.txt gdzie L: jest odwzorowywany \\ server \ Folder1 \
\\ server \ Folder \ Sample.odf -> \ server \ Folder \ Sample.odf

Czy istnieje prosty sposób to zrobić w C# albo ja trzeba użyć okna api wywołanie WNetGetConnection, a następnie ręcznie sprawdzić te, które nie zostały zmapowane?

Odpowiedz

2

Nie ma wbudowanej funkcji w BCL, która wykona odpowiednik. Myślę, że najlepszą opcją jest pInvoking w WNetGetConnection zgodnie z sugestią.

5

P/Wywołanie WNetGetUniversalName().

Zrobiłem to modyfikując this code ze strony www.pinvoke.net.

0

Spróbuj tego kodu, jest napisany w Delphi .NET

trzeba tłumaczyć go do 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

bardzo ładne Dzięki tak dużo –

5

Oto trochę kodu C# z funkcją wrappera LocalToUNC, która wydaje się działać poprawnie, chociaż nie testowałem jej w znacznym stopniu.

[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 powodu 'Marshal.ReadIntPtr (lpBuff)' dostać w buforze strun. To jest czystszy niż najlepszy przykład na pinvoke.net, gdzie wykonują arytmetyczną wskazówkę, ponieważ tworzą nieudokumentowane założenie, że bufor łańcuchowy znajduje się bezpośrednio za strukturą 'UNIVERSAL_NAME_INFO'. – herzbube

Powiązane problemy