2009-09-11 132 views
7

Delphiにはファイル名を取り込み、それをUNCに変換する関数ExpandUNCFileNameがあります。マップされたドライブを展開し、ローカルおよび既に展開されている場所をスキップします。ローカルパスまたはマップされたパスからUNCパスを取得する

サンプル

C:\フォルダ\ TEXT.TXT - > C:\フォルダ\ TEXT.TXT
L:\フォルダ\ Sample.txtを - Folder1に\フォルダ\ Sample.txtを\> \\サーバーL:が\\ server \ Folder1 \
にマップされています \\ server \ Folder \ Sample.odf - > \ server \ Folder \ Sample.odf

C#でこれを行う簡単な方法はありますか? Windows APIを使用してWNetGetConnectionを呼び出してから、手動でマッピングされないものをチェックする必要がありますか?

答えて

2

同等の処理を行う組み込み関数がBCLにはありません。私はあなたが持っている最良の選択肢は、あなたが提案したようにWNetGetConnectionにpInvokingしていると思います。

5

P/Invoke WNetGetUniversalName()

私はそれを修正しましたthis code www.pinvoke.netから。

0

このコードを試してみてくださいは、あなたが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; 

さようならにそれを翻訳しなければなりませんデルファイの.Net

で書かれています。

+0

非常に素晴らしい感謝そんなに –

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); 
     } 
    } 
+0

+1ため 'Marshal.ReadIntPtr(lpBuff)の'文字列バッファに取得します。これは、pinvoke.netの上の例よりも洗練されています。ここでは、文字列バッファがUNIVERSAL_NAME_INFO構造体のすぐ後ろに位置するという文書化されていない仮定を行うため、ポインタの算術演算を行います。 – herzbube

関連する問題