給定一個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