Mon*_*yak 7 c# wmi microsoft-distributed-file-system
给定DFS路径,我如何知道它当前以编程方式存在的活动路径.
例如,我有2个服务器共享"\\Server1\Folder\","\\Server2\Folder\"并且它已打开DFS,因此可以访问它"\\DFS_Server\Folder\",我怎么知道当前所处的活动路径"\\DFS_Server\Folder\"是什么,无论是"\\Server1\Folder\"或"\\Server2\Folder\".
如果我正确理解您的要求,那么还有一个似乎可以满足您需求的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;
}
}
Run Code Online (Sandbox Code Playgroud)
像这样使用它:
string dfsPath = @"\\DFS_Server\Folder\";
string share = Dfs.GetDfsInfo(dfsPath)
Run Code Online (Sandbox Code Playgroud)
有关API参考,请检查NetDfsGetInfo,DFS_INFO_3,DFS_STORAGE_INFO和NetApiBufferFree上的msdn.
尝试一下,其中 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;
}
Run Code Online (Sandbox Code Playgroud)
希望这是有道理的
| 归档时间: |
|
| 查看次数: |
8024 次 |
| 最近记录: |