I want to access share and cancel access when I need to. I use the following code:
class Program
{
const string Share = "\\\\srv\\share";
static void ListFiles()
{
foreach (var dir in Directory.EnumerateDirectories(Share))
Console.WriteLine(dir);
}
static void Main(string[] args)
{
using (var connection = new NetworkConnection(Share, new System.Net.NetworkCredential("user", "password")))
ListFiles();
ListFiles();
}
}
First ListFiles() call succeeds. I expect second ListFiles() call to fail but it also succeeds. How to cancel connection properly? Seems that WNetCancelConnection2 doesnt work.
This is also stated here. I wonder if anybody can make it work.
FIY here's a Network connection class:
public class NetworkConnection : IDisposable
{
string _networkName;
public NetworkConnection(string networkName,
NetworkCredential credentials)
{
_networkName = networkName;
var netResource = new NetResource()
{
Scope = ResourceScope.GlobalNetwork,
ResourceType = ResourceType.Disk,
DisplayType = ResourceDisplaytype.Share,
RemoteName = networkName
};
var userName = string.IsNullOrEmpty(credentials.Domain)
? credentials.UserName
: string.Format(@"{0}\{1}", credentials.Domain, credentials.UserName);
var result = WNetAddConnection2(
netResource,
credentials.Password,
userName,
0);
if (result != 0)
{
throw new Win32Exception(result, "Error connecting to remote share");
}
}
~NetworkConnection()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
WNetCancelConnection2(_networkName, 0, true);
}
[DllImport("mpr.dll")]
private static extern int WNetAddConnection2(NetResource netResource,
string password, string username, int flags);
[DllImport("mpr.dll")]
private static extern int WNetCancelConnection2(string name, int flags,
bool force);
}
[StructLayout(LayoutKind.Sequential)]
public 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;
}
public enum ResourceScope : int
{
Connected = 1,
GlobalNetwork,
Remembered,
Recent,
Context
};
public enum ResourceType : int
{
Any = 0,
Disk = 1,
Print = 2,
Reserved = 8,
}
public enum ResourceDisplaytype : int
{
Generic = 0x0,
Domain = 0x01,
Server = 0x02,
Share = 0x03,
File = 0x04,
Group = 0x05,
Network = 0x06,
Root = 0x07,
Shareadmin = 0x08,
Directory = 0x09,
Tree = 0x0a,
Ndscontainer = 0x0b
}
I met similar issues. And I waited 60 seconds in the code and then the network connection is really closed. Paulik is right, the credential is cached somewhere which made my next connection with a different credential fail. However, if I close with WNetCancelConnection2(pathname, flag, false) and wait for 60 seconds, my new credential will work okay. Don't know the reason but it just works.
I faced the same issues, and unfortunately, didn't manage to find appropriate solution. I can only describe my research result.
This method uses 'net use /delete' command under the hood. It works fine and deletes network connection. You can check that by calling 'net use' in command window. The connection is closed, but, credentials are still cached somewhere.
So the main reason of this issue is cached credentials. You can try to find them in Credential Manager calling 'control keymgr.dll' in Run window, but in my case they were not displayed. Credentials might be cached by explorer.exe, so you can try to open Task Manager and restart it.
The only reliable way to get rid of them is to restart Workstation Service using 'net stop' 'net start' commands.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With