给定一个DFS路径我怎么会知道什么是有效的路径是目前编程。我怎样才能在DFS得到一个积极的UNC路径编程
对于〔实施例我有2个服务器股份"\\Server1\Folder\"
和"\\Server2\Folder\"
,它有DFS开启,以便它可以在"\\DFS_Server\Folder\"
访问,我怎么会知道什么是活动路径目前"\\DFS_Server\Folder\"
是,无论是"\\Server1\Folder\"
或"\\Server2\Folder\"
。
给定一个DFS路径我怎么会知道什么是有效的路径是目前编程。我怎样才能在DFS得到一个积极的UNC路径编程
对于〔实施例我有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<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;
}
}
使用方法如下:
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;
}
}
我发现了小模式。所以dfs解析是可以修复的。假设你正在寻找unc a。每次迭代需要从a的开始处移除EntryPath,并重新构建它(前缀ServerName和ShareName的前缀,您从StorageInfo获取),接收unc b。如果a == b分辨率完成。 – user3042599 2014-01-27 12:41:24
NetDfsGetInfo触发错误1168(未找到),这是有线的,所以我使用NetDfsGetClientInfo。这一个只返回主动存储的数据。对于非活动存储,它什么都不返回。解决办法 - 在调用NetDfsGetClientInfo之前,在unc路径上使用System.IO.Directory.Exists(...)。 – user3042599 2014-01-27 12:48:11
可以在VBS中使用NetDfsGetClientInfo,也许使用WMI? – Lizz 2014-01-29 04:46:14
会如何VBS上述外观使用WMI?任何指导将不胜感激。 – Lizz 2014-01-29 04:51:13