using System; using System.IO; using System.Runtime.InteropServices; using System.Text; using System.ComponentModel; public class NetworkShareAccess : IDisposable { private readonly string _networkPath; private readonly string _username; private readonly string _password; private bool _isConnected = false; public NetworkShareAccess(string networkPath, string username, string password) { // Validate and normalize the network path _networkPath = networkPath?.Trim().Replace('/', '\\') ?? throw new ArgumentNullException(nameof(networkPath)); if (!_networkPath.StartsWith(@"\\")) { throw new ArgumentException("Network path must start with \\\\"); } _username = username ?? throw new ArgumentNullException(nameof(username)); _password = password ?? throw new ArgumentNullException(nameof(password)); } public void ConnectToNetworkPath() { if (_isConnected) return; var netResource = new NetResource { Scope = ResourceScope.GlobalNetwork, ResourceType = ResourceType.Disk, DisplayType = ResourceDisplayType.Share, RemoteName = _networkPath }; int result = WNetAddConnection2(netResource, _password, _username, 0); if (result != 0) { string errorMessage = GetNetworkErrorDescription(result); Console.WriteLine($"Failed to connect to {_networkPath}. Error {result}: {errorMessage}"); throw new IOException($"Failed to connect to network path. Error {result}: {errorMessage}"); } _isConnected = true; Console.WriteLine($"Successfully connected to {_networkPath}"); } public void DisconnectFromNetworkShare() { if (!_isConnected) return; try { int result = WNetCancelConnection2(_networkPath, 0, true); if (result != 0) { string errorMessage = GetNetworkErrorDescription(result); Console.WriteLine($"Failed to disconnect from {_networkPath}. Error {result}: {errorMessage}"); throw new IOException($"Failed to disconnect from network path. Error {result}: {errorMessage}"); } Console.WriteLine($"Successfully disconnected from {_networkPath}"); } finally { _isConnected = false; } } public void Dispose() { try { DisconnectFromNetworkShare(); } catch (Exception ex) { Console.WriteLine($"Error during disposal: {ex.Message}"); // Suppress disposal errors } } private string GetNetworkErrorDescription(int errorCode) { return errorCode switch { 5 => "Access denied", 53 => "Network path not found", 67 => "Network name not found", 85 => "Network connection already exists", 86 => "Invalid password", 1219 => "Multiple connections to a server or shared resource not allowed", _ => new Win32Exception(errorCode).Message }; } [DllImport("mpr.dll", CharSet = CharSet.Unicode)] private static extern int WNetAddConnection2(NetResource netResource, string password, string username, int flags); [DllImport("mpr.dll", CharSet = CharSet.Unicode)] private static extern int WNetCancelConnection2(string name, int flags, bool force); [DllImport("mpr.dll", CharSet = CharSet.Unicode)] private static extern int WNetGetConnection(string localName, StringBuilder remoteName, ref int length); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private class NetResource { public ResourceScope Scope; public ResourceType ResourceType; public ResourceDisplayType DisplayType; public int Usage; public string LocalName; public string RemoteName; public string Comment; public string Provider; } private enum ResourceScope { Connected = 1, GlobalNetwork, Remembered, Recent, Context } private enum ResourceType { Any = 0, Disk = 1, Print = 2, Reserved = 8 } private enum ResourceDisplayType { Generic = 0x0, Domain = 0x01, Server = 0x02, Share = 0x03, File = 0x04, Group = 0x05 } }