网上搜索到的方法都是获取1台PC1个共享资源里所有文件与目录。如图所示:
我现在的需求是获取1台PC所有的共享资源,然后遍历每一个共享资源里所有文件与目录。如图所示:
遍历的功能我已经实现,但是如何获取所有共享资源?NetShareEnum方法返回值是5。代码如下:
SHARE_INFO_502 shareBuffer; PSHARE_INFO_502 pShareTmp=NULL; NET_API_STATUS netApiStat=ERROR_SUCCESS; DWORD dwEr=0,dwTr=0,dwResume=0,i=0,dwEnumOpenStat=0,dwEnumEnumStat=0; in_addr ipDest; char* pcHost=(char*)calloc(64,sizeof(char)); LPWSTR szWideIp=(LPWSTR)calloc(32,sizeof(WCHAR)); BOOL bFind=FALSE; m_Ipv4Ctrl.GetAddress(ipDest.S_un.S_addr); sprintf(pcHost,"%d.%d.%d.%d",ipDest.S_un.S_un_b.s_b4,ipDest.S_un.S_un_b.s_b3,ipDest.S_un.S_un_b.s_b2,ipDest.S_un.S_un_b.s_b1); //GetHostNameByIp(pcHost); //i=MultiByteToWideChar(CP_ACP,0,pcIp,-1,NULL,0); MultiByteToWideChar(CP_ACP,0,pcHost,-1,szWideIp,64); memcpy(pcHost,szWideIp,64); do { netApiStat=NetShareEnum(pcHost,502,(LPBYTE*)&shareBuffer,-1,&dwEr,&dwTr,&dwResume); if (netApiStat==ERROR_SUCCESS||netApiStat==ERROR_MORE_DATA) { pShareTmp=&shareBuffer; for (i=0;i<=dwEr;i++) { if (IsValidSecurityDescriptor(pShareTmp->shi502_security_descriptor)) { } pShareTmp++; } bFind=TRUE; NetApiBufferFree(pShareTmp); } } while (netApiStat==ERROR_MORE_DATA); if (bFind) { CSelectPath dlgSp(this,pcHost); if (dlgSp.DoModal()==IDOK) { } } else { MessageBox("远程主机没有共享资源!","找不到共享资源",MB_OK|MB_ICONINFORMATION); } delete pShareTmp; delete pcHost; delete szWideIp;
微软MSDN网站上搜索不到相关的资料,求网友们回答。
共享资源的遍历关键是获取主机的共享的根目录,然后和主机名一起拼接出网络路径后就可以像遍历本地文件一样直接遍历了。
Directory.GetDirectories(@"\\127.0.0.1\projects");
至于获取共享的根目录,简单点的话直接用这段代码就可以获取共享的所有的根文件夹了:
[StructLayout(LayoutKind.Sequential)] protected struct SHARE_INFO_1 { [MarshalAs(UnmanagedType.LPWStr)] public string shi1_netname; [MarshalAs(UnmanagedType.U4)] public uint shi1_type; [MarshalAs(UnmanagedType.LPWStr)] public string shi1_remark; } [DllImport("Netapi32.dll", EntryPoint = "NetShareEnum")] protected static extern int NetShareEnum( [MarshalAs(UnmanagedType.LPWStr)] string servername, [MarshalAs(UnmanagedType.U4)] uint level, out IntPtr bufptr, [MarshalAs(UnmanagedType.U4)] int prefmaxlen, [MarshalAs(UnmanagedType.U4)] out uint entriesread, [MarshalAs(UnmanagedType.U4)] out uint totalentries, [MarshalAs(UnmanagedType.U4)] out uint resume_handle ); static string[] GetNetShareList(string server) { IntPtr buffer; uint entriesread; uint totalentries; uint resume_handle; //-1应该是获取所有的share,msdn里面的例子是这么写的,返回0表示成功 if (NetShareEnum(server, 1, out buffer, -1, out entriesread, out totalentries, out resume_handle) == 0) { Int32 ptr = buffer.ToInt32(); ArrayList alShare = new ArrayList(); for (int i = 0; i < entriesread; i++) { SHARE_INFO_1 shareInfo = (SHARE_INFO_1)Marshal.PtrToStructure(new IntPtr(ptr), typeof(SHARE_INFO_1)); if (shareInfo.shi1_type == 0)//Disk drive类型 { alShare.Add(shareInfo.shi1_netname); } ptr += Marshal.SizeOf(shareInfo);//有点类似C代码 } string[] share = new string[alShare.Count]; for (int i = 0; i < alShare.Count; i++) { share[i] = alShare[i].ToString(); } return share; } else return null; }
codeproject上也有一个完善点的封装。http://www.codeproject.com/Articles/2939/Network-Shares-and-UNC-paths。一楼所列出来的用wmi的方式没有p/invoke调用,更加可靠。
谢谢你,我使用SHARE_INFOR_1成功了。
可以考虑使用wmi去做。参考 http://gallery.technet.microsoft.com/scriptcenter/Lists-all-the-shared-5ebb395a
我也想了解