2012-03-21 5 views
1

그물에도 이와 비슷한 질문이 있습니다.하지만 여기에도 몇 가지 질문이 있지만, 질문자가 행복해 보이긴하지만 실제로 필요한 항목을 찾을 수는 없습니다.네트워크 폴더 브라우저 서비스

웹 기반 관리 제어판 (인트라넷 기반)에 원격 디렉터리 탐색 기능을 추가하려고합니다.

다른 곳에서 처리되므로 보안에 대해 걱정할 필요가 없습니다.

이렇게하려면 매개 변수로 서버 이름과 공유/폴더 경로를 허용하는 webservice를 사용하고 있습니다. 이 경로의 하위 디렉토리를 반환해야합니다.

그렇게 열심히하지 않습니까? 글쎄, 적어도 (나에게!)

내가 도움이 필요한 유일한 비트는 실제로 서버와 경로에 대한 디렉토리 목록을 작성하는 것입니다.

모든 도움을 주실 수는 있지만 이미 사이트를 링크 한 것이 아니라 이미 본 적이 있지만 실제로 해결책을 찾지 못했습니다. 이것들의 대부분은 그 제목이 함축하는 것을하려고 시도조차하지 않는 것입니다. 일부 explaination도 도움이 될 것입니다!

환호

+0

'네트워크 폴더'란 무엇을 의미합니까? SMB 공유? NFS? FTP? WebDAV? 폴더를 나열하는 것은 각 프로토콜마다 완전히 다릅니다. –

+0

다음은 표준 Windows Server 공유 폴더 및 해당 하위 폴더입니다. – CompanyDroneFromSector7G

답변

0

설명한 방법 here using Interop을 사용할 수 있습니다.

코드를 약간 수정하여이 문제를 해결했습니다. 광범위하게 테스트하지 않았으므로 오류가있을 수 있지만 시작해야합니다.

private List<string> GetSubDirectories(string serverName, string folderPath) 
{ 
     List<string> subDirectories = new List<string>(); 
     string folder_path = Path.Combine(serverName, folderPath);    
     IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1); 

     WIN32_FIND_DATA findData; 

     IntPtr findHandle; 

     findHandle = FindFirstFile(folder_path, out findData); 
     if (findHandle == INVALID_HANDLE_VALUE) 
     { 
      int error = Marshal.GetLastWin32Error(); 
      Console.WriteLine(error.ToString()); 
      return null; 
     } 

     do 
     { 
      try 
      { 
       if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) 
        subDirectories.Add(findData.cFileName);      
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.ToString()); 
      } 
     } 
     while (FindNextFile(findHandle, out findData)); 
     FindClose(findHandle); 

     return subDirectories; 
    } 

    public const int FILE_ATTRIBUTE_DIRECTORY = 0x10; 

    [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Auto)] 
    public static extern IntPtr FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData); 

    [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Auto)] 
    public static extern bool FindNextFile(IntPtr hFindFile, out WIN32_FIND_DATA lpFindFileData); 

    [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Auto)] 
    public static extern bool FindClose(IntPtr hFindFile); 

    [StructLayout(LayoutKind.Sequential)] 
    public struct FILETIME 
    { 
     public uint dwLowDateTime; 
     public uint dwHighDateTime; 
    }; 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
    public struct WIN32_FIND_DATA 
    { 
     public uint dwFileAttributes; 
     public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime; 
     public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime; 
     public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime; 
     public uint nFileSizeHigh; 
     public uint nFileSizeLow; 
     public uint dwReserved0; 
     public uint dwReserved1; 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 
     public string cFileName; 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)] 
     public string cAlternateFileName; 
    } 


    [DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
    public static extern bool CloseHandle(IntPtr handle); 

} 

당신은 그것을 좋아 호출 할 수 있습니다 :

var subdirectories = GetSubDirectories(@"\\[serverName]", @"[folderPath]\*"); 

을 추가해야 "\ *"네트워크 공유에 as per MSDN

, 당신은의 형태에 lpFileName을 사용할 수 있습니다 다음 : "\ Server \ Share *". 그러나 공유 자체를 가리키는 lpFileName 을 사용할 수 없습니다. 예를 들어 "\ Server \ Share"는 이 아닙니다.

+0

