C# 如何以编程方式在DFS中获取活动UNC路径
给定DFS路径,我如何知道它当前在编程上的活动路径是什么C# 如何以编程方式在DFS中获取活动UNC路径,c#,wmi,microsoft-distributed-file-system,C#,Wmi,Microsoft Distributed File System,给定DFS路径,我如何知道它当前在编程上的活动路径是什么 对于exmaple,我有两个服务器共享,分别为“\\Server1\Folder\”和“\\Server2\Folder\”,并且它已打开DFS,因此可以在“\\DFS\u Server\Folder\”上访问它,我如何知道当前的活动路径是什么“\\DFS\u Server\Folder\”,它是“\\Server1\Folder\”还是“\\Server2\Folder\”尝试此操作,其中sDFSPath是要查询的路径,sHostSer
对于exmaple,我有两个服务器共享,分别为
“\\Server1\Folder\”
和“\\Server2\Folder\”
,并且它已打开DFS,因此可以在“\\DFS\u Server\Folder\”
上访问它,我如何知道当前的活动路径是什么“\\DFS\u 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<T>(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<DFS_INFO_3>(b);
if(sRes.NumberOfStorages > 0)
{
DFS_STORAGE_INFO sResInfo = GetStruct<DFS_STORAGE_INFO>(sRes.Storage);
rval = string.Concat(@"\\", sResInfo.ServerName, @"\", sResInfo.ShareName, @"\");
}
NetApiBufferFree(b);
return rval;
}
}
有关API参考,请查看msdn on,和。谢谢,您的提示很有用。但是,我使用NetDfsGetClientInfo更成功。我还意识到解析过程可能是递归的。我最后至少进行了两次递归调用以获得实际的物理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;
}
}
公共静态类DFS
{
#地区进口
[DllImport(“Netapi32.dll”,EntryPoint=“NetApiBufferFree”)]
公共静态外部单元NetApiBufferFree(IntPtr Buffer);
[DllImport(“Netapi32.dll”,CharSet=CharSet.Unicode,SetLastError=true)]
公共静态外部int NetDfsGetInfo(
[Marshallas(UnmanagedType.LPWStr)]字符串入口路径,
[Marshallas(UnmanagedType.LPWStr)]字符串服务器名,
[Marshallas(UnmanagedType.LPWStr)]字符串共享名,
整数级,
输出IntPtr缓冲区);
[DllImport(“Netapi32.dll”)]
公共静态外部int NetDfsGetClientInfo(
[Marshallas(UnmanagedType.LPWStr)]字符串入口路径,
[Marshallas(UnmanagedType.LPWStr)]字符串服务器名,
[Marshallas(UnmanagedType.LPWStr)]字符串共享名,
整数级,
输出IntPtr缓冲区);
#端区
#区域结构
公共结构DFS\u信息\u 3
{
[Marshallas(UnmanagedType.LPWStr)]
公共字符串入口路径;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串评论;
公共UInt32州;
公共存储单元32个;
公共IntPtr存储;
}
公共结构DFS\u存储\u信息
{
国家公共部门;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串ServerName;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串共享名;
}
#端区
常量int DFS\u卷\u状态\u OK=0x00000001;
const int DFS\u VOLUME\u STATE\u ONLINE=0x00000004;
const int DFS_STORAGE_STATE_ONLINE=0x00000002;
常量int DFS\u存储\u状态\u活动=0x00000004;
公共静态字符串GetSharePath(字符串DFSPath)
{
如果(!String.IsNullOrEmpty(DFSPath))
{
IntPtr Buffer=IntPtr.Zero;
尝试
{
int Error=NetDfsGetClientInfo(DFSPath,null,null,3,输出缓冲区);
如果(错误==0)
{
DFS_INFO_3 DFSInfo=(DFS_INFO_3)Marshal.ptr结构(缓冲区,类型(DFS_INFO_3));
如果((DFSInfo.State&DFS\u VOLUME\u State\u OK)>0)
{
String SubPath=DFSPath.Remove(0,1+DFSInfo.EntryPath.Length).TrimStart(新字符[]{'\\'});
对于(int i=0;i0)
{
if(String.IsNullOrEmpty(子路径))
{
返回String.Format(@“\\{0}\{1}”、StorageInfo.ServerName、StorageInfo.ShareName);
}
其他的
{
返回GetSharePath(String.Format(@“\{0}\{1}\{2}”、StorageInfo.ServerName、StorageInfo.ShareName、SubPath));
}
}
}
}
}
否则如果(错误==2662)
返回路径;
}
最后
{
NetapipBufferFree(缓冲区);
}
}
返回null;
}
公共静态字符串GetShareName(字符串SharePath)
{
如果(!String.IsNullOrEmpty(SharePath))
{
String[]Tokens=SharePath.Trim(新字符[]{'\\'}).Split(新字符[]{'\\'},StringSplitOptions.RemoveEmptyEntries);
如果(2)我发现了小模式。因此dfs解析是可重复的。假设您正在查找unc a。每次迭代都需要从a的开头删除EntryPath,并重新生成它(前缀为ServerName和ShareName,您从StorageInfo获得),以接收unc b。如果a==b解析已完成。NetDfsGetInfo触发错误1168(未找到),这是有线的,所以我使用了NetDfsGetClientInfo。这一个只返回活动存储的数据。对于非活动存储,它不返回任何数据。解决方法是使用System.IO.Directory.Exists(…)在调用NetDfsGetClientInfo之前在您的unc路径上。NetDfsGetClientInfo是否可以在VBS中使用,也许可以与WMI一起使用?从int Error=NetDfsGetClientInfo(DFSPath,null,null,3,out Buffer)获取2662代码;如果有任何解决问题的建议,上面的内容在VBS中使用WMI时会是什么样子?如果有任何指导,我们将不胜感激。@Raymund我看到您通过了ho
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;
}
}