我正在尝试找出如何以编程方式(我正在使用C#)确定我的工作站当前映射的服务器的名称(或i.p.)。换句话说,在Windows资源管理器中的某个时刻,我将网络驱动器映射到驱动器号(或使用“net use w:”来映射它)。我知道如何在系统上获得网络驱动器:
DriveInfo[] allDrives = DriveInfo.GetDrives();
foreach (DriveInfo d in allDrives)
{
if (d.IsReady && d.DriveType == DriveType.Network)
{
}
}
但DriveInfo类没有告诉我映射驱动器所关联的服务器和共享文件夹的属性。还有其他地方我应该看吗?
答案 0 :(得分:26)
您是否曾尝试使用WMI进行此操作?
using System;
using System.Management;
using System.Windows.Forms;
public static void Main()
{
try
{
var searcher = new ManagementObjectSearcher(
"root\\CIMV2",
"SELECT * FROM Win32_MappedLogicalDisk");
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("-----------------------------------");
Console.WriteLine("Win32_MappedLogicalDisk instance");
Console.WriteLine("-----------------------------------");
Console.WriteLine("Access: {0}", queryObj["Access"]);
Console.WriteLine("Availability: {0}", queryObj["Availability"]);
Console.WriteLine("BlockSize: {0}", queryObj["BlockSize"]);
Console.WriteLine("Caption: {0}", queryObj["Caption"]);
Console.WriteLine("Compressed: {0}", queryObj["Compressed"]);
Console.WriteLine("ConfigManagerErrorCode: {0}", queryObj["ConfigManagerErrorCode"]);
Console.WriteLine("ConfigManagerUserConfig: {0}", queryObj["ConfigManagerUserConfig"]);
Console.WriteLine("CreationClassName: {0}", queryObj["CreationClassName"]);
Console.WriteLine("Description: {0}", queryObj["Description"]);
Console.WriteLine("DeviceID: {0}", queryObj["DeviceID"]);
Console.WriteLine("ErrorCleared: {0}", queryObj["ErrorCleared"]);
Console.WriteLine("ErrorDescription: {0}", queryObj["ErrorDescription"]);
Console.WriteLine("ErrorMethodology: {0}", queryObj["ErrorMethodology"]);
Console.WriteLine("FileSystem: {0}", queryObj["FileSystem"]);
Console.WriteLine("FreeSpace: {0}", queryObj["FreeSpace"]);
Console.WriteLine("InstallDate: {0}", queryObj["InstallDate"]);
Console.WriteLine("LastErrorCode: {0}", queryObj["LastErrorCode"]);
Console.WriteLine("MaximumComponentLength: {0}", queryObj["MaximumComponentLength"]);
Console.WriteLine("Name: {0}", queryObj["Name"]);
Console.WriteLine("NumberOfBlocks: {0}", queryObj["NumberOfBlocks"]);
Console.WriteLine("PNPDeviceID: {0}", queryObj["PNPDeviceID"]);
if(queryObj["PowerManagementCapabilities"] == null)
Console.WriteLine("PowerManagementCapabilities: {0}", queryObj["PowerManagementCapabilities"]);
else
{
UInt16[] arrPowerManagementCapabilities = (UInt16[])(queryObj["PowerManagementCapabilities"]);
foreach (UInt16 arrValue in arrPowerManagementCapabilities)
{
Console.WriteLine("PowerManagementCapabilities: {0}", arrValue);
}
}
Console.WriteLine("PowerManagementSupported: {0}", queryObj["PowerManagementSupported"]);
Console.WriteLine("ProviderName: {0}", queryObj["ProviderName"]);
Console.WriteLine("Purpose: {0}", queryObj["Purpose"]);
Console.WriteLine("QuotasDisabled: {0}", queryObj["QuotasDisabled"]);
Console.WriteLine("QuotasIncomplete: {0}", queryObj["QuotasIncomplete"]);
Console.WriteLine("QuotasRebuilding: {0}", queryObj["QuotasRebuilding"]);
Console.WriteLine("SessionID: {0}", queryObj["SessionID"]);
Console.WriteLine("Size: {0}", queryObj["Size"]);
Console.WriteLine("Status: {0}", queryObj["Status"]);
Console.WriteLine("StatusInfo: {0}", queryObj["StatusInfo"]);
Console.WriteLine("SupportsDiskQuotas: {0}", queryObj["SupportsDiskQuotas"]);
Console.WriteLine("SupportsFileBasedCompression: {0}", queryObj["SupportsFileBasedCompression"]);
Console.WriteLine("SystemCreationClassName: {0}", queryObj["SystemCreationClassName"]);
Console.WriteLine("SystemName: {0}", queryObj["SystemName"]);
Console.WriteLine("VolumeName: {0}", queryObj["VolumeName"]);
Console.WriteLine("VolumeSerialNumber: {0}", queryObj["VolumeSerialNumber"]);
}
}
catch (ManagementException ex)
{
MessageBox.Show("An error occurred while querying for WMI data: " + ex.Message);
}
}
让您开始下载WMI Code Creater
更容易一些答案 1 :(得分:13)
您可以使用WMI枚举和查询映射的驱动器。以下代码枚举映射的驱动器,提取服务器名称部分,并将其打印出来。
using System;
using System.Text.RegularExpressions;
using System.Management;
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
ManagementObjectSearcher searcher = new ManagementObjectSearcher(
"select * from Win32_MappedLogicalDisk");
foreach (ManagementObject drive in searcher.Get()) {
Console.WriteLine(Regex.Match(
drive["ProviderName"].ToString(),
@"\\\\([^\\]+)").Groups[1]);
}
}
}
}
}
答案 2 :(得分:8)
WMI方法不会告诉您驱动器是否设置为在登录时重新连接。当您在登录时将驱动器设置为重新连接时,Windows会在HKCU \ Network \下创建一个密钥。以下方法可用于确定是否将驱动器设置为在登录时重新映射。
private static bool DriveSetForReconnect(string ComputerName, string DriveLetter)
{
RegistryKey key = RegistryKey.OpenRemoteBaseKey(RegistryHive.CurrentUser, ComputerName);
key = key.OpenSubKey("Network\\" + DriveLetter);
return key != null;
}
HTH!
编辑: 要使WMI解决方案适用于任何任意计算机,您需要更改范围参数,如下面的代码。您显然必须拥有远程计算机的管理员权限。
string scope = string.Format(@"\\{0}\root\CIMV2", ComputerName);
ManagementObjectSearcher searcher =
new ManagementObjectSearcher(scope,
"SELECT * FROM Win32_MappedLogicalDisk");
答案 3 :(得分:5)
您遗憾的是必须通过P / Invoke使用WinAPI。它需要使用WNetGetUniversalName和UNIVERSAL_NAME_INFO结构。您检查如果使用GetFullPath扩展路径不等于扩展路径的通用名称,那么您知道它已映射。基本伪代码如下(0错误检查,最低限度):
var nfo = new UNIVERSAL_NAME_INFO();
var size = Marshal.SizeOf(nfo);
if (ERROR_MORE_DATA == WNetGetUniversalName(path, InfoLevel.UniversalName,
ref nfo, ref size)
{
var buffer = Marshal.AllocHGlobal(size);
if (NO_ERROR == WNetGetUniversalName(path, InfoLevel.UniversalName,
buffer, ref size))
{
nfo = (UNIVERSAL_NAME_INFO)Marshal.PtrToStructure(buffer,
typeof(UNIVERSAL_NAME_INFO));
}
}
以下是P / Invoke声明,它可以帮助您:
internal class NativeMethods
{
/// <summary>
/// The type of structure that the function stores in the buffer.
/// </summary>
public enum InfoLevel
{
/// <summary>
/// The function stores a <see cref="UNIVERSAL_NAME_INFO"/> structure in the
/// buffer.
/// </summary>
UniversalName = 1,
/// <summary>
/// The function stores a <c>REMOTE_NAME_INFO</c> structure in the buffer.
/// </summary>
/// <remarks>
/// Using this level will throw an <see cref="NotSupportedException"/>.
/// </remarks>
RemoteName = 2
}
/// <summary>
/// The <see cref="WNetGetUniversalName(string,int,UNIVERSAL_NAME_INFO,int)"/> function
/// takes a drive-based path for a network resource and returns an information
/// structure that contains a more universal form of the name.
/// </summary>
/// <param name="lpLocalPath">A pointer to a constant null-terminated string that
/// is a drive-based path for a network resource.</param>
/// <param name="dwInfoLevel">The type of structure that the function stores in
/// the buffer pointed to by the <paramref name="lpBuffer"/> parameter.</param>
/// <param name="lpBuffer">A pointer to a buffer that receives the structure
/// specified by the <paramref name="dwInfoLevel"/> parameter.</param>
/// <param name="lpBufferSize">A pointer to a variable that specifies the size,
/// in bytes, of the buffer pointed to by the <paramref name="lpBuffer"/> parameter.</param>
/// <returns>If the function succeeds, the return value is <see cref="NO_ERROR"/>.</returns>
[DllImport("mpr.dll", CharSet = CharSet.Auto)]
public static extern int WNetGetUniversalName(
string lpLocalPath,
InfoLevel dwInfoLevel,
ref UNIVERSAL_NAME_INFO lpBuffer,
ref int lpBufferSize);
/// <summary>
/// The <see cref="WNetGetUniversalName(string,int,IntPtr,int)"/> function
/// takes a drive-based path for a network resource and returns an information
/// structure that contains a more universal form of the name.
/// </summary>
/// <param name="lpLocalPath">A pointer to a constant null-terminated string that
/// is a drive-based path for a network resource.</param>
/// <param name="dwInfoLevel">The type of structure that the function stores in
/// the buffer pointed to by the <paramref name="lpBuffer"/> parameter.</param>
/// <param name="lpBuffer">A pointer to a buffer that receives the structure
/// specified by the <paramref name="dwInfoLevel"/> parameter.</param>
/// <param name="lpBufferSize">A pointer to a variable that specifies the size,
/// in bytes, of the buffer pointed to by the <paramref name="lpBuffer"/> parameter.</param>
/// <returns>If the function succeeds, the return value is <see cref="NO_ERROR"/>.</returns>
[DllImport("mpr.dll", CharSet = CharSet.Auto)]
public static extern int WNetGetUniversalName(
string lpLocalPath,
InfoLevel dwInfoLevel,
IntPtr lpBuffer,
ref int lpBufferSize);
/// <summary>
/// The <see cref="UNIVERSAL_NAME_INFO"/> structure contains a pointer to a
/// Universal Naming Convention (UNC) name string for a network resource.
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct UNIVERSAL_NAME_INFO
{
/// <summary>
/// Pointer to the null-terminated UNC name string that identifies a
/// network resource.
/// </summary>
[MarshalAs(UnmanagedType.LPTStr)]
public string lpUniversalName;
}
}
答案 4 :(得分:5)
我发现了另一种方法,它使用了发布的六个变量技术的一部分。我喜欢一些关于各种技术的优点和缺点的反馈。例如,我的是否有缺点,例如它无法工作的情况?
[DllImport("mpr.dll")]
static extern uint WNetGetConnection(string lpLocalName, StringBuilder lpRemoteName, ref int lpnLength);
internal static bool IsLocalDrive(String driveName)
{
bool isLocal = true; // assume local until disproved
// strip trailing backslashes from driveName
driveName = driveName.Substring(0, 2);
int length = 256; // to be on safe side
StringBuilder networkShare = new StringBuilder(length);
uint status = WNetGetConnection(driveName, networkShare, ref length);
// does a network share exist for this drive?
if (networkShare.Length != 0)
{
// now networkShare contains a UNC path in format \\MachineName\ShareName
// retrieve the MachineName portion
String shareName = networkShare.ToString();
string[] splitShares = shareName.Split('\\');
// the 3rd array element now contains the machine name
if (Environment.MachineName == splitShares[2])
isLocal = true;
else
isLocal = false;
}
return isLocal;
}
这是从这段代码中调用的:
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (DriveInfo drive in drives)
{
bool isLocal = IsLocalDrive(drive.Name);
if (isLocal)
{
// do whatever
}
}
答案 5 :(得分:0)
我们还可以使用net use查找映射网络驱动器的IP或计算机名称
Process process = new Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Arguments = "/c net use";
process.Start();
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
string driveName = "Y:";
var line = output.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
.Where(x => x.Contains(driveName)).FirstOrDefault();
if (!string.IsNullOrEmpty(line))
{
var host = line.Substring(line.IndexOf("\\"), line.Substring(line.IndexOf("\\")).IndexOf(" ")).Split(new[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
}
答案 6 :(得分:0)
受到map network drive path in C#的启发,这是使用脚本对象的另一种简单方法:
Manual
有关IWshNetwork_Class的详细信息,请参阅https://msdn.microsoft.com/en-us/library/t9zt39at(v=vs.84).aspx。