如何以编程方式在DFS中获取活动的UNC路径

给定DFS路径,我如何知道它当前以编程方式存在的活动路径。

例如,我有2个服务器共享为"\\Server1\Folder\""\\Server2\Folder\"并且它已打开DFS,因此可以在"\\DFS_Server\Folder\"上访问它,我怎么知道当前"\\DFS_Server\Folder\"的活动路径是什么,无论是"\\Server1\Folder\"还是"\\Server2\Folder\"

尝试这样,其中sDFSPath是您要查询的路径,sHostServer是您要查询WMI的服务器,这可以是您上面提到的两台服务器中的任何一台。 您甚至可以在第一台服务器上发生故障时生成更优雅的代码,然后在下一台服务器上查询WMI

 public static ArrayList GetActiveServers(string sDFSPath, string sHostServer) { ArrayList sHostNames = new ArrayList(); ManagementPath oManagementPath = new ManagementPath(); oManagementPath.Server = sHostServer; oManagementPath.NamespacePath = @"root\cimv2"; oManagementScope = new ManagementScope(oManagementPath); oManagementScope.Connect(); SelectQuery oSelectQuery = new SelectQuery(); oSelectQuery.QueryString = @"SELECT * FROM Win32_DfsTarget WHERE LinkName LIKE '%" + sDFSPath.Replace("\\", "\\\\") + "%' and State = 1"; ManagementObjectSearcher oObjectSearcher = new ManagementObjectSearcher(oManagementScope, oSelectQuery); ManagementObjectCollection oObjectCollection = oObjectSearcher.Get(); if (oObjectCollection.Count != 0) { foreach (ManagementObject oItem in oObjectCollection) { sHostNames.Add(oItem.Properties["ServerName"].Value.ToString()); } } return sHostNames; } 

希望它有意义

如果我正确理解您的要求,那么还有一个似乎可以满足您需求的API:

 // mscorlib (no additional assemblies needed) using System.Runtime.InteropServices; public static class Dfs { private enum NetDfsInfoLevel { DfsInfo1 = 1, DfsInfo2 = 2, DfsInfo3 = 3, DfsInfo4 = 4, DfsInfo5 = 5, DfsInfo6 = 6, DfsInfo7 = 7, DfsInfo8 = 8, DfsInfo9 = 9, DfsInfo50 = 50, DfsInfo100 = 100, DfsInfo150 = 150, } [DllImport("netapi32.dll", SetLastError = true)] private static extern int NetApiBufferFree(IntPtr buffer); [DllImport("Netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern int NetDfsGetInfo( [MarshalAs(UnmanagedType.LPWStr)] string DfsEntryPath, // DFS entry path for the volume [MarshalAs(UnmanagedType.LPWStr)] string ServerName, // This parameter is currently ignored and should be NULL [MarshalAs(UnmanagedType.LPWStr)] string ShareName, // This parameter is currently ignored and should be NULL. NetDfsInfoLevel Level, // Level of information requested out IntPtr Buffer // API allocates and returns buffer with requested info ); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] private struct DFS_INFO_3 { [MarshalAs(UnmanagedType.LPWStr)] public string EntryPath; [MarshalAs(UnmanagedType.LPWStr)] public string Comment; public int State; public int NumberOfStorages; public IntPtr Storage; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] private struct DFS_STORAGE_INFO { public int State; [MarshalAs(UnmanagedType.LPWStr)] public string ServerName; [MarshalAs(UnmanagedType.LPWStr)] public string ShareName; } private static T GetStruct(IntPtr buffer, int offset=0)where T:struct { T r = new T(); r = (T) Marshal.PtrToStructure(buffer + offset * Marshal.SizeOf(r), typeof(T)); return r; } public static string GetDfsInfo(string server) { string rval = null; IntPtr b; int r = NetDfsGetInfo(server, null, null, NetDfsInfoLevel.DfsInfo3, out b); if(r != 0) { NetApiBufferFree(b); // return passed string if not DFS return rval; } DFS_INFO_3 sRes = GetStruct(b); if(sRes.NumberOfStorages > 0) { DFS_STORAGE_INFO sResInfo = GetStruct(sRes.Storage); rval = string.Concat(@"\\", sResInfo.ServerName, @"\", sResInfo.ShareName, @"\"); } NetApiBufferFree(b); return rval; } } 

