Подключение сетевого диска на C#

Введение

В процессе разработки приложений на 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.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.