2009-09-11 13 views
7

डेल्फी में एक फ़ंक्शन ExpandUNCFileName है जो फ़ाइल नाम लेता है और इसे यूएनसी समकक्ष में परिवर्तित करता है। यह मैप किए गए ड्राइव का विस्तार करता है और स्थानीय और पहले ही विस्तारित स्थानों को छोड़ देता है।स्थानीय पथ या मैप किए गए पथ से यूएनसी पथ प्राप्त करें

नमूने

C: \ फ़ोल्डर \ Text.txt -> C: \ फ़ोल्डर \ Text.txt
एल: \ फ़ोल्डर \ Sample.txt -> \\ सर्वर \ Folder1 \ फ़ोल्डर \ Sample.txt कहाँ एल: \ Folder1 \
\\ सर्वर \ फ़ोल्डर \ Sample.odf सर्वर के लिए \\ मैप किया गया है -> \ सर्वर \ फ़ोल्डर \ Sample.odf

वहाँ सी # में यह करने के लिए एक आसान तरीका है या मैं लूंगा विंडोज एपीआई कॉल WNetGetConnection का उपयोग करना होगा और फिर उन लोगों को मैन्युअल रूप से जांचें जिन्हें मैप नहीं किया जाएगा?

उत्तर

2

बीसीएल में कोई अंतर्निहित कार्य नहीं है जो समकक्ष करेगा। मुझे लगता है कि आपके पास सबसे अच्छा विकल्प है जैसा कि आपने सुझाव दिया है WNetGetConnection में pInvoking।

5

पी/WNetGetUniversalName() आमंत्रित करें।

मैंने इसे www.pinvoke.net से this code संशोधित किया है।

0

इस कोड का प्रयास करें, डेल्फी नेट

में लिखा है आप #

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

इतना –

5

यहां कुछ सी # कोड है जो एक रैपर फ़ंक्शन LocalToUNC के साथ है, जो ठीक काम करता प्रतीत होता है, हालांकि मैंने इसे बड़े पैमाने पर परीक्षण नहीं किया है।

[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

संबंधित मुद्दे