像这样用它:

 string dfsPath = @"\\DFS_Server\Folder\"; string share = Dfs.GetDfsInfo(dfsPath) 

有关API参考,请检查NetDfsGetInfo , DFS_INFO_3 , DFS_STORAGE_INFO和NetApiBufferFree上的msdn 。

谢谢你,你的提示很有用。 但是我使用NetDfsGetClientInfo更成功。 还意识到解析过程可能是递归的。 我最终得到了至少2次递归调用以获得实际的物理UNC共享,这是我的例子。

我不知道,怎么样

 public static class DFS { #region Import [DllImport("Netapi32.dll", EntryPoint = "NetApiBufferFree")] public static extern uint NetApiBufferFree(IntPtr Buffer); [DllImport("Netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] public static extern int NetDfsGetInfo( [MarshalAs(UnmanagedType.LPWStr)] string EntryPath, [MarshalAs(UnmanagedType.LPWStr)] string ServerName, [MarshalAs(UnmanagedType.LPWStr)] string ShareName, int Level, out IntPtr Buffer); [DllImport("Netapi32.dll")] public static extern int NetDfsGetClientInfo( [MarshalAs(UnmanagedType.LPWStr)] string EntryPath, [MarshalAs(UnmanagedType.LPWStr)] string ServerName, [MarshalAs(UnmanagedType.LPWStr)] string ShareName, int Level, out IntPtr Buffer); #endregion #region Structures public struct DFS_INFO_3 { [MarshalAs(UnmanagedType.LPWStr)] public string EntryPath; [MarshalAs(UnmanagedType.LPWStr)] public string Comment; public UInt32 State; public UInt32 NumberOfStorages; public IntPtr Storages; } public struct DFS_STORAGE_INFO { public Int32 State; [MarshalAs(UnmanagedType.LPWStr)] public string ServerName; [MarshalAs(UnmanagedType.LPWStr)] public string ShareName; } #endregion const int DFS_VOLUME_STATE_OK = 0x00000001; const int DFS_VOLUME_STATE_ONLINE = 0x00000004; const int DFS_STORAGE_STATE_ONLINE = 0x00000002; const int DFS_STORAGE_STATE_ACTIVE = 0x00000004; public static String GetSharePath(String DFSPath) { if (!String.IsNullOrEmpty(DFSPath)) { IntPtr Buffer = IntPtr.Zero; try { int Error = NetDfsGetClientInfo(DFSPath, null, null, 3, out Buffer); if (Error == 0) { DFS_INFO_3 DFSInfo = (DFS_INFO_3)Marshal.PtrToStructure(Buffer, typeof(DFS_INFO_3)); if ((DFSInfo.State & DFS_VOLUME_STATE_OK) > 0) { String SubPath = DFSPath.Remove(0, 1 + DFSInfo.EntryPath.Length).TrimStart(new Char[] { '\\' }); for (int i = 0; i < DFSInfo.NumberOfStorages; i++) { IntPtr Storage = new IntPtr(DFSInfo.Storages.ToInt64() + i * Marshal.SizeOf(typeof(DFS_STORAGE_INFO))); DFS_STORAGE_INFO StorageInfo = (DFS_STORAGE_INFO)Marshal.PtrToStructure(Storage, typeof(DFS_STORAGE_INFO)); if ((StorageInfo.State & DFS_STORAGE_STATE_ACTIVE) > 0) { if (String.IsNullOrEmpty(SubPath)) { return String.Format(@"\\{0}\{1}", StorageInfo.ServerName, StorageInfo.ShareName); } else { return GetSharePath(String.Format(@"\\{0}\{1}\{2}", StorageInfo.ServerName, StorageInfo.ShareName, SubPath)); } } } } } else if (Error == 2662) return DFSPath; } finally { NetApiBufferFree(Buffer); } } return null; } public static String GetShareName(String SharePath) { if (!String.IsNullOrEmpty(SharePath)) { String[] Tokens = SharePath.Trim(new Char[] { '\\' }).Split(new Char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries); if (2 <= Tokens.Length) return Tokens[1]; } return null; } }