2009-09-11 16 views
7

In Delphi esiste una funzione ExpandUNCFileName che contiene un nome file e lo converte nell'equivalente UNC. Espande le unità mappate e ignora le posizioni locali e già espanse.Ottieni percorso UNC da un percorso locale o percorso mappato

campioni

C: \ Folder \ Text.txt -> C: \ Folder \ Text.txt
L: \ Folder \ Sample.txt -> \\ server \ Cartella1 \ Folder \ Sample.txt Dove L: è mappato a \\ server \ Cartella1 \
\\ server \ Folder \ Sample.odf -> \ server \ Folder \ Sample.odf

C'è un modo semplice per farlo in C# oppure io devi usare windows api chiamare WNetGetConnection e quindi controllare manualmente quelli che non verrebbero mappati?

risposta

2

Non esiste una funzione incorporata nel BCL che faccia l'equivalente. Penso che la migliore opzione che hai è di entrare in WNetGetConnection come suggerito.

5

P/Invoke WNetGetUniversalName().

L'ho fatto modificando this code da www.pinvoke.net.

0

provare questo codice, è scritto in Delphi Net

è necessario tradurlo in 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

molto piacevoli grazie tanto –

5

Ecco un codice C# con una funzione wrapper LocalToUNC, che sembra funzionare correttamente, sebbene non l'abbia provata estesamente.

[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 a causa del 'Marshal.ReadIntPtr (lpBuff)' per arrivare al buffer di stringa. Questo è più pulito rispetto all'esempio in alto su pinvoke.net, dove eseguono un'aritmetica puntatore shifty perché fanno l'ipotesi non documentata che il buffer di stringa si trovi direttamente dietro la struttura 'UNIVERSAL_NAME_INFO'. – herzbube

Problemi correlati