감사합니다. 이것은 공유 이름이있는 한 작동하는 것 같습니다. 주식을 나열하는 방법이 있습니까, 아니면 완전히 다른 것입니까? – CompanyDroneFromSector7G

+0

공유를 열거하려면 [여기에 설명 된] 방법이 필요합니다 (http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/19b88200-3dfd-4042-b16a-1f514dd5e1f9/). –

+0

이것은 나를 위해 가장 잘 작동하는 해결책입니다. 모든 제안을 주셔서 감사합니다. – CompanyDroneFromSector7G

0

우리가 이것을 달성 할 수 있는지 확실하지 않습니다. 비슷한 문제가 있었지만 마침내 공유 경로 (\ SERVERNAME \ FOLDER)를 제공하여 해결했습니다.

가장 중요한 webservice는 디렉토리에 대한 전체 권한을 가진 계정을 사용해야하며, 권한과 관련된 예외는 호출하는 클라이언트에게 던져 질 것입니다.

0

글쎄, 실제로는 NetShareEnum Win32API function을 사용하여 수행 할 수 있습니다.

하지만 로컬 및 원격 컴퓨터에서 네트워크 공유를 열거하고 로컬 파일 경로를 UNC 경로로 변환하는 .NET 래퍼 클래스가 있습니다. 자세한 내용은 Network Shares and UNC paths을 참조하십시오.

+0

그 기사를 보았지만 필요한 것은하지 않습니다. 로컬 컴퓨터의 공유를 열거하지 않고 원격 컴퓨터의 공유를 알고 싶습니다. 이것이 서버 이름이 필요한 이유입니다. – CompanyDroneFromSector7G

+0

'ShareCollection' 클래스의'GetShares' 정적 메서드를 보았습니까? –

+0

나는 지금있다! : $ 감사합니다 - 지금 다른 옵션을보고 있습니다. – CompanyDroneFromSector7G

0

.NET에서 지정된 폴더의 하위 폴더를 열거하려면 예를 들어 DirectoryInfo.EnumerateDirectories 메서드를 사용할 수 있습니다.

C$, ADMIN$, print$ 같은 관리 공유를 숨겨 등등 당신을 위해 중요하지 않은 경우 WNetEnumResource 기본 기능을 사용하거나 모든 공유를 열거 할 NetShareEnum을 사용할 수있는 컴퓨터의 주식을 열거합니다.

대응 코드가 될 수있는 상기 코드 간략화

Subdirectories of \\OK01\Users: 
All Users 
ASP.NET v4.0 
Default 
Default User 
MSSQL$SQL2012 
Oleg 
Public 

Subdirectories of \\OK01\Users\Public: 
Desktop 
Documents 
Downloads 
Favorites 
Libraries 
Music 
Pictures 
Recorded TV 
Roaming 
Videos 

All Shares of \\OK01 (inclusive hidden): 
ADMIN$ 
C$ 
print$ 
Q$ 
Users 
Virtual Machines 
VMware 

Shares of \\OK01: 
Users 
Virtual Machines 
VMware 

같은 출력은 대응하는 API를 사용하는 방법에 대해서만 설명하기 생산

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.IO; 
using System.Runtime.InteropServices; 

namespace Subfolders { 
    static internal class Native { 
     [DllImport ("Netapi32.dll", SetLastError = true)] 
     internal static extern uint NetApiBufferFree (IntPtr buffer); 

     [DllImport ("Netapi32.dll", CharSet = CharSet.Unicode)] 
     internal static extern uint NetShareEnum (
      string serverName, 
      int level, 
      ref IntPtr bufPtr, 
      uint prefmaxlen, 
      ref int entriesread, 
      ref int totalentries, 
      ref int resumeHandle 
     ); 

     [DllImport ("MPR.dll", CharSet = CharSet.Auto)] 
     internal static extern uint WNetEnumResource(IntPtr hEnum, ref int lpcCount, IntPtr lpBuffer, ref int lpBufferSize); 

     [DllImport ("MPR.dll", CharSet = CharSet.Auto)] 
     internal static extern uint WNetOpenEnum(ResourceScope dwScope, ResourceType dwType, ResourceUsage dwUsage, 
      IntPtr lpNetResource, out IntPtr lphEnum); 

