How to programmatically discover mapped network drives on system and their server names?

前端 未结 7 1319
星月不相逢
星月不相逢 2020-11-28 06:28

I\'m trying to find out how to programmatically (I\'m using C#) determine the name (or i.p.) of servers to which my workstation has current maps. In other words, at some po

相关标签:
7条回答
  • 2020-11-28 07:09

    I've found yet another way of doing this, which uses part of the technique sixlettervariables posted. I'd love some feedback about the pros and cons of the various techniques. For example, does mine have a downside, a scenario where it won't work, for instance?

    [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;
    }
    

    This is called from this code:

    DriveInfo[] drives = DriveInfo.GetDrives();
    foreach (DriveInfo drive in drives)
    {
        bool isLocal = IsLocalDrive(drive.Name);
        if (isLocal)
        {
             // do whatever
        }
    }
    
    0 讨论(0)
  • 2020-11-28 07:09

    Inspired by map network drive path in C# here's another simple method using Scripting objects:

                private static IDictionary<DriveInfo, string> GetMappedNetworkDrives()
            {
                var rawDrives = new IWshRuntimeLibrary.IWshNetwork_Class()
                    .EnumNetworkDrives();
                var result = new Dictionary<DriveInfo, string>(
                    rawDrives.length / 2);
                for (int i = 0; i < rawDrives.length; i += 2)
                {
                    result.Add(
                        new DriveInfo(rawDrives.Item(i)),
                        rawDrives.Item(i + 1));
                }
                return result;
            }
    

    See https://msdn.microsoft.com/en-us/library/t9zt39at(v=vs.84).aspx for details about the IWshNetwork_Class.

    0 讨论(0)
  • 2020-11-28 07:10

    Have you tried to use WMI to do it?

    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);
        }
    }
    

    to make it a little easier to get started download WMI Code Creater

    0 讨论(0)
  • 2020-11-28 07:16

    You could use WMI to enumerate and query mapped drives. The following code enumerates mapped drives, extracts the server name portion, and prints that out.

    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]);
                    }
                }
            }
        }
    }
    

    You can find the documentaiton of the Win32_MappedLogicalDisk class here. An intro for accessing WMI from C# is here.

    0 讨论(0)
  • 2020-11-28 07:16

    The WMI methods won't tell you whether the drive is set to reconnect on login. When you set a drive to reconnect on login, Windows creates a key under HKCU\Network\. The method below can be used to determine if the drive is set to be remapped at login.

    private static bool DriveSetForReconnect(string ComputerName, string DriveLetter)
    {
        RegistryKey key = RegistryKey.OpenRemoteBaseKey(RegistryHive.CurrentUser, ComputerName);
        key = key.OpenSubKey("Network\\" + DriveLetter);
    
        return key != null;
    }
    

    HTH!

    EDIT: To adapt the WMI solutions to work on any arbitrary machine, you need to change the scope parameter like the code below. You obviously have to have have admin rights on the remote machine.

    string scope = string.Format(@"\\{0}\root\CIMV2", ComputerName);
    
    ManagementObjectSearcher searcher =
        new ManagementObjectSearcher(scope,
        "SELECT * FROM Win32_MappedLogicalDisk");
    
    0 讨论(0)
  • 2020-11-28 07:17

    We can also use net use to find IP or Computer Name of mapped network drive

    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();
    }
    
    0 讨论(0)
提交回复
热议问题