Введение
В процессе разработки приложений на C# иногда возникает необходимость монтировать сетевые диски напрямую из кода. Однако .NET Framework и .NET Core не предоставляют встроенных средств для работы с сетевыми ресурсами такого типа. Это может стать проблемой для разработчиков, которым нужно автоматизировать подключение сетевых хранилищ, например, в корпоративных приложениях.
Почему стандартных средств .NET недостаточно?
Несмотря на широкие возможности .NET, в нем отсутствуют нативные методы для подключения к сетевым папкам с указанием имени пользователя и пароля. В результате приходится использовать дополнительные инструменты – например, низкоуровневый API Windows.
Решение: использование Win32 API
Для решения этой задачи можно использовать функции из набора Win32 API:
WNetAddConnection2A
— подключение сетевого ресурса;WNetCancelConnection2A
— отключение подключенного ресурса.
Эти функции позволяют не только подключить сетевой диск, но и задать учетные данные для
доступа к нему.
Пример кода на C# для подключения сетевого диска
using System.Runtime.InteropServices; public class NetworkDrive { private enum ResourceScope { RESOURCE_CONNECTED = 1, RESOURCE_GLOBALNET, RESOURCE_REMEMBERED, RESOURCE_RECENT, RESOURCE_CONTEXT } private enum ResourceType { RESOURCETYPE_ANY, RESOURCETYPE_DISK, RESOURCETYPE_PRINT, RESOURCETYPE_RESERVED } private enum ResourceUsage { RESOURCEUSAGE_CONNECTABLE = 0x00000001, RESOURCEUSAGE_CONTAINER = 0x00000002, RESOURCEUSAGE_NOLOCALDEVICE = 0x00000004, RESOURCEUSAGE_SIBLING = 0x00000008, RESOURCEUSAGE_ATTACHED = 0x00000010 } private enum ResourceDisplayType { RESOURCEDISPLAYTYPE_GENERIC, RESOURCEDISPLAYTYPE_DOMAIN, RESOURCEDISPLAYTYPE_SERVER, RESOURCEDISPLAYTYPE_SHARE, RESOURCEDISPLAYTYPE_FILE, RESOURCEDISPLAYTYPE_GROUP, RESOURCEDISPLAYTYPE_NETWORK, RESOURCEDISPLAYTYPE_ROOT, RESOURCEDISPLAYTYPE_SHAREADMIN, RESOURCEDISPLAYTYPE_DIRECTORY, RESOURCEDISPLAYTYPE_TREE, RESOURCEDISPLAYTYPE_NDSCONTAINER } [StructLayout(LayoutKind.Sequential)] private struct NETRESOURCE { public ResourceScope oResourceScope; public ResourceType oResourceType; public ResourceDisplayType oDisplayType; public ResourceUsage oResourceUsage; public string sLocalName; public string sRemoteName; public string sComments; public string sProvider; } [DllImport("mpr.dll")] private static extern int WNetAddConnection2 (ref NETRESOURCE oNetworkResource, string sPassword, string sUserName, int iFlags); [DllImport("mpr.dll")] private static extern int WNetCancelConnection2 (string sLocalName, uint iFlags, int iForce); public static void MapNetworkDrive(string sDriveLetter, string sNetworkPath) { //Checks if the last character is \ as this causes error on mapping a drive. if (sNetworkPath.Substring(sNetworkPath.Length - 1, 1) == @"\") { sNetworkPath = sNetworkPath.Substring(0, sNetworkPath.Length - 1); } NETRESOURCE oNetworkResource = new NETRESOURCE() { oResourceType = ResourceType.RESOURCETYPE_DISK, sLocalName = sDriveLetter + ":", sRemoteName = sNetworkPath }; //If Drive is already mapped disconnect the current //mapping before adding the new mapping if (IsDriveMapped(sDriveLetter)) { DisconnectNetworkDrive(sDriveLetter, true); } WNetAddConnection2(ref oNetworkResource, null, null, 0); } public static int DisconnectNetworkDrive(string sDriveLetter, bool bForceDisconnect) { if (bForceDisconnect) { return WNetCancelConnection2(sDriveLetter + ":", 0, 1); } else { return WNetCancelConnection2(sDriveLetter + ":", 0, 0); } } public static bool IsDriveMapped(string sDriveLetter) { string[] DriveList = Environment.GetLogicalDrives(); for (int i = 0; i < DriveList.Length; i++) { if (sDriveLetter + ":\\" == DriveList[i].ToString()) { return true; } } return false; } }
Код для подключения диска :
NetworkDrive.MapNetworkDrive("X", @"\\unc\path");
и для отключения:
NetworkDrive.DisconnectNetworkDrive("X", true);
Заключение
Подключение сетевых дисков в C# возможно даже без встроенных средств платформы .NET. Использование Win32 API через PInvoke позволяет гибко управлять подключениями, включая передачу учетных данных. Такой подход пригодится в автоматизации корпоративных задач, встраивании в системные утилиты и при разработке приложений для Windows.