     [DllImport ("MPR.dll", CharSet = CharSet.Auto)] 
     internal static extern uint WNetCloseEnum(IntPtr hEnum); 

     internal const uint MaxPreferredLength = 0xFFFFFFFF; 
     internal const int NerrSuccess = 0; 
     internal enum NetError : uint { 
      NerrSuccess = 0, 
      NerrBase = 2100, 
      NerrUnknownDevDir = (NerrBase + 16), 
      NerrDuplicateShare = (NerrBase + 18), 
      NerrBufTooSmall = (NerrBase + 23), 
     } 
     internal enum ShareType : uint { 
      StypeDisktree = 0, 
      StypePrintq = 1, 
      StypeDevice = 2, 
      StypeIpc = 3, 
      StypeSpecial = 0x80000000, 
     } 
     [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
     public struct ShareInfo1 { 
      public string shi1_netname; 
      public uint shi1_type; 
      public string shi1_remark; 
      public ShareInfo1 (string sharename, uint sharetype, string remark) { 
       shi1_netname = sharename; 
       shi1_type = sharetype; 
       shi1_remark = remark; 
      } 
      public override string ToString() { 
       return shi1_netname; 
      } 
     } 
     public enum ResourceScope: uint { 
      ResourceConnected = 0x00000001, 
      ResourceGlobalnet = 0x00000002, 
      ResourceRemembered = 0x00000003, 
      ResourceRecent = 0x00000004, 
      ResourceContext = 0x00000005 
     } 
     public enum ResourceType: uint { 
      ResourcetypeAny = 0x00000000, 
      ResourcetypeDisk = 0x00000001, 
      ResourcetypePrint = 0x00000002, 
      ResourcetypeReserved = 0x00000008, 
      ResourcetypeUnknown = 0xFFFFFFFF 
     } 
     public enum ResourceUsage: uint { 
      ResourceusageConnectable = 0x00000001, 
      ResourceusageContainer = 0x00000002, 
      ResourceusageNolocaldevice = 0x00000004, 
      ResourceusageSibling = 0x00000008, 
      ResourceusageAttached = 0x00000010, 
      ResourceusageAll = (ResourceusageConnectable | ResourceusageContainer | ResourceusageAttached), 
      ResourceusageReserved = 0x80000000 
     } 
     public enum ResourceDisplaytype: uint { 
      ResourcedisplaytypeGeneric = 0x00000000, 
      ResourcedisplaytypeDomain = 0x00000001, 
      ResourcedisplaytypeServer = 0x00000002, 
      ResourcedisplaytypeShare = 0x00000003, 
      ResourcedisplaytypeFile = 0x00000004, 
      ResourcedisplaytypeGroup = 0x00000005, 
      ResourcedisplaytypeNetwork = 0x00000006, 
      ResourcedisplaytypeRoot = 0x00000007, 
      ResourcedisplaytypeShareadmin = 0x00000008, 
      ResourcedisplaytypeDirectory = 0x00000009, 
      ResourcedisplaytypeTree = 0x0000000A, 
      ResourcedisplaytypeNdscontainer = 0x0000000B 
     } 
     [StructLayout (LayoutKind.Sequential)] 
     public struct NetResource { 
      public ResourceScope dwScope; 
      public ResourceType dwType; 
      public ResourceDisplaytype dwDisplayType; 
      public ResourceUsage dwUsage; 
      [MarshalAs (UnmanagedType.LPTStr)] 
      public string lpLocalName; 
      [MarshalAs (UnmanagedType.LPTStr)] 
      public string lpRemoteName; 
      [MarshalAs (UnmanagedType.LPTStr)] 
      public string lpComment; 
      [MarshalAs (UnmanagedType.LPTStr)] 
      public string lpProvider; 
     } 
    } 
    class Program { 
     static IEnumerable<string> GetShares(string computerName) { 
      var resources = new List<string>(); 
      IntPtr hEnum = IntPtr.Zero, pResource = IntPtr.Zero; 
      try { 
       var resource = new Native.NetResource(); 
       int bufferSize = 163840; 
       resource.dwType = Native.ResourceType.ResourcetypeAny; 
       resource.dwScope = Native.ResourceScope.ResourceGlobalnet; 
       resource.dwUsage = Native.ResourceUsage.ResourceusageContainer; 
       resource.lpRemoteName = computerName; 
       pResource = Marshal.AllocHGlobal(Marshal.SizeOf(resource)); 
       Marshal.StructureToPtr (resource, pResource, false); 
       uint status = Native.WNetOpenEnum (Native.ResourceScope.ResourceGlobalnet, 
                Native.ResourceType.ResourcetypeDisk, 
                0, 
                pResource, 
                out hEnum); 
       if (status != 0) 
        return resources; 

       int numberOfEntries = -1; 
       IntPtr pBuffer = Marshal.AllocHGlobal(bufferSize); 
       status = Native.WNetEnumResource (hEnum, ref numberOfEntries, pBuffer, ref bufferSize); 
       if (status == Native.NerrSuccess && numberOfEntries > 0) { 
        var ptr = pBuffer; 
        for (int i = 0; i < numberOfEntries; i++, ptr += Marshal.SizeOf(resource)) { 
         resource = (Native.NetResource)Marshal.PtrToStructure (ptr, typeof (Native.NetResource)); 
         resources.Add (resource.lpRemoteName.StartsWith (computerName + '\\', 
                     StringComparison.OrdinalIgnoreCase) 
              ? resource.lpRemoteName.Substring (computerName.Length + 1) 
              : resource.lpRemoteName); 
        } 
       } 
      } finally { 
       if (hEnum != IntPtr.Zero) { 
        Native.WNetCloseEnum (hEnum); 
       } 
       if (pResource != IntPtr.Zero) { 
        Marshal.FreeHGlobal(pResource); 
       } 
      } 
      return resources; 
     } 

