ver usuario unidades unidad una sesion saber ruta puede problemas para mapear mapeadas mac iniciar contraseña conectar con como bat archivo c# .net windows

c# - usuario - problemas conectar unidad de red windows 10



¿Cómo descubrir programáticamente las unidades de red mapeadas en el sistema y sus nombres de servidor? (7)

Estoy tratando de averiguar cómo programáticamente (estoy usando C #) determinar el nombre (o ip) de los servidores a los que mi estación de trabajo tiene mapas actuales. En otras palabras, en algún momento en Windows Explorer mapeé una unidad de red en una letra de unidad (o usé "net use w:" para mapearla). Sé cómo obtener las unidades de red en el sistema:

DriveInfo[] allDrives = DriveInfo.GetDrives(); foreach (DriveInfo d in allDrives) { if (d.IsReady && d.DriveType == DriveType.Network) { } }

Pero la clase DriveInfo no tiene propiedades que me digan a qué servidor y carpeta compartida está asociada la unidad mapeada. ¿Hay algún otro lugar donde debería estar mirando?


Desafortunadamente tiene que usar WinAPI a través de P / Invoke. Se requerirá el uso de WNetGetUniversalName y la estructura UNIVERSAL_NAME_INFO . Comprueba que si expandir la ruta usando GetFullPath no es igual a lo que es el nombre universal para la ruta expandida, entonces sabe que está mapeado. El pseudocódigo básico es el siguiente (comprobación de errores 0, mínimo absoluto):

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

Aquí están las declaraciones de P / Invoke, que deberían ayudarlo a lo largo de su camino:

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


Podría usar WMI para enumerar y consultar unidades mapeadas. El siguiente código enumera las unidades mapeadas, extrae la parte del nombre del servidor y las imprime.

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

Puede encontrar la documentación de la clase Win32_MappedLogicalDisk aquí . Una introducción para acceder a WMI desde C # está aquí .


He encontrado otra forma de hacerlo, que utiliza parte de la técnica sixlettervariables publicadas. Me gustaría recibir algunos comentarios sobre los pros y los contras de las diversas técnicas. Por ejemplo, ¿el mío tiene una desventaja, un escenario donde no funcionará, por ejemplo?

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

Esto se llama desde este código:

DriveInfo[] drives = DriveInfo.GetDrives(); foreach (DriveInfo drive in drives) { bool isLocal = IsLocalDrive(drive.Name); if (isLocal) { // do whatever } }


Los métodos de WMI no le dirán si la unidad está configurada para volverse a conectar al iniciar sesión. Cuando configura una unidad para volver a conectarse al iniciar sesión, Windows crea una clave en HKCU / Network /. El siguiente método se puede usar para determinar si la unidad está configurada para ser reasignada al iniciar sesión.

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

HTH!

EDITAR: Para adaptar las soluciones WMI para que funcionen en cualquier máquina arbitraria, debe cambiar el parámetro de ámbito como el código siguiente. Obviamente tiene que tener derechos de administrador en la máquina remota.

string scope = string.Format(@"//{0}/root/CIMV2", ComputerName); ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, "SELECT * FROM Win32_MappedLogicalDisk");


¿Has intentado utilizar WMI para hacerlo?

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

para que sea un poco más fácil para empezar a descargar WMI Code Creater


También podemos usar el uso de la red para encontrar la IP o el nombre del equipo de la unidad de red asignada.

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


Inspirado por la ruta de la unidad de red de mapas en C #, aquí hay otro método simple que utiliza objetos de scripting:

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

Consulte https://msdn.microsoft.com/en-us/library/t9zt39at(v=vs.84).aspx para obtener más información sobre IWshNetwork_Class.