2009-09-11 4 views
7

Dans Delphi, il existe une fonction ExpandUNCFileName qui prend un nom de fichier et le convertit en équivalent UNC. Il étend les lecteurs mappés et ignore les emplacements locaux et déjà étendus.Récupère le chemin UNC à partir d'un chemin local ou d'un chemin mappé

échantillons

C: \ Dossier \ Text.txt -> C: \ Dossier \ Text.txt
L: \ Dossier \ Sample.txt -> \\ serveur \ Folder1 \ Dossier \ Sample.txt où L: à \\ serveur \ Dossier1 \
\\ serveur \ dossier \ Sample.odf -> \ server \ dossier \ Sample.odf

est-il un moyen simple de le faire en C# ou vais-je avoir à utiliser Windows api appeler WNetGetConnection, puis vérifier manuellement ceux qui ne seraient pas mappés?

Répondre

2

Il n'y a pas de fonction intégrée dans le BCL qui fera l'équivalent. Je pense que la meilleure option que vous avez est pInvoquer dans WNetGetConnection comme vous l'avez suggéré.

5

P/Appel WNetGetUniversalName().

Je l'ai fait en modifiant this code de www.pinvoke.net.

0

Essayez ce code, est écrit dans Delphi .Net

vous devez traduire en 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

très agréable merci beaucoup –

5

Voici un code C# avec une fonction d'encapsulation LocalToUNC, qui semble fonctionner correctement, bien que je ne l'ai pas testé intensivement.

[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 à cause de 'Marshal.ReadIntPtr (lpBuff)' pour obtenir le tampon de chaîne. Ceci est plus propre que l'exemple le plus haut sur pinvoke.net, où ils font une certaine arithmétique de pointeur de shifty parce qu'ils font l'hypothèse non documentée que le tampon de chaîne est situé directement derrière la structure 'UNIVERSAL_NAME_INFO'. – herzbube

Questions connexes