     static IEnumerable<string> GetAllShares (string computerName) { 
      var shares = new List<string>(); 
      IntPtr bufPtr = IntPtr.Zero; 
      int entriesread = 0; 
      int totalentries = 0; 
      int resumeHandle = 0; 
      int nStructSize = Marshal.SizeOf (typeof (Native.ShareInfo1)); 
      try { 
       uint ret = Native.NetShareEnum (computerName, 1, ref bufPtr, 
        Native.MaxPreferredLength, 
        ref entriesread, 
        ref totalentries, 
        ref resumeHandle); 
       if (ret == (uint)Native.NetError.NerrSuccess) { 
        var currentPtr = bufPtr; 
        for (int i = 0; i < entriesread; i++) { 
         var shi1 = (Native.ShareInfo1)Marshal.PtrToStructure (currentPtr, typeof (Native.ShareInfo1)); 
         if ((shi1.shi1_type & ~(uint)Native.ShareType.StypeSpecial) == (uint)Native.ShareType.StypeDisktree) { 
          shares.Add (shi1.shi1_netname); 
         } 
         currentPtr = new IntPtr (currentPtr.ToInt32() + nStructSize); 
        } 
       } 
      } finally { 
       if (bufPtr != IntPtr.Zero) 
        Native.NetApiBufferFree (bufPtr); 
      } 
      return shares; 
     } 
     static IEnumerable<string> GetSubdirectories (string root) { 
      var dirInfo = new DirectoryInfo (root); 
      return (from info in dirInfo.EnumerateDirectories() select info.Name).ToList(); 
     } 
     static void Main() { 
      var root = @"\\OK01\Users"; 
      Console.WriteLine ("Subdirectories of {0}:", root); 
      foreach (var dir in GetSubdirectories (root)) { 
       Console.WriteLine (dir); 
      } 

      Console.WriteLine(); 
      root = @"\\OK01\Users\Public"; 
      Console.WriteLine ("Subdirectories of {0}:", root); 
      foreach (var dir in GetSubdirectories (root)) { 
       Console.WriteLine (dir); 
      } 

      Console.WriteLine(); 
      root = @"\\OK01"; 
      Console.WriteLine ("All Shares of {0} (inclusive hidden):", root); 
      foreach (var shareName in GetAllShares (root)) { 
       Console.WriteLine (shareName); 
      } 

      Console.WriteLine(); 
      root = @"\\OK01"; 
      Console.WriteLine ("Shares of {0}:", root); 
      foreach (var shareName in GetShares (root)) { 
       Console.WriteLine (shareName); 
      } 
     } 
    } 
} 

. 실제 오류보고가 없습니다.

관련 문제