从 C# 中的 DFS 路径获取 DFS 文件夹目标(本地服务器路径)
Get DFS folder target (local server path) from a DFS path in C#
我有一个DFS文件夹路径...
\domain.name\SharesRoot\DFSShare
我需要获取此根目录的实际文件夹目标 link 或者换句话说,DFSShare 定位的本地服务器路径
本地服务器path/folder目标如下
\MyServer\Share\MyShare
我已经成功地使用 NetDfsGetClientInfo() 方法从给定的 DFS 路径中检索了一些需要的信息
此方法填充的 DFS_STORAGE_INFO 对象为我提供了以下数据
- 状态:不相关数据
- 服务器名称:'MyServer'
- 共享名:'SharesRoot'
虽然我正在寻找 ServerName,但 ShareName 对我毫无帮助。
我需要找出路径在什么地方 MyServer
那个DFS路径 \domain.name\SharesRoot\DFSShare
正在瞄准
NetDfsGetInfo() 给我 1168 错误,所以那个方法没有帮助,我还没有尝试 NetDfsEnum() ,但是我的希望并不高,因为它填充了与 NetDfsGetClientInfo() 相同的结构...如果有人在这里有任何其他线索,我将非常感激!
看来 NetDfsGetClientInfo() 确实是满足我特殊需求的答案。
问题是它的行为会根据它是在 DFS 客户端计算机上调用还是在 DFS 服务器计算机上调用而改变。
在客户端机器上调用 returns 具有以下数据的 DFS_STORAGE_INFO 对象:
- 服务器名称:'MyServer'
- 共享名:'Share'
返回后所需要做的就是附加子路径,可以使用 DFS_INFO_3 对象的入口路径和 NetDfsGetClientInfo() 调用中使用的原始路径删除子路径
我发现在客户端上我需要首先访问 DFS 路径,然后 Windows 中的某些东西缓存它,这样当我执行 NetDfsGetClientInfo() 时我得到了底层路径(不是 dfs路径)
所以这对我有用:
string dfsPath = "\domain.name\SharesRoot\DFSShare";
//by doing Directory.Exists we access the DFS path, causing Windows to resolve it
if (Directory.Exists(dfsPath))
{
string dfsPath = DFS.GetSharePath(dfsPath);
MessageBox.Show($"{dfsPath});
}
这是我在别处找到的 class 代码(不是我的)
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
{
Console.WriteLine("User : {0}, Domain= {1}", Environment.UserName, Environment.UserDomainName);
Console.WriteLine("Path is {0}", DFSPath);
int Error = NetDfsGetClientInfo(DFSPath, null, null, 3, out Buffer);
Console.WriteLine("Error code {0}", Error);
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 (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文件夹路径...
\domain.name\SharesRoot\DFSShare
我需要获取此根目录的实际文件夹目标 link 或者换句话说,DFSShare 定位的本地服务器路径
本地服务器path/folder目标如下
\MyServer\Share\MyShare
我已经成功地使用 NetDfsGetClientInfo() 方法从给定的 DFS 路径中检索了一些需要的信息
此方法填充的 DFS_STORAGE_INFO 对象为我提供了以下数据
- 状态:不相关数据
- 服务器名称:'MyServer'
- 共享名:'SharesRoot'
虽然我正在寻找 ServerName,但 ShareName 对我毫无帮助。
我需要找出路径在什么地方 MyServer
那个DFS路径 \domain.name\SharesRoot\DFSShare
正在瞄准
NetDfsGetInfo() 给我 1168 错误,所以那个方法没有帮助,我还没有尝试 NetDfsEnum() ,但是我的希望并不高,因为它填充了与 NetDfsGetClientInfo() 相同的结构...如果有人在这里有任何其他线索,我将非常感激!
看来 NetDfsGetClientInfo() 确实是满足我特殊需求的答案。
问题是它的行为会根据它是在 DFS 客户端计算机上调用还是在 DFS 服务器计算机上调用而改变。
在客户端机器上调用 returns 具有以下数据的 DFS_STORAGE_INFO 对象:
- 服务器名称:'MyServer'
- 共享名:'Share'
返回后所需要做的就是附加子路径,可以使用 DFS_INFO_3 对象的入口路径和 NetDfsGetClientInfo() 调用中使用的原始路径删除子路径
我发现在客户端上我需要首先访问 DFS 路径,然后 Windows 中的某些东西缓存它,这样当我执行 NetDfsGetClientInfo() 时我得到了底层路径(不是 dfs路径)
所以这对我有用:
string dfsPath = "\domain.name\SharesRoot\DFSShare";
//by doing Directory.Exists we access the DFS path, causing Windows to resolve it
if (Directory.Exists(dfsPath))
{
string dfsPath = DFS.GetSharePath(dfsPath);
MessageBox.Show($"{dfsPath});
}
这是我在别处找到的 class 代码(不是我的)
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
{
Console.WriteLine("User : {0}, Domain= {1}", Environment.UserName, Environment.UserDomainName);
Console.WriteLine("Path is {0}", DFSPath);
int Error = NetDfsGetClientInfo(DFSPath, null, null, 3, out Buffer);
Console.WriteLine("Error code {0}", Error);
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 (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;